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);
// 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;
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.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
@ -13,32 +15,56 @@ import org.springframework.web.servlet.ModelAndView;
@Slf4j
public class UserInterceptor implements HandlerInterceptor {
private final UserService userService;
public UserInterceptor(UserService userService) {
this.userService = userService;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
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();
Object principal = authentication.getPrincipal();
if (authentication != null && authentication.isAuthenticated()) {
Object principal = authentication.getPrincipal();
String userId;
String userName;
String id;
String userName;
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();
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);
// 로그인 로그를 기록
userService.requestLogs(id, request.getRequestURL().toString());
} else {
userId = principal.toString();
userName = principal.toString();
log.info("No authenticated user found.");
}
log.info("userId : [{}]",userId.toString());
log.info("userName : [{}]",userName.toString());
modelAndView.addObject("userId", userId);
modelAndView.addObject("userName", userName);
}
}
}

View File

@ -1,5 +1,7 @@
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.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ -7,9 +9,14 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private UserService userService;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserInterceptor())
.addPathPatterns("/**");
registry.addInterceptor(new UserInterceptor(userService))
.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 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 java.io.Serializable;
import java.sql.Date;
/**
* 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.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.itn.dictionary.mapper.DictionaryMapper;
import com.itn.admin.itn.dictionary.mapper.domain.DictionaryVO;
import com.itn.admin.itn.dictionary.service.DictionaryService;
import com.itn.admin.itn.dict.mapper.DictionaryMapper;
import com.itn.admin.itn.dict.mapper.domain.DictionaryVO;
import com.itn.admin.itn.dict.service.DictionaryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
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.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@ -15,7 +15,7 @@ public class DictionaryController {
this.dictionaryService = dictionaryService;
}
@GetMapping(value = "/dictionary/list")
@GetMapping(value = "/dict/list")
public String list() {
// public String list(@ModelAttribute("dictionaryVO") DictionaryVO dictionaryVO, Model model) {
//
@ -24,7 +24,7 @@ public class DictionaryController {
//
// 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.dictionary.service.DictionaryService;
import com.itn.admin.itn.dict.mapper.domain.DictionaryVO;
import com.itn.admin.itn.dict.service.DictionaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -24,7 +21,7 @@ public class DictionaryRestController {
// 데이터 불러오기
@GetMapping("/dictionary/list/load")
@GetMapping("/dict/list/load")
public ResponseEntity<List<DictionaryVO>> loadData() {
// 데이터베이스에서 데이터를 조회하는 로직
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) {
// 데이터 처리 로직
// : 데이터베이스에서 기존 데이터를 수정

View File

@ -1,27 +1,23 @@
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 org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
import java.util.stream.Collectors;
@Mapper
public interface UserMapper {
// 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);
@Select("SELECT id, user_id AS userId, user_pw AS password, user_name AS username, role FROM users WHERE id = #{id}")
UserVO findById(String 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 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);
@ -39,6 +35,11 @@ public interface UserMapper {
void updateRole(UserVO user);
@Insert("INSERT INTO login_logs (id, FRST_REGIST_PNTTM) VALUES (#{id}, now())")
void loginLog(String id);
@Insert("INSERT INTO login_logs (uniqId, FRST_REGIST_PNTTM) VALUES (#{uniqId}, now())")
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
@NoArgsConstructor
public class UserVO implements UserDetails {
private String id;
private String uniqId;
private String userId;
private String password;
private String username;

View File

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

View File

@ -55,8 +55,8 @@ public class UserServiceImpl implements UserService {
}
@Override
public RestResponse updateRole(String id, Role role) {
UserVO user = userMapper.findById(id);
public RestResponse updateRole(String uniqId, Role role) {
UserVO user = userMapper.findById(uniqId);
if (user != null) {
user.setRole(role);
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.web.servlet.mvc.support.RedirectAttributes;
import java.util.Collections;
import java.util.UUID;
@Controller
@ -55,7 +54,7 @@ public class LoginController {
}
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.setUsername(userDTO.getUserName());
user.setPassword(passwordEncoder.encode(userDTO.getPassword()));

View File

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

View File

@ -12,6 +12,6 @@
<!-- Type Aliases 설정-->
<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>
</configuration>

View File

@ -3,10 +3,10 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"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="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
a.id
, a.KOREAN_WORD
@ -21,7 +21,7 @@
, b.USER_NAME as lastUpdusrName
FROM dictionary a
LEFT JOIN users b
ON a.LAST_UPDUSR_ID = b.ID
ON a.LAST_UPDUSR_ID = b.uniq_id
</select>
@ -64,15 +64,17 @@
, ENGLISH_WORD
, ABBREVIATION
, IS_CONFIRMED
, LAST_UPDUSR_ID
, FRST_REGIST_PNTTM
)
values
(
#{koreanWord}
, #{englishWord}
, #{abbreviation}
, #{isConfirmed}
, NOW()
#{koreanWord}
, #{englishWord}
, #{abbreviation}
, #{isConfirmed}
, #{userId}
, NOW()
);
</insert>

View File

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

View File

@ -15,7 +15,7 @@
<!-- 별칭 -->
<typeAliases>
<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"/>
</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/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/toastr/toastr.min.css}">
<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>
@ -138,12 +139,34 @@
<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/toastr/toastr.min.js}"></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
var editor = new DataTable.Editor({
ajax: {
type: 'POST',
url: '/dictionary/api/update',
url: '/dict/api/update',
contentType: 'application/json', // Content-Type을 application/json으로 설정
data: function (d) {
return JSON.stringify(d); // 데이터를 JSON 문자열로 변환
@ -181,17 +204,18 @@
{ label: 'Yes', value: 'Y' },
{ label: 'No', value: 'N' }
]
},
{
}
/*,{
label: '최근수정자:',
name: 'lastUpdusrName'
},
{
// ,type: 'readonly' // 수정 불가능하게 설정
}
,{
label: '수정시간:',
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({
"pageLength": 100,
ajax: {
url: '/dictionary/list/load',
url: '/dict/list/load',
type: 'GET',
dataSrc: ''
},
@ -345,7 +369,7 @@
]
}
},
order: [0, 'asc'],
order: [5, 'desc'], // "확정" 열을 기준으로 기본 정렬 설정
select: {
style: 'os',
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.on('submitSuccess', function() {
// editor.DataTable().destroy();
table.ajax.reload(null, false); // 수정이 성공한 후 테이블 데이터 리로드
editor.on('submitSuccess', function(e, json, data, action) {
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) {

View File

@ -69,7 +69,7 @@
</ul>
</li>
<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>
<p>단어사전</p>
<!-- <i class="nav-icon fas fa-th"></i>-->

View File

@ -112,11 +112,11 @@
<tbody>
<tr th:each="row, stat : ${list}">
<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.username}"></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>
</select>
</td>
@ -199,39 +199,40 @@
} );
function updateRole(selectElement) {
var id = $(selectElement).data("id");
var uniqId = $(selectElement).data("uniqid");
var role = $(selectElement).val();
console.log(id)
console.log(role)
console.log('uniqId : ', uniqId);
console.log('role : ', role);
$.ajax({
url: "/user/updateRole",
type: "POST",
data: {
id: id,
uniqId: uniqId,
role: role
},
success: function(response) {
console.log('response : ', response);
if (response.status === "OK") {
fn_successAlert(id, role, response.msg);
fn_successAlert(uniqId, role, response.msg);
} else {
fn_failedAlert();
}
},
error: function() {
alert("Error while updating role.");
error: function(jqXHR, textStatus, errorThrown) {
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', {
class: 'bg-info',
title: msg,
subtitle: '',
autohide : true,
delay: 3000,
body: id+'의 권한을 \''+ role+'\'으로 수정하였습니다.'
body: uniqId+'의 권한을 \''+ role+'\'으로 수정하였습니다.'
})
}
function fn_failedAlert(){