users TB에 id -> uniq_id 로 수정

alert Toasts 추가
This commit is contained in:
hylee 2024-05-23 18:08:26 +09:00
parent e770fc903e
commit 40babaeddc
22 changed files with 187 additions and 101 deletions

View File

@ -31,6 +31,6 @@ public class CustomUserDetailsService implements UserDetailsService {
Collection<? extends GrantedAuthority> authorities = Collections.singletonList(authority); Collection<? extends GrantedAuthority> authorities = Collections.singletonList(authority);
// CustomUserDetails 객체 생성 // CustomUserDetails 객체 생성
return new CustomUserDetails(user.getUserId(), user.getPassword(), user.getUserId(), user.getId(), authorities); return new CustomUserDetails(user.getUserId(), user.getPassword(), user.getUserId(), user.getUniqId(), authorities);
} }
} }

View File

@ -1,9 +1,11 @@
package com.itn.admin.cmn.config; package com.itn.admin.cmn.config;
import com.itn.admin.itn.user.mapper.domain.UserVO; import com.itn.admin.itn.user.mapper.domain.UserVO;
import com.itn.admin.itn.user.service.UserService;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
@ -13,32 +15,56 @@ import org.springframework.web.servlet.ModelAndView;
@Slf4j @Slf4j
public class UserInterceptor implements HandlerInterceptor { public class UserInterceptor implements HandlerInterceptor {
@Override private final UserService userService;
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
if (modelAndView != null) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Object principal = authentication.getPrincipal();
String userId; public UserInterceptor(UserService userService) {
String userName; this.userService = userService;
if (principal instanceof UserVO) {
UserVO loggedInUser = (UserVO) principal;
userId = loggedInUser.getUserId();
userName = loggedInUser.getUsername();
} else if (principal instanceof User) {
User loggedInUser = (User) principal;
userId = loggedInUser.getUsername();
userName = loggedInUser.getUsername();
} else {
userId = principal.toString();
userName = principal.toString();
} }
log.info("userId : [{}]",userId.toString()); @Override
log.info("userName : [{}]",userName.toString()); public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
modelAndView.addObject("userId", userId);
log.info(" :: postHandle :: ");
log.info("Request URL: " + request.getRequestURL());
log.info("Request Method: " + request.getMethod());
log.info("Remote Address: " + request.getRemoteAddr());
if (modelAndView != null) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
Object principal = authentication.getPrincipal();
String id;
String userName;
if (principal instanceof UserVO) { // principal이 UserVO 타입인 경우
UserVO loggedInUser = (UserVO) principal; // principal 객체를 UserVO 타입으로 변환
id = loggedInUser.getUserId(); // UserVO 객체에서 userId 값을 가져옴
userName = loggedInUser.getUsername(); // UserVO 객체에서 username 값을 가져옴
} else if (principal instanceof User) { // principal이 User 타입인 경우
User loggedInUser = (User) principal; // principal 객체를 User 타입으로 변환
id = loggedInUser.getUsername(); // User 객체에서 username 값을 가져옴 (userId로 사용)
userName = loggedInUser.getUsername(); // User 객체에서 username 값을 가져옴
} else if (principal instanceof CustomUserDetails) { // principal이 CustomUserDetails 타입인 경우
CustomUserDetails loggedInUser = (CustomUserDetails) principal; // principal 객체를 CustomUserDetails 타입으로 변환
id = loggedInUser.getId(); // CustomUserDetails 객체에서 id 값을 가져옴
userName = loggedInUser.getUsername(); // CustomUserDetails 객체에서 username 값을 가져옴
} else { // principal이 위의 어떤 타입도 아닌 경우
id = principal.toString(); // principal 객체의 문자열 표현을 userId로 사용
userName = principal.toString(); // principal 객체의 문자열 표현을 username으로 사용
}
log.info("userId : [{}]", id);
log.info("userName : [{}]", userName);
modelAndView.addObject("userId", id);
modelAndView.addObject("userName", userName); modelAndView.addObject("userName", userName);
// 로그인 로그를 기록
userService.requestLogs(id, request.getRequestURL().toString());
} else {
log.info("No authenticated user found.");
}
} }
} }
} }

