diff --git a/src/main/java/com/dbnt/faisp/config/SecurityConfig.java b/src/main/java/com/dbnt/faisp/config/SecurityConfig.java index f0fb61b1..db57bdc6 100644 --- a/src/main/java/com/dbnt/faisp/config/SecurityConfig.java +++ b/src/main/java/com/dbnt/faisp/config/SecurityConfig.java @@ -38,8 +38,8 @@ public class SecurityConfig{ log.warn("accessDeniedHandler"); return (request, response, e) -> { response.setStatus(HttpServletResponse.SC_FORBIDDEN); - response.setContentType("text/plain;charset=UTF-8"); - response.getWriter().write("ACCESS DENIED"); + response.setContentType("text/html;charset=UTF-8"); + response.getWriter().println(""); response.getWriter().flush(); response.getWriter().close(); }; @@ -49,8 +49,8 @@ public class SecurityConfig{ public AuthenticationEntryPoint authenticationEntryPoint() { return (request, response, e) -> { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - response.setContentType("text/plain;charset=UTF-8"); - response.getWriter().write("UNAUTHORIZED"); + response.setContentType("text/html;charset=UTF-8"); + response.getWriter().println(""); response.getWriter().flush(); response.getWriter().close(); }; @@ -59,23 +59,23 @@ public class SecurityConfig{ @Bean protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeRequests() // 페이지 권한 설정 - .antMatchers("/dashboard").hasRole(Role.USER.name()) // USER, ADMIN 접근 허용 - .antMatchers("/codeMgt/**", "/menuMgt/**").hasRole(Role.ADMIN.name()) // ADMIN만 접근 허용 - .antMatchers("/login").permitAll() // 로그인 페이지는 권한 없이 접근 허용 + .antMatchers("/dashboard", "/refreshSession").hasRole(Role.USER.name()) // USER, ADMIN 접근 허용 + .antMatchers("/codeMgt/**", "/menuMgt/**").hasRole(Role.ADMIN.name()) // ADMIN만 접근 허용 + .antMatchers("/login").permitAll() // 로그인 페이지는 권한 없이 접근 허용 .and() // 로그인 설정 - .formLogin() .loginPage("/login") // Custom login form 사용 - .failureUrl("/login-error") // 로그인 실패 시 이동 - .defaultSuccessUrl("/") // 로그인 성공 시 redirect 이동 + .formLogin() .loginPage("/login") // Custom login form 사용 + .failureUrl("/login-error") // 로그인 실패 시 이동 + .defaultSuccessUrl("/") // 로그인 성공 시 redirect 이동 .and() // 로그아웃 설정 - .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")) // 로그아웃 시 URL 재정의 - .logoutSuccessUrl("/") // 로그아웃 성공 시 redirect 이동 - .invalidateHttpSession(true) // HTTP Session 초기화 - .deleteCookies("JSESSIONID") // 특정 쿠키 제거 + .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")) // 로그아웃 시 URL 재정의 + .logoutSuccessUrl("/") // 로그아웃 성공 시 redirect 이동 + .invalidateHttpSession(true) // HTTP Session 초기화 + .deleteCookies("JSESSIONID") // 특정 쿠키 제거 .and() // 403 예외처리 핸들링 - //.exceptionHandling().accessDeniedPage("/denied"); - .exceptionHandling() - .accessDeniedHandler(accessDeniedHandler()) - .authenticationEntryPoint(authenticationEntryPoint()); + //.exceptionHandling().accessDeniedPage("/denied"); + .exceptionHandling() + .accessDeniedHandler(accessDeniedHandler()) + .authenticationEntryPoint(authenticationEntryPoint()); return http.build(); } diff --git a/src/main/java/com/dbnt/faisp/controller/BaseController.java b/src/main/java/com/dbnt/faisp/controller/BaseController.java index eac4f31c..1f3b4841 100644 --- a/src/main/java/com/dbnt/faisp/controller/BaseController.java +++ b/src/main/java/com/dbnt/faisp/controller/BaseController.java @@ -1,11 +1,10 @@ package com.dbnt.faisp.controller; import com.dbnt.faisp.model.UserInfo; -import com.dbnt.faisp.service.CommonCodeService; +import com.dbnt.faisp.service.CodeMgtService; import lombok.RequiredArgsConstructor; import org.springframework.security.core.annotation.AuthenticationPrincipal; 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; @@ -15,7 +14,7 @@ import javax.servlet.http.HttpSession; @RequiredArgsConstructor public class BaseController { - private final CommonCodeService commonCodeService; + private final CodeMgtService codeMgtService; @GetMapping("/") public ModelAndView loginCheck(@AuthenticationPrincipal UserInfo loginUser, HttpSession session) { @@ -23,6 +22,7 @@ public class BaseController { if(loginUser == null){ mav = new ModelAndView("redirect:/login"); }else{ + session.setAttribute("commonCodeList", codeMgtService.selectCodeCatgAndChild()); mav = new ModelAndView("redirect:/dashboard"); } return mav; @@ -30,8 +30,7 @@ public class BaseController { @GetMapping("/refreshSession") public void getSession(HttpSession session){ - session.setAttribute("positionList", commonCodeService.selectCommonCodeValue("POSITION")); - session.setAttribute("departmentList", commonCodeService.selectCommonCodeValue("DEPARTMENT")); + session.setAttribute("commonCodeList", codeMgtService.selectCodeCatgAndChild()); } @GetMapping("/login") diff --git a/src/main/java/com/dbnt/faisp/controller/CodeMgtController.java b/src/main/java/com/dbnt/faisp/controller/CodeMgtController.java index e6e253e6..b55f39a4 100644 --- a/src/main/java/com/dbnt/faisp/controller/CodeMgtController.java +++ b/src/main/java/com/dbnt/faisp/controller/CodeMgtController.java @@ -1,13 +1,13 @@ package com.dbnt.faisp.controller; +import com.dbnt.faisp.model.CodeCatg; import com.dbnt.faisp.service.CodeMgtService; import lombok.RequiredArgsConstructor; -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.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; +import java.util.List; + @RestController @RequiredArgsConstructor @RequestMapping("/codeMgt") @@ -21,4 +21,16 @@ public class CodeMgtController { return mav; } + + @PostMapping("/saveCode") + @ResponseBody + public String saveCode(@RequestBody List codeCategoryList){ + codeMgtService.saveCode(codeCategoryList); + return ""; + } + + @GetMapping("/selectCodeCatgList") + public List selectCodeCatgList(){ + return codeMgtService.selectCodeCatgAndChild(); + } } diff --git a/src/main/java/com/dbnt/faisp/controller/UserInfoController.java b/src/main/java/com/dbnt/faisp/controller/UserInfoController.java index 6cc10f07..841a59da 100644 --- a/src/main/java/com/dbnt/faisp/controller/UserInfoController.java +++ b/src/main/java/com/dbnt/faisp/controller/UserInfoController.java @@ -1,14 +1,11 @@ package com.dbnt.faisp.controller; import com.dbnt.faisp.model.UserInfo; -import com.dbnt.faisp.service.CommonCodeService; import com.dbnt.faisp.service.UserInfoService; import lombok.RequiredArgsConstructor; -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 diff --git a/src/main/java/com/dbnt/faisp/mapper/CommonCodeMapper.java b/src/main/java/com/dbnt/faisp/mapper/CommonCodeMapper.java deleted file mode 100644 index 3aa4972a..00000000 --- a/src/main/java/com/dbnt/faisp/mapper/CommonCodeMapper.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.dbnt.faisp.mapper; - -import com.dbnt.faisp.model.CommonCode; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -@Mapper -public interface CommonCodeMapper { - List selectCommonCodeCategory(CommonCode commonCode); -} diff --git a/src/main/java/com/dbnt/faisp/model/CodeCatg.java b/src/main/java/com/dbnt/faisp/model/CodeCatg.java index 7c42173b..dfdb1835 100644 --- a/src/main/java/com/dbnt/faisp/model/CodeCatg.java +++ b/src/main/java/com/dbnt/faisp/model/CodeCatg.java @@ -7,6 +7,7 @@ import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; import javax.persistence.*; +import java.util.List; @Getter @Setter @@ -24,4 +25,9 @@ public class CodeCatg { @Column(name = "description") private String description; + @Transient + private String status; + @Transient + private List itemList; + } diff --git a/src/main/java/com/dbnt/faisp/model/CodeMgt.java b/src/main/java/com/dbnt/faisp/model/CodeMgt.java index 13b767af..90b38b83 100644 --- a/src/main/java/com/dbnt/faisp/model/CodeMgt.java +++ b/src/main/java/com/dbnt/faisp/model/CodeMgt.java @@ -22,11 +22,14 @@ public class CodeMgt { @Id @Column(name = "item_cd") private String itemCd; - @Column(name = "VALUE", nullable = false) - private String value; + @Column(name = "item_value", nullable = false) + private String itemValue; @Column(name = "use_chk") private String useChk; + @Transient + private String status; + @Embeddable @Data @NoArgsConstructor diff --git a/src/main/java/com/dbnt/faisp/model/CommonCode.java b/src/main/java/com/dbnt/faisp/model/CommonCode.java deleted file mode 100644 index 72cb2752..00000000 --- a/src/main/java/com/dbnt/faisp/model/CommonCode.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.dbnt.faisp.model; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.hibernate.annotations.DynamicInsert; -import org.hibernate.annotations.DynamicUpdate; - -import javax.persistence.*; - -@Getter -@Setter -@Entity -@NoArgsConstructor -@DynamicInsert -@DynamicUpdate -@Table(name = "COMMON_CODE") -public class CommonCode { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "CODE_SQ") - private Integer codeSq; - @Column(name = "CATEGORY", nullable = false) - private String category; - @Column(name = "VALUE", nullable = false) - private String value; - @Column(name = "DESCRIPTION") - private String description; - @Column(name = "IS_DELETED") - private String isDeleted; - -} diff --git a/src/main/java/com/dbnt/faisp/repository/CodeMgtRepository.java b/src/main/java/com/dbnt/faisp/repository/CodeMgtRepository.java index d83208b2..2bd46cfc 100644 --- a/src/main/java/com/dbnt/faisp/repository/CodeMgtRepository.java +++ b/src/main/java/com/dbnt/faisp/repository/CodeMgtRepository.java @@ -3,9 +3,11 @@ package com.dbnt.faisp.repository; import com.dbnt.faisp.model.CodeMgt; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; import java.util.Optional; public interface CodeMgtRepository extends JpaRepository { + List findByCategoryCdOrderByItemCdAsc(String categoryCd); } diff --git a/src/main/java/com/dbnt/faisp/repository/CommonCodeRepository.java b/src/main/java/com/dbnt/faisp/repository/CommonCodeRepository.java deleted file mode 100644 index 18ba3eb6..00000000 --- a/src/main/java/com/dbnt/faisp/repository/CommonCodeRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.dbnt.faisp.repository; - -import com.dbnt.faisp.model.CommonCode; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - - -public interface CommonCodeRepository extends JpaRepository { - List findByCategoryAndIsDeleted(String category, String isDeleted); -} diff --git a/src/main/java/com/dbnt/faisp/service/CodeMgtService.java b/src/main/java/com/dbnt/faisp/service/CodeMgtService.java index f749ab39..c33d3757 100644 --- a/src/main/java/com/dbnt/faisp/service/CodeMgtService.java +++ b/src/main/java/com/dbnt/faisp/service/CodeMgtService.java @@ -1,6 +1,8 @@ package com.dbnt.faisp.service; import com.dbnt.faisp.mapper.CodeMgtMapper; +import com.dbnt.faisp.model.CodeCatg; +import com.dbnt.faisp.model.CodeMgt; import com.dbnt.faisp.repository.CodeCatgRepository; import com.dbnt.faisp.repository.CodeMgtRepository; import lombok.RequiredArgsConstructor; @@ -17,4 +19,26 @@ public class CodeMgtService{ private final CodeCatgRepository codeCatgRepository; private final CodeMgtMapper codeMgtMapper; + @Transactional + public String saveCode(List codeMgtList){ + for(CodeCatg codeCatg: codeMgtList){ + codeCatgRepository.save(codeCatg); + if (codeCatg.getItemList().size()>0){ + codeItemSave(codeCatg.getItemList()); + } + } + return ""; + } + + private void codeItemSave(List itemList){ + codeMgtRepository.saveAll(itemList); + } + + public List selectCodeCatgAndChild() { + List codeCatgList = codeCatgRepository.findAll(); + for(CodeCatg codeCatg: codeCatgList){ + codeCatg.setItemList(codeMgtRepository.findByCategoryCdOrderByItemCdAsc(codeCatg.getCategoryCd())); + } + return codeCatgList; + } } diff --git a/src/main/java/com/dbnt/faisp/service/CommonCodeService.java b/src/main/java/com/dbnt/faisp/service/CommonCodeService.java deleted file mode 100644 index 06b3c4b3..00000000 --- a/src/main/java/com/dbnt/faisp/service/CommonCodeService.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.dbnt.faisp.service; - -import com.dbnt.faisp.mapper.CommonCodeMapper; -import com.dbnt.faisp.model.CommonCode; -import com.dbnt.faisp.repository.CommonCodeRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -@RequiredArgsConstructor -public class CommonCodeService { - - private final CommonCodeMapper commonCodeMapper; - private final CommonCodeRepository commonCodeRepository; - - public List selectCommonCodeCategory(CommonCode commonCode) { - return commonCodeMapper.selectCommonCodeCategory(commonCode); - } - public List selectCommonCodeValue(String category) { - return commonCodeRepository.findByCategoryAndIsDeleted(category, "N"); - } - public void insertCommonCode(CommonCode commonCode) { - commonCodeRepository.save(commonCode); - } - - public void updateCommonCode(List codeList) { - commonCodeRepository.saveAll(codeList); - } -} diff --git a/src/main/resources/mybatisMapper/CommonCodeMapper.xml b/src/main/resources/mybatisMapper/CommonCodeMapper.xml deleted file mode 100644 index 4735eb0c..00000000 --- a/src/main/resources/mybatisMapper/CommonCodeMapper.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - SELECT DISTINCT - CATEGORY - FROM COMMON_CODE - - - AND IS_DELETED = 'N' - - - - \ No newline at end of file diff --git a/src/main/resources/static/js/codeMgt/codeMgt.js b/src/main/resources/static/js/codeMgt/codeMgt.js new file mode 100644 index 00000000..42ce179b --- /dev/null +++ b/src/main/resources/static/js/codeMgt/codeMgt.js @@ -0,0 +1,149 @@ +let codeCategoryList=[]; +let selectedCategoryIdx=0; +let selectedItemIdx=0; + +$(function(){ + $.ajax({ + url: '/codeMgt/selectCodeCatgList', + type: 'GET', + dataType:"json", + success: function(data){ + codeCategoryList = data; + makeCategoryTr(); + }, + error:function(){ + + } + }); +}); + +$(document).on('click', '#categoryAddBtn', function (){ + $('#categoryTable').find('tbody').append( + '' + + ''+ + ''+ + ''+ + ''+ + '' + ) + codeCategoryList.push({categoryCd:"", categoryValue: "", description: "", status:"new", itemList: []}) +}) +$(document).on('click', '#itemAddBtn', function (){ + $('#itemTable').find('tbody').append( + '' + + ''+ + ''+ + ''+ + ''+ + '' + ) + codeCategoryList[selectedCategoryIdx].itemList.push({categoryCd:codeCategoryList[selectedCategoryIdx].categoryCd, itemCd:"", itemValue: "", useChk: "", status:"new"}) +}) + +$(document).on('click', '.rowDeleteBtn', function (){ + switch ($(this).parents("table")[0].id){ + case "categoryTable": + selectedCategoryIdx = $(this).parents('tr')[0].rowIndex-1; + codeCategoryList.splice(selectedItemIdx, 1); + break; + case "itemTable": + selectedItemIdx = $(this).parents('tr')[0].rowIndex-1; + codeCategoryList[selectedCategoryIdx].itemList.splice(selectedItemIdx, 1); + break; + } + $(this).parents('tr').remove(); +}) + +$(document).on('click', '.categoryTr', function (){ + selectedCategoryIdx = this.rowIndex-1; + $(".allChk").prop("checked", false); + $('#itemTable').find('tbody').find('tr').remove(); + $("#itemBtnRow").show(); + + if(codeCategoryList[selectedCategoryIdx].itemList.length>0){ + makeItemTr(codeCategoryList[selectedCategoryIdx].itemList); + } +}) + +$(document).on('click', '.itemTr', function (){ + selectedItemIdx = this.rowIndex-1; +}) + +$(document).on('change', '.categoryInput', function (){ + selectedCategoryIdx = $(this).parents('tr')[0].rowIndex-1; + const target = codeCategoryList[selectedCategoryIdx]; + switch (this.name){ + case "categoryCd": + target.categoryCd = this.value + break; + case "categoryValue": + target.categoryValue = this.value + break; + case "description": + target.description = this.value + break; + } +}) + +$(document).on('change', '.itemInput', function (){ + selectedItemIdx = $(this).parents('tr')[0].rowIndex-1; + const target = codeCategoryList[selectedCategoryIdx].itemList[selectedItemIdx]; + switch (this.name){ + case "itemCd": + target.itemCd = this.value + break; + case "itemValue": + target.itemValue = this.value + break; + case "useChk": + target.useChk = this.checked?"T":"F" + break; + } +}) + +$(document).on('click', '#codeSaveBtn', function (){ + contentFade("in"); + $.ajax({ + type : 'POST', + url : "/codeMgt/saveCode", + data : JSON.stringify(codeCategoryList), + 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 makeCategoryTr(){ + codeCategoryList.forEach(function (category, idx){ + $("#categoryTable").find('tbody').append( + '' + + ''+(category.status==="new"?'':'')+''+ + ''+ + ''+ + ''+ + '' + ) + }); +} +function makeItemTr(itemList){ + itemList.forEach(function (item, idx){ + $("#itemTable").find('tbody').append( + '' + + ''+(item.status==="new"?'':'')+''+ + ''+ + ''+ + ''+ + '' + ) + }); +} \ No newline at end of file diff --git a/src/main/resources/static/js/common.js b/src/main/resources/static/js/common.js index 2d9717ba..e47522fe 100644 --- a/src/main/resources/static/js/common.js +++ b/src/main/resources/static/js/common.js @@ -4,4 +4,17 @@ function contentFade(action){ }else{ $("#fadeDiv").hide() } -} \ No newline at end of file +} + +function sessionReload(){ + $.ajax({ + url: '/refreshSession', + type: 'GET', + success: function(){location.reload();}, + error:function(){} + }); +} + +$(document).on('click', '.allChk', function (){ + $(this).parents('table').find('[type="checkbox"]').prop("checked", this.checked); +}) \ No newline at end of file diff --git a/src/main/resources/templates/adminPage/codeMgt/codeMgt.html b/src/main/resources/templates/adminPage/codeMgt/codeMgt.html index e6f553b9..97af015f 100644 --- a/src/main/resources/templates/adminPage/codeMgt/codeMgt.html +++ b/src/main/resources/templates/adminPage/codeMgt/codeMgt.html @@ -3,64 +3,69 @@ xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/layout}"> - + 코드 관리 + + + + + + 저장 + + + - - - - - 분류코드 - 분류명 - 설명 - - - - + + + + + + 분류코드 + 분류명 + 설명 + + + + + + + + + + - - - - - - - 하위코드 - 값 - 사용여부 - - - - + + + + + + 하위코드 + 값 + 사용 + + + + 분류를 선택해주세요. + + + + + +