대시보드 설정 작업중.

강석 최 2022-10-13 18:34:32 +09:00
parent 94b6963e35
commit a9338ac74c
17 changed files with 446 additions and 29 deletions

View File

@ -5,6 +5,7 @@ import com.dbnt.faisp.organMgt.service.OrganConfigService;
import com.dbnt.faisp.userInfo.model.UserInfo;
import com.dbnt.faisp.codeMgt.service.CodeMgtService;
import com.dbnt.faisp.userInfo.service.UserInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
@ -20,6 +21,7 @@ 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) {

View File

@ -0,0 +1,30 @@
package com.dbnt.faisp.config;
import com.dbnt.faisp.menuMgt.model.MenuMgt;
import com.dbnt.faisp.menuMgt.service.MenuMgtService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
@RestController
@RequiredArgsConstructor
@RequestMapping("/modal")
public class ModalController {
private final MenuMgtService menuMgtService;
@GetMapping("/menuModal")
public ModelAndView menuModalPage(MenuMgt menuMgt){
ModelAndView mav = new ModelAndView("commonModal/menuModal");
menuMgt.setQueryInfo();
mav.addObject("menuMgtList", menuMgtService.selectMenuMgtList(menuMgt));
menuMgt.setContentCnt(menuMgtService.selectMenuMgtListCnt(menuMgt));
menuMgt.setPaginationInfo();
mav.addObject("searchParams", menuMgt);
return mav;
}
}

View File

@ -81,7 +81,8 @@ public class SecurityConfig{
http.authorizeRequests() // 페이지 권한 설정
.antMatchers(
"/dashboard",
"/refreshSession",
"/myInfo/**",
"/modal/**",
"/publicBoard/**",
"/affairPlan/**",
"/affair/**",

View File

@ -0,0 +1,42 @@
package com.dbnt.faisp.userInfo;
import com.dbnt.faisp.menuMgt.model.MenuMgt;
import com.dbnt.faisp.userInfo.model.DashboardConfig;
import com.dbnt.faisp.userInfo.model.UserInfo;
import com.dbnt.faisp.userInfo.service.UserInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
@RestController
@RequiredArgsConstructor
@RequestMapping("/myInfo")
public class MyInfoController {
private final UserInfoService userInfoService;
@GetMapping("/myInfoPage")
public ModelAndView myInfoPage(@AuthenticationPrincipal UserInfo loginUser){
ModelAndView mav = new ModelAndView("user/myInfo");
mav.addObject("userInfo", loginUser);
mav.addObject("dashboardConfigList", userInfoService.getDashboardConfigList(loginUser.getUserSeq()));
return mav;
}
@GetMapping("/getDashBoardConfig")
public List<DashboardConfig> getDashBoardConfig(@AuthenticationPrincipal UserInfo loginUser){
return userInfoService.getDashboardConfigList(loginUser.getUserSeq());
}
@PostMapping("/selectedMenuTable")
@ResponseBody
public ModelAndView dashboardConfigTable(@RequestBody List<DashboardConfig> selectMenuList){
ModelAndView mav = new ModelAndView("user/dashboardConfigTable");
mav.addObject("dashboardConfigList", selectMenuList);
return mav;
}
}

View File

@ -3,12 +3,9 @@ package com.dbnt.faisp.userInfo;
import com.dbnt.faisp.userInfo.model.UserInfo;
import com.dbnt.faisp.userInfo.service.UserInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
@RestController
@RequiredArgsConstructor
@ -22,11 +19,4 @@ public class UserInfoController {
return userInfoService.insertUserInfo(insertReqInfo);
}
@GetMapping("/myInfo")
public ModelAndView myInfoPage(@AuthenticationPrincipal UserInfo loginUser){
ModelAndView mav = new ModelAndView("user/myInfo");
mav.addObject("userInfo", loginUser);
mav.addObject("dashboardConfig", userInfoService.getDashboardConfigList(loginUser.getUserSeq()));
return mav;
}
}

View File

@ -1,5 +1,6 @@
package com.dbnt.faisp.userInfo.mapper;
import com.dbnt.faisp.userInfo.model.DashboardConfig;
import com.dbnt.faisp.userInfo.model.UserInfo;
import com.dbnt.faisp.util.ParamMap;
@ -14,4 +15,6 @@ public interface UserInfoMapper {
Integer selectUserInfoListCnt(UserInfo userInfo);
List<ParamMap> selectManagerList(ParamMap param);
List<DashboardConfig> selectDashboardConfigList(Integer userSeq);
}

View File

@ -25,6 +25,15 @@ public class DashboardConfig {
@Column(name = "order_num")
private Integer orderNum;
@Transient
private String cat1Cd;
@Transient
private String cat2Cd;
@Transient
private String cat3Cd;
@Transient
private String menuUrl;
@Embeddable
@Data
@NoArgsConstructor

View File

@ -8,5 +8,4 @@ import java.util.List;
public interface DashboardConfigRepository extends JpaRepository<DashboardConfig, DashboardConfig.DashboardConfigId> {
List<DashboardConfig> findByUserSeqOrderByOrderNum(Integer userSeq);
}

View File

@ -117,6 +117,6 @@ public class UserInfoService implements UserDetailsService {
}
public List<DashboardConfig> getDashboardConfigList(Integer userSeq) {
return dashboardConfigRepository.findByUserSeqOrderByOrderNum(userSeq);
return userInfoMapper.selectDashboardConfigList(userSeq);
}
}

View File

@ -78,4 +78,18 @@
</foreach>
order by user_nm asc
</select>
<select id="selectDashboardConfigList" resultType="DashboardConfig" parameterType="int">
select a.menu_key ,
a.cat1_cd ,
a.cat2_cd ,
a.cat3_cd ,
a.menu_url ,
b.order_num
from menu_mgt a
inner join dashboard_config b
on a.menu_key = b.menu_key
where b.user_seq = #{userSeq}
order by b.order_num
</select>
</mapper>

View File

@ -10,7 +10,14 @@ $(document).on('click', '.allChk', function (){
$(this).parents('table').find('[type="checkbox"]').prop("checked", this.checked);
})
$(document).on('click', '.page-item', function (){
searchFormSubmit($(this).attr("data-pageindex"))
if(!this.className.includes("modalPage")){
searchFormSubmit($(this).attr("data-pageindex"))
}else{
searchModalSubmit($(this).attr("data-pageindex"))
}
})
$(document).on('click', '#searchModalBtn', function (){
searchModalSubmit(1);
})
$(document).on('change', '#rowCnt', function (){
searchFormSubmit(1)
@ -19,6 +26,24 @@ function searchFormSubmit(pageIndex){
$("#pageIndex").val(pageIndex);
$("#searchBtn").click();
}
function searchModalSubmit(pageIndex){
$("#pageIndex").val(pageIndex);
$.ajax({
url: $("#modalUrl").val(),
data : $("#modalSearchForm").serialize(),
type: 'GET',
contentType: false,
dataType:"html",
success: function(html){
$("#modalBody").empty().append(html)
if(selectedList !== undefined){
setSelectedChkBox();
}
},
error:function(){
}
});
}
$(document).on('mouseenter', '.firstMenuLink', function (event){

View File

@ -1,5 +1,63 @@
let selectedList = [];
$(function (){
$.ajax({
type : 'GET',
url : "/myInfo/getDashBoardConfig",
dataType:"json",
success : function(data) {
},
error : function(xhr, status) {
}
})
})
$(document).on('click', '#configAddBtn', function (){
searchModalSubmit(1);
$("#menuModal").modal('show');
})
$(document).on('click', '.menuTr', function (){
const checkBox = $(this).find(".menuCheckBox")[0]
checkBox.checked = !checkBox.checked;
if(checkBox.checked){
selectedList.push({
menuKey: Number(checkBox.value),
cat1Cd: $(this).find(".cat1Cd").val(),
cat2Cd: $(this).find(".cat2Cd").val(),
cat3Cd: $(this).find(".cat3Cd").val(),
menuUrl: $(this).find(".menuUrl").val()
});
}else{
const tempList = [];
$.each(selectedList, function (idx, menu){
if(menu.menuKey !== Number(checkBox.value)){
tempList.push(menu);
}
})
selectedList = tempList;
}
})
$(document).on('click', '#getMenuBtn', function (){
$.ajax({
type : 'POST',
url : "/myInfo/selectedMenuTable",
data : JSON.stringify(selectedList),
contentType: 'application/json',
dataType:"html",
beforeSend: function (xhr){
xhr.setRequestHeader($("[name='_csrf_header']").val(), $("[name='_csrf']").val());
},
success : function(html) {
debugger
$("#dashboardConfigTbody").empty().append($(html)[1].children[0].children);
$("#menuModal").modal("hide");
},
error : function(xhr, status) {
}
})
})
$(document).on('click', '#savePasswordBtn', function (){
@ -29,6 +87,33 @@ $(document).on('click', '#savePasswordBtn', function (){
}
})
$(document).on('click', '#configSaveBtn', function (){
contentFade("in");
$.ajax({
type : 'POST',
url : "/myInfo/saveDashboardConfig",
data : JSON.stringify(selectedList),
contentType: 'application/json',
beforeSend: function (xhr){
xhr.setRequestHeader($("[name='_csrf_header']").val(), $("[name='_csrf']").val());
},
success : function(data) {
alert("저장되었습니다.");
contentFade("out");
location.reload();
},
error : function(xhr, status) {
alert("저장에 실패하였습니다.")
contentFade("out");
}
})
})
function setSelectedChkBox(){
$.each(selectedList, function (idx, item){
$("[value="+item.menuKey+"]").prop("checked", true);
})
}
function passwordCheck(){
let returnFlag = true;

View File

@ -1,19 +1,19 @@
$(document).on('click', '.userInfoTr', function (){
if($('#userStatus').val() == 'USC003'){
$.ajax({
url: '/userMgt/userEditModal',
data: {userSeq: Number($(this).find(".userSeq").val())},
type: 'GET',
dataType:"html",
success: function(html){
$("#configInfo").empty().append(html)
$("#userEditModal").modal('show');
},
error:function(){
if($('#userStatus').val() === 'USC003'){
$.ajax({
url: '/userMgt/userEditModal',
data: {userSeq: Number($(this).find(".userSeq").val())},
type: 'GET',
dataType:"html",
success: function(html){
$("#configInfo").empty().append(html)
$("#userEditModal").modal('show');
},
error:function(){
}
});
}
});
}
})

View File

@ -0,0 +1,125 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<div class="row">
<div class="col-12">
<form method="get" action="#" id="modalSearchForm">
<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" 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-auto">
<select class="form-select form-select-sm" name="cat1Cd">
<option value="">대분류 선택</option>
<th:block th:each="commonCode:${session.commonCode.get('CAT1')}">
<option th:value="${commonCode.itemCd}" th:text="${commonCode.itemValue}" th:selected="${searchParams.cat1Cd eq commonCode.itemCd}"></option>
</th:block>
</select>
</div>
<div class="col-auto">
<select class="form-select form-select-sm" name="cat2Cd">
<option value="">중분류 선택</option>
<th:block th:each="commonCode:${session.commonCode.get('CAT2')}">
<option th:value="${commonCode.itemCd}" th:text="${commonCode.itemValue}" th:selected="${searchParams.cat2Cd eq commonCode.itemCd}"></option>
</th:block>
</select>
</div>
<div class="col-auto">
<select class="form-select form-select-sm" name="cat3Cd">
<option value="">소분류 선택</option>
<th:block th:each="commonCode:${session.commonCode.get('CAT3')}">
<option th:value="${commonCode.itemCd}" th:text="${commonCode.itemValue}" th:selected="${searchParams.cat3Cd eq commonCode.itemCd}"></option>
</th:block>
</select>
</div>
<div class="col-auto">
<input type="text" class="form-control form-control-sm" name="menuUrl" placeholder="url" th:value="${searchParams.menuUrl}">
</div>
<input type="button" class="btn btn-sm btn-primary col-auto" id="searchModalBtn" value="검색">
</div>
</div>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-12">
<table class="table table-striped">
<thead>
<tr>
<th></th>
<th>대분류</th>
<th>중분류</th>
<th>소분류</th>
<th>url</th>
</tr>
</thead>
<tbody>
<tr class="menuTr" th:each="menuMgt:${menuMgtList}">
<input type="hidden" class="menuKey" th:value="${menuMgt.menuKey}">
<input type="hidden" class="cat1Cd" th:value="${menuMgt.cat1Cd}">
<input type="hidden" class="cat2Cd" th:value="${menuMgt.cat2Cd}">
<input type="hidden" class="cat3Cd" th:value="${menuMgt.cat3Cd}">
<input type="hidden" class="menuUrl" th:value="${menuMgt.menuUrl}">
<input type="hidden" class="approvalChk" th:value="${menuMgt.approvalChk}">
<td>
<input type="checkbox" class="menuCheckBox" th:value="${menuMgt.menuKey}">
</td>
<th:block th:if="${menuMgt.cat1RowspanCnt ne 0}" th:each="commonCode:${session.commonCode.get('CAT1')}">
<th:block th:if="${commonCode.itemCd eq menuMgt.cat1Cd}">
<td th:text="${commonCode.itemValue}" th:rowspan="${menuMgt.cat1RowspanCnt}"></td>
</th:block>
</th:block>
<th:block th:if="${menuMgt.cat2RowspanCnt ne 0}" th:each="commonCode:${session.commonCode.get('CAT2')}">
<th:block th:if="${commonCode.itemCd eq menuMgt.cat2Cd}">
<td th:text="${commonCode.itemValue}" th:rowspan="${menuMgt.cat2RowspanCnt}"></td>
</th:block>
</th:block>
<th:block th:each="commonCode:${session.commonCode.get('CAT3')}">
<th:block th:if="${commonCode.itemCd eq menuMgt.cat3Cd}">
<td th:text="${commonCode.itemValue}"></td>
</th:block>
</th:block>
<th:block th:if="${#strings.isEmpty(menuMgt.cat3Cd)}">
<td></td>
</th:block>
<td th:text="${menuMgt.menuUrl}"></td>
</tr>
</tbody>
</table>
</div>
</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 modalPage" 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 modalPage" 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 modalPage" 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>
</html>

View File

@ -31,7 +31,7 @@
<li class="nav-item"><a href="/publicBoard/boardPage" class="nav-link p-1 link-dark">게시판</a></li>
<li class="nav-item"><a href="/publicBoard/referencePage" class="nav-link p-1 link-dark">자료실</a></li>
<li class="nav-item"><a href="/publicBoard/qnaPage" class="nav-link p-1 link-dark">Q&A</a></li>
<li class="nav-item"><a href="/user/myInfo" class="nav-link p-1 link-dark">마이페이지</a></li>
<li class="nav-item"><a href="/myInfo/myInfoPage" class="nav-link p-1 link-dark">마이페이지</a></li>
<li class="nav-item"><a href="/logout" class="nav-link p-1 link-dark">로그아웃</a></li>
</ul>
</div>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<table>
<tr th:each="dashboardConfig:${dashboardConfigList}">
<td><input type="checkbox" class="configChkBox" th:data-menukey="${dashboardConfig.menuKey}"></td>
<td></td>
<th:block th:each="commonCode:${session.commonCode.get('CAT1')}">
<td th:if="${commonCode.itemCd eq dashboardConfig.cat1Cd}" th:text="${commonCode.itemValue}"></td>
</th:block>
<th:block th:if="${#strings.isEmpty(dashboardConfig.cat2Cd)}"><td></td></th:block>
<th:block th:unless="${#strings.isEmpty(dashboardConfig.cat2Cd)}" th:each="commonCode:${session.commonCode.get('CAT2')}">
<td th:if="${commonCode.itemCd eq dashboardConfig.cat2Cd}" th:text="${commonCode.itemValue}"></td>
</th:block>
<th:block th:if="${#strings.isEmpty(dashboardConfig.cat3Cd)}"><td></td></th:block>
<th:block th:unless="${#strings.isEmpty(dashboardConfig.cat3Cd)}" th:each="commonCode:${session.commonCode.get('CAT3')}">
<td th:if="${commonCode.itemCd eq dashboardConfig.cat3Cd}" th:text="${commonCode.itemValue}"></td>
</th:block>
<td th:text="${dashboardConfig.menuUrl}"></td>
<td></td>
</tr>
</table>

View File

@ -26,7 +26,49 @@
</div>
<div class="tab-pane fade p-2" id="dashboardTabPanel" role="tabpanel" aria-labelledby="dashboardTab" tabindex="0">
<form action="#" id="dashboardConfigForm">
<table class="table table-hover">
<thead>
<tr>
<th><input type="checkbox" class="allChk"></th>
<th>순번</th>
<th>대분류</th>
<th>중분류</th>
<th>소분류</th>
<th>url</th>
<th>위치변경</th>
</tr>
</thead>
<tbody id="dashboardConfigTbody">
<tr th:each="dashboardConfig, idx:${dashboardConfigList}">
<td><input type="checkbox" class="configChkBox" th:data-menukey="${dashboardConfig.menuKey}"></td>
<td th:text="${idx.count}"></td>
<th:block th:each="commonCode:${session.commonCode.get('CAT1')}">
<td th:if="${commonCode.itemCd eq dashboardConfig.cat1Cd}" th:text="${commonCode.itemValue}"></td>
</th:block>
<th:block th:if="${#strings.isEmpty(dashboardConfig.cat2Cd)}"><td></td></th:block>
<th:block th:unless="${#strings.isEmpty(dashboardConfig.cat2Cd)}" th:each="commonCode:${session.commonCode.get('CAT2')}">
<td th:if="${commonCode.itemCd eq dashboardConfig.cat2Cd}" th:text="${commonCode.itemValue}"></td>
</th:block>
<th:block th:if="${#strings.isEmpty(dashboardConfig.cat3Cd)}"><td></td></th:block>
<th:block th:unless="${#strings.isEmpty(dashboardConfig.cat3Cd)}" th:each="commonCode:${session.commonCode.get('CAT3')}">
<td th:if="${commonCode.itemCd eq dashboardConfig.cat3Cd}" th:text="${commonCode.itemValue}"></td>
</th:block>
<td th:text="${dashboardConfig.menuUrl}"></td>
<td></td>
</tr>
</tbody>
</table>
</form>
<div class="row justify-content-between">
<div class="col-auto">
<input type="button" class="btn btn-danger" id="configDeleteBtn" value="삭제">
</div>
<div class="col-auto">
<input type="button" class="btn btn-success" id="configAddBtn" value="추가">
<input type="button" class="btn btn-primary" id="configSaveBtn" value="저장">
</div>
</div>
</div>
</div>
</div>
@ -69,5 +111,34 @@
</div>
</div>
</div>
<div class="modal fade" id="menuModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="menuModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="menuModalLabel">메뉴 추가</h5>
<input type="hidden" id="modalUrl" value="/modal/menuModal">
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="modalBody">
<div class="row">
<div class="col-12">
<form method="get" action="#" id="modalSearchForm">
<input type="hidden" name="pageIndex" id="pageIndex" value="1">
<div class="row justify-content-between pe-3 py-1">
<div class="col-auto">
<input type="hidden" name="rowCnt" value="10">
</div>
</div>
</form>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" id="getMenuBtn">추가</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
</div>
</div>
</div>
</div>
</div>
</html>