View File

@ -1,5 +1,7 @@
package com.itn.admin.cmn.config; package com.itn.admin.cmn.config;
import com.itn.admin.itn.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ -7,9 +9,14 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration @Configuration
public class WebConfig implements WebMvcConfigurer { public class WebConfig implements WebMvcConfigurer {
@Autowired
private UserService userService;
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserInterceptor()) registry.addInterceptor(new UserInterceptor(userService))
.addPathPatterns("/**"); .addPathPatterns("/**")
.excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg", "/**/*.gif", "/**/*.woff", "/**/*.woff2", "/**/*.ttf", "/**/*.eot", "/**/*.map")
;
} }
} }

View File

@ -1,6 +1,6 @@
package com.itn.admin.itn.dictionary.mapper; package com.itn.admin.itn.dict.mapper;
import com.itn.admin.itn.dictionary.mapper.domain.DictionaryVO; import com.itn.admin.itn.dict.mapper.domain.DictionaryVO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List; import java.util.List;

View File

@ -1,9 +1,8 @@
package com.itn.admin.itn.dictionary.mapper.domain; package com.itn.admin.itn.dict.mapper.domain;
import lombok.*; import lombok.*;
import java.io.Serializable; import java.io.Serializable;
import java.sql.Date;
/** /**
* packageName : com.itn.admin.itn.commute.mapper.domain * packageName : com.itn.admin.itn.commute.mapper.domain

View File

@ -1,6 +1,6 @@
package com.itn.admin.itn.dictionary.service; package com.itn.admin.itn.dict.service;
import com.itn.admin.itn.dictionary.mapper.domain.DictionaryVO; import com.itn.admin.itn.dict.mapper.domain.DictionaryVO;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;

View File

@ -1,15 +1,13 @@
package com.itn.admin.itn.dictionary.service.impl; package com.itn.admin.itn.dict.service.impl;
import com.itn.admin.cmn.config.SecurityUtil; import com.itn.admin.cmn.config.SecurityUtil;
import com.itn.admin.itn.dictionary.mapper.DictionaryMapper; import com.itn.admin.itn.dict.mapper.DictionaryMapper;
import com.itn.admin.itn.dictionary.mapper.domain.DictionaryVO; import com.itn.admin.itn.dict.mapper.domain.DictionaryVO;
import com.itn.admin.itn.dictionary.service.DictionaryService; import com.itn.admin.itn.dict.service.DictionaryService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;

View File

@ -1,6 +1,6 @@
package com.itn.admin.itn.dictionary.web; package com.itn.admin.itn.dict.web;
import com.itn.admin.itn.dictionary.service.DictionaryService; import com.itn.admin.itn.dict.service.DictionaryService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -15,7 +15,7 @@ public class DictionaryController {
this.dictionaryService = dictionaryService; this.dictionaryService = dictionaryService;
} }
@GetMapping(value = "/dictionary/list") @GetMapping(value = "/dict/list")
public String list() { public String list() {
// public String list(@ModelAttribute("dictionaryVO") DictionaryVO dictionaryVO, Model model) { // public String list(@ModelAttribute("dictionaryVO") DictionaryVO dictionaryVO, Model model) {
// //
@ -24,7 +24,7 @@ public class DictionaryController {
// //
// model.addAttribute("list", resultMap.get("resultList")); // model.addAttribute("list", resultMap.get("resultList"));
return "dictionary/list"; return "dict/list";
} }

View File

@ -1,14 +1,11 @@
package com.itn.admin.itn.dictionary.web; package com.itn.admin.itn.dict.web;
import com.itn.admin.itn.dictionary.mapper.domain.DictionaryVO; import com.itn.admin.itn.dict.mapper.domain.DictionaryVO;
import com.itn.admin.itn.dictionary.service.DictionaryService; import com.itn.admin.itn.dict.service.DictionaryService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -24,7 +21,7 @@ public class DictionaryRestController {
// 데이터 불러오기 // 데이터 불러오기
@GetMapping("/dictionary/list/load") @GetMapping("/dict/list/load")
public ResponseEntity<List<DictionaryVO>> loadData() { public ResponseEntity<List<DictionaryVO>> loadData() {
// 데이터베이스에서 데이터를 조회하는 로직 // 데이터베이스에서 데이터를 조회하는 로직
List<DictionaryVO> data = dictionaryService.getList(); List<DictionaryVO> data = dictionaryService.getList();
@ -33,7 +30,7 @@ public class DictionaryRestController {
// 데이터 수정 // 데이터 수정
@PostMapping("/dictionary/api/update") @PostMapping("/dict/api/update")
public ResponseEntity<?> updateData(@RequestBody Map<String, Object> dictionaryMap) { public ResponseEntity<?> updateData(@RequestBody Map<String, Object> dictionaryMap) {
// 데이터 처리 로직 // 데이터 처리 로직
// : 데이터베이스에서 기존 데이터를 수정 // : 데이터베이스에서 기존 데이터를 수정

View File

@ -1,27 +1,23 @@
package com.itn.admin.itn.user.mapper; package com.itn.admin.itn.user.mapper;
import com.itn.admin.commute.mapper.domain.CommuteVO;
import com.itn.admin.itn.user.mapper.domain.Role;
import com.itn.admin.itn.user.mapper.domain.UserVO; import com.itn.admin.itn.user.mapper.domain.UserVO;
import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
@Mapper @Mapper
public interface UserMapper { public interface UserMapper {
// UserVO save(UserVO userVO); // UserVO save(UserVO userVO);
@Select("SELECT id, user_id AS userId, user_pw AS password, user_name AS username, role FROM users WHERE user_id = #{userId}") @Select("SELECT uniq_id, user_id AS userId, user_pw AS password, user_name AS username, role FROM users WHERE user_id = #{userId}")
UserVO getUserById(String userId); UserVO getUserById(String userId);
@Select("SELECT id, user_id AS userId, user_pw AS password, user_name AS username, role FROM users WHERE id = #{id}") @Select("SELECT uniq_id, user_id AS userId, user_pw AS password, user_name AS username, role FROM users WHERE uniq_id = #{uniqId}")
UserVO findById(String id); UserVO findById(String uniqId);
@Insert("INSERT INTO users (id, user_id, user_pw, user_name, role) VALUES (#{id}, #{userId}, #{password}, #{username}, #{role})") @Insert("INSERT INTO users (uniq_id, user_id, user_pw, user_name, role) VALUES (#{uniqId}, #{userId}, #{password}, #{username}, #{role})")
void save(UserVO userVO); void save(UserVO userVO);
@ -39,6 +35,11 @@ public interface UserMapper {
void updateRole(UserVO user); void updateRole(UserVO user);
@Insert("INSERT INTO login_logs (id, FRST_REGIST_PNTTM) VALUES (#{id}, now())") @Insert("INSERT INTO login_logs (uniqId, FRST_REGIST_PNTTM) VALUES (#{uniqId}, now())")
void loginLog(String id); void loginLog(String uniqId);
/// 진행중
@Insert("INSERT INTO request_logs (uniqId, FRST_REGIST_PNTTM) VALUES (#{uniqId}, now())")
void requestLogs(String uniqId, String requestURL);
} }

View File

@ -14,7 +14,7 @@ import java.util.Collections;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
public class UserVO implements UserDetails { public class UserVO implements UserDetails {
private String id; private String uniqId;
private String userId; private String userId;
private String password; private String password;
private String username; private String username;

View File

@ -13,7 +13,9 @@ public interface UserService {
Map<String, Object> getList(UserVO userVO); Map<String, Object> getList(UserVO userVO);
RestResponse updateRole(String id, Role role); RestResponse updateRole(String uniqId, Role role);
void loginLog(String id); void loginLog(String id);
void requestLogs(String id, String requestURL);
} }

View File

@ -55,8 +55,8 @@ public class UserServiceImpl implements UserService {
} }
@Override @Override
public RestResponse updateRole(String id, Role role) { public RestResponse updateRole(String uniqId, Role role) {
UserVO user = userMapper.findById(id); UserVO user = userMapper.findById(uniqId);
if (user != null) { if (user != null) {
user.setRole(role); user.setRole(role);
userMapper.updateRole(user); userMapper.updateRole(user);
@ -78,5 +78,11 @@ public class UserServiceImpl implements UserService {
} }
@Override
public void requestLogs(String id, String requestURL) {
// userMapper.requestLogs(id, requestURL);
}
} }

View File

@ -15,7 +15,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.util.Collections;
import java.util.UUID; import java.util.UUID;
@Controller @Controller
@ -55,7 +54,7 @@ public class LoginController {
} }
UserVO user = new UserVO(); UserVO user = new UserVO();
user.setId("ITN_"+UUID.randomUUID().toString().replace("-", "").substring(0, 10)); user.setUniqId("ITN_"+UUID.randomUUID().toString().replace("-", "").substring(0, 10));
user.setUserId(userDTO.getUserId()); user.setUserId(userDTO.getUserId());
user.setUsername(userDTO.getUserName()); user.setUsername(userDTO.getUserName());
user.setPassword(passwordEncoder.encode(userDTO.getPassword())); user.setPassword(passwordEncoder.encode(userDTO.getPassword()));

View File

@ -23,7 +23,7 @@ public class UserRestController {
@PostMapping("/user/updateRole") @PostMapping("/user/updateRole")
@ResponseBody @ResponseBody
public ResponseEntity<?> updateRole(@RequestParam("id") String id, @RequestParam("role") Role role) { public ResponseEntity<?> updateRole(@RequestParam("uniqId") String uniqId, @RequestParam("role") Role role) {
return ResponseEntity.ok(userService.updateRole(id, role)); return ResponseEntity.ok(userService.updateRole(uniqId, role));
} }
} }

View File

@ -12,6 +12,6 @@
<!-- Type Aliases 설정--> <!-- Type Aliases 설정-->
<typeAliases> <typeAliases>
<typeAlias alias="dictionaryVO" type="com.itn.admin.itn.dictionary.mapper.domain.DictionaryVO" /> <typeAlias alias="dictionaryVO" type="com.itn.admin.itn.dict.mapper.domain.DictionaryVO" />
</typeAliases> </typeAliases>
</configuration> </configuration>

View File

@ -3,10 +3,10 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itn.admin.itn.dictionary.mapper.DictionaryMapper"> <mapper namespace="com.itn.admin.itn.dict.mapper.DictionaryMapper">
<select id="findAll" resultType="dictionaryVO"> <select id="findAll" resultType="dictionaryVO">
<!-- <select id="findAll" resultType="com.itn.admin.itn.dictionary.mapper.domain.DictionaryVO" parameterType="com.itn.admin.itn.dictionary.mapper.domain.DictionaryVO">--> <!-- <select id="findAll" resultType="com.itn.admin.itn.dict.mapper.domain.DictionaryVO" parameterType="com.itn.admin.itn.dict.mapper.domain.DictionaryVO">-->
SELECT SELECT
a.id a.id
, a.KOREAN_WORD , a.KOREAN_WORD
@ -21,7 +21,7 @@
, b.USER_NAME as lastUpdusrName , b.USER_NAME as lastUpdusrName
FROM dictionary a FROM dictionary a
LEFT JOIN users b LEFT JOIN users b
ON a.LAST_UPDUSR_ID = b.ID ON a.LAST_UPDUSR_ID = b.uniq_id
</select> </select>
@ -64,6 +64,7 @@
, ENGLISH_WORD , ENGLISH_WORD
, ABBREVIATION , ABBREVIATION
, IS_CONFIRMED , IS_CONFIRMED
, LAST_UPDUSR_ID
, FRST_REGIST_PNTTM , FRST_REGIST_PNTTM
) )
values values
@ -72,6 +73,7 @@
, #{englishWord} , #{englishWord}
, #{abbreviation} , #{abbreviation}
, #{isConfirmed} , #{isConfirmed}
, #{userId}
, NOW() , NOW()
); );

View File

@ -7,7 +7,7 @@
<select id="findAll" resultType="userVO"> <select id="findAll" resultType="userVO">
SELECT SELECT
id uniq_id
, user_id , user_id
, user_pw , user_pw
, user_name , user_name
@ -18,7 +18,7 @@
</select> </select>
<update id="updateRole" parameterType="userVO"> <update id="updateRole" parameterType="userVO">
UPDATE users SET role = #{role} WHERE id = #{id} UPDATE users SET role = #{role} WHERE uniq_id = #{uniqId}
</update> </update>
</mapper> </mapper>

View File

@ -15,7 +15,7 @@
<!-- 별칭 --> <!-- 별칭 -->
<typeAliases> <typeAliases>
<typeAlias type="com.itn.admin.commute.mapper.domain.CommuteVO" alias="commuteVO"/> <typeAlias type="com.itn.admin.commute.mapper.domain.CommuteVO" alias="commuteVO"/>
<typeAlias type="com.itn.admin.itn.dictionary.mapper.domain.DictionaryVO" alias="dictionaryVO"/> <typeAlias type="com.itn.admin.itn.dict.mapper.domain.DictionaryVO" alias="dictionaryVO"/>
<typeAlias type="com.itn.admin.itn.user.mapper.domain.UserVO" alias="userVO"/> <typeAlias type="com.itn.admin.itn.user.mapper.domain.UserVO" alias="userVO"/>
</typeAliases> </typeAliases>

View File

@ -119,6 +119,7 @@
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/2.0.2/css/select.dataTables.css"> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/2.0.2/css/select.dataTables.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/datetime/1.5.2/css/dataTables.dateTime.min.css"> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/datetime/1.5.2/css/dataTables.dateTime.min.css">
<link rel="stylesheet" th:href="@{/plugins/datatable_editor/css/editor.dataTables.css}"> <link rel="stylesheet" th:href="@{/plugins/datatable_editor/css/editor.dataTables.css}">
<link rel="stylesheet" th:href="@{/plugins/toastr/toastr.min.css}">
<script src="https://cdn.datatables.net/2.0.7/js/dataTables.js"></script> <script src="https://cdn.datatables.net/2.0.7/js/dataTables.js"></script>
<script src="https://cdn.datatables.net/buttons/3.0.2/js/dataTables.buttons.js"></script> <script src="https://cdn.datatables.net/buttons/3.0.2/js/dataTables.buttons.js"></script>
@ -138,12 +139,34 @@
<script th:src="@{/plugins/datatable_editor/js/dataTables.editor.js}"></script> <script th:src="@{/plugins/datatable_editor/js/dataTables.editor.js}"></script>
<script th:src="@{/plugins/datatable_editor/js/editor.dataTables.js}"></script> <script th:src="@{/plugins/datatable_editor/js/editor.dataTables.js}"></script>
<script th:src="@{/plugins/toastr/toastr.min.js}"></script>
<script> <script>
toastr.options = {
"timeOut": "3000" // 알림이 자동으로 사라지기까지 걸리는 시간 (밀리초, 예: 5000은 5초)
// ,"closeButton": false // 알림에 닫기 버튼을 표시할지 여부 (true: 표시, false: 표시 안함)
// ,"debug": false // 디버그 모드 활성화 여부 (true: 활성화, false: 비활성화)
// ,"newestOnTop": false // 최신 알림을 맨 위에 표시할지 여부 (true: 최신 알림이 맨 위, false: 맨 아래)
// ,"progressBar": false // 알림에 진행 막대를 표시할지 여부 (true: 표시, false: 표시 안함)
// ,"positionClass": "toast-top-right" // 알림의 위치 설정 (가능한 값: 'toast-top-right' 'toast-bottom-right' 'toast-bottom-left' 'toast-top-left' 'toast-top-full-width' 'toast-bottom-full-width' 'toast-top-center' 'toast-bottom-center')
// ,"preventDuplicates": false // 중복 알림을 방지할지 여부 (true: 방지 false: 방지 안함)
// ,"onclick": null // 알림 클릭 시 호출될 함수 (기본값: null 예: function() { alert('Clicked!'); })
// ,"showDuration": "300" // 알림이 나타나는 데 걸리는 시간 (밀리초 예: 300)
// ,"hideDuration": "1000" // 알림이 사라지는 데 걸리는 시간 (밀리초 예: 1000)
// ,"extendedTimeOut": "1000" // 알림에 마우스를 올려놓았을 때 추가로 유지되는 시간 (밀리초 예: 1000)
// ,"showEasing": "swing" // 알림이 나타날 때 애니메이션 방식 (가능한 값: 'swing' 'linear')
// ,"hideEasing": "linear" // 알림이 사라질 때 애니메이션 방식 (가능한 값: 'swing' 'linear')
// ,"showMethod": "fadeIn" // 알림이 나타날 때 사용되는 애니메이션 효과 (가능한 값: 'fadeIn' 'slideDown' 'show')
// ,"hideMethod": "fadeOut" // 알림이 사라질 때 사용되는 애니메이션 효과 (가능한 값: 'fadeOut' 'slideUp' 'hide')
};
// https://editor.datatables.net/examples/simple/simple.html // https://editor.datatables.net/examples/simple/simple.html
var editor = new DataTable.Editor({ var editor = new DataTable.Editor({
ajax: { ajax: {
type: 'POST', type: 'POST',
url: '/dictionary/api/update', url: '/dict/api/update',
contentType: 'application/json', // Content-Type을 application/json으로 설정 contentType: 'application/json', // Content-Type을 application/json으로 설정
data: function (d) { data: function (d) {
return JSON.stringify(d); // 데이터를 JSON 문자열로 변환 return JSON.stringify(d); // 데이터를 JSON 문자열로 변환
@ -181,17 +204,18 @@
{ label: 'Yes', value: 'Y' }, { label: 'Yes', value: 'Y' },
{ label: 'No', value: 'N' } { label: 'No', value: 'N' }
] ]
}, }
{ /*,{
label: '최근수정자:', label: '최근수정자:',
name: 'lastUpdusrName' name: 'lastUpdusrName'
}, // ,type: 'readonly' // 수정 불가능하게 설정
{ }
,{
label: '수정시간:', label: '수정시간:',
name: 'lastUpdtPnttm', name: 'lastUpdtPnttm',
type: 'datetime', format: 'YYYY-MM-DD HH:mm:ss',
format: 'YYYY-MM-DD HH:mm:ss' type: 'readonly' // 수정 불가능하게 설정
} }*/
] ]
}); });
@ -292,7 +316,7 @@
var table = $('#dicTb').DataTable({ var table = $('#dicTb').DataTable({
"pageLength": 100, "pageLength": 100,
ajax: { ajax: {
url: '/dictionary/list/load', url: '/dict/list/load',
type: 'GET', type: 'GET',
dataSrc: '' dataSrc: ''
}, },
@ -345,7 +369,7 @@
] ]
} }
}, },
order: [0, 'asc'], order: [5, 'desc'], // "확정" 열을 기준으로 기본 정렬 설정
select: { select: {
style: 'os', style: 'os',
selector: 'td:first-child' selector: 'td:first-child'
@ -353,13 +377,37 @@
}); });
// 필드 클릭해서 수정할수 있는 옵션 // 필드 클릭해서 수정할수 있는 옵션
$('#dicTb').on('click', 'tbody td:not(:first-child)', function (e) { // $('#dicTb').on('click', 'tbody td:not(:first-child)', function (e) {
// editor.inline(this);
// });
// 필드 클릭해서 수정할 수 있는 옵션
$('#dicTb').on('click', 'tbody td:not(:first-child):not(:nth-child(7)):not(:nth-child(8))', function (e) {
editor.inline(this); editor.inline(this);
}); });
editor.on('submitSuccess', function() {
// editor.DataTable().destroy(); editor.on('submitSuccess', function(e, json, data, action) {
table.ajax.reload(null, false); // 수정이 성공한 후 테이블 데이터 리로드 var message = '';
if (action === 'create') {
message = '단어 등록 성공';
toastr.success(message)
} else if (action === 'edit') {
message = '단어 수정 성공';
toastr.info(message)
} else if (action === 'remove') {
message = '단어 삭제 성공';
toastr.error(message)
}
table.ajax.reload(null, false);
// fn_successAlert(message);
}); });
/*
editor.on('postRemove', function() {
// 삭제된 데이터를 가져와 메시지에 포함
var message = '단어 삭제 성공';
fn_successAlert(message);
});*/
// 삭제 버튼 클릭 이벤트 // 삭제 버튼 클릭 이벤트
table.on('click', 'td.editor-delete button', function (e) { table.on('click', 'td.editor-delete button', function (e) {

View File

@ -69,7 +69,7 @@
</ul> </ul>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a th:href="@{/dictionary/list}" class="nav-link"> <a th:href="@{/dict/list}" class="nav-link">
<i class="nav-icon fas fa-book"></i> <i class="nav-icon fas fa-book"></i>
<p>단어사전</p> <p>단어사전</p>
<!-- <i class="nav-icon fas fa-th"></i>--> <!-- <i class="nav-icon fas fa-th"></i>-->

View File

@ -112,11 +112,11 @@
<tbody> <tbody>
<tr th:each="row, stat : ${list}"> <tr th:each="row, stat : ${list}">
<td th:text="${stat.count}"></td> <td th:text="${stat.count}"></td>
<td th:text="${row.id}"></td> <td th:text="${row.uniqId}"></td>
<td th:text="${row.userId}"></td> <td th:text="${row.userId}"></td>
<td th:text="${row.username}"></td> <td th:text="${row.username}"></td>
<td> <td>
<select th:data-id="${row.id}" onchange="updateRole(this)"> <select th:data-uniqid="${row.uniqId}" onchange="updateRole(this)">
<option th:each="role : ${roles}" th:value="${role}" th:text="${role}" th:selected="${role == row.role}"></option> <option th:each="role : ${roles}" th:value="${role}" th:text="${role}" th:selected="${role == row.role}"></option>
</select> </select>
</td> </td>
@ -199,39 +199,40 @@
} ); } );
function updateRole(selectElement) { function updateRole(selectElement) {
var id = $(selectElement).data("id"); var uniqId = $(selectElement).data("uniqid");
var role = $(selectElement).val(); var role = $(selectElement).val();
console.log(id) console.log('uniqId : ', uniqId);
console.log(role) console.log('role : ', role);
$.ajax({ $.ajax({
url: "/user/updateRole", url: "/user/updateRole",
type: "POST", type: "POST",
data: { data: {
id: id, uniqId: uniqId,
role: role role: role
}, },
success: function(response) { success: function(response) {
console.log('response : ', response); console.log('response : ', response);
if (response.status === "OK") { if (response.status === "OK") {
fn_successAlert(id, role, response.msg); fn_successAlert(uniqId, role, response.msg);
} else { } else {
fn_failedAlert(); fn_failedAlert();
} }
}, },
error: function() { error: function(jqXHR, textStatus, errorThrown) {
alert("Error while updating role."); console.error("Error while updating role: ", textStatus, errorThrown);
fn_failedAlert("서버와 통신 중 오류가 발생했습니다. 다시 시도해 주세요.");
} }
}); });
} }
function fn_successAlert(id, role, msg){ function fn_successAlert(uniqId, role, msg){
$(document).Toasts('create', { $(document).Toasts('create', {
class: 'bg-info', class: 'bg-info',
title: msg, title: msg,
subtitle: '', subtitle: '',
autohide : true, autohide : true,
delay: 3000, delay: 3000,
body: id+'의 권한을 \''+ role+'\'으로 수정하였습니다.' body: uniqId+'의 권한을 \''+ role+'\'으로 수정하였습니다.'
}) })
} }
function fn_failedAlert(){ function fn_failedAlert(){