저번글의 관리자 로그인 및 로그아웃 구현에 이어서 이번 글에서는 회원관리에 대해서 기능을 구현하고, 설명하려고 합니다. 부족해도 좋게 봐주세요 :)
adminMain.html에서 작성해 놓은
<!-- 회원관리 섹션 -->
<div class="admin-section">
<h3 class="clickable" onclick="toggleContent(this)">회원 관리</h3>
<div class="content-list" style="display: none;">
<a th:href="@{/admin-customer-list}">회원리스트</a><br>
</div>
</div>
<a th:href="@{/admin-customer-list}">회원리스트</a> a링크를 통해서 /admin-customer-list URL로 GET 요청이 전송됩니다.
// 회원관리 페이지
@GetMapping("/admin-customer-list")
public String allCustomerList(HttpSession session, Model model) {
Member admin = (Member)session.getAttribute("admin");
if(admin == null) {
model.addAttribute("message", "로그인 페이지로 이동");
model.addAttribute("text", "회원관리를 위해 로그인해주세요.");
model.addAttribute("messageType", "info");
return "admin/admin_login";
}
// 회원 목록을 가져오는 로직 구현
List<Member> members = memberService.getAllMembers();
model.addAttribute("members", members);
return "admin/section/customer_list"; // 뷰 이름
}
- Member admin = (Member)session.getAttribute("admin"); : session 객체에서 현재 로그인된 관리자의 정보를 admin 변수에 저장합니다.
- List<Member> members = memberService.getAllMembers(); : 전체 회원 목록을 가져오고, 반환된 members 리스트를 model.addAttribute("members", members); 를 통해 모델에 추가합니다.
-- getAllMembers() 메서드 (repository, serviceimpl)
- Repository
// 전체 회원목록 조회
@Query(value="SELECT * FROM member ORDER BY signup_date DESC", nativeQuery=true)
List<Member> getAllMember();
- ServiceImpl
// 관리자용
@Override
public List<Member> getAllMembers() {
return memberRepo.getAllMember();
}
customer_list.html
<div class="all-container">
<h1>회원 관리</h1>
<label for="searchMember"></label>
<input type="text" id="searchMember" placeholder="회원 검색 ( ID를 입력하세요 )">
<div class="customer-list">
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>Email</th>
<th>이름</th>
<th>회원코드</th>
<th>가입일</th>
<th>회원 탈퇴 여부</th>
</tr>
</thead>
<tbody id="memberTableBody">
<!-- 전체 회원 리스트를 여기에 동적으로 채웁니다 -->
<tr th:each="member : ${members}">
<td th:text="${member.id}"></td>
<td th:text="${member.email}"></td>
<td th:text="${member.name}"></td>
<td>
<span th:text="${member.membercode}"></span>
<button class="update-btn" type="button" th:alt="${member.membercode}"
th:data-memberid="${member.id}" th:data-membercode="${member.membercode}"
onclick="updateMemberCode(this)">수정</button>
</td>
<td th:text="${member.signupDate}"></td>
<td>
<span th:text="${member.withdrawalRequest == 0 ? 'X' : 'O'}"></span>
<button class="delete-btn" type="button" th:alt="${member.withdrawalRequest}"
th:data-memberid="${member.id}" th:data-withdrawalRequest="${member.withdrawalRequest}"
onclick="deleteMember(this)">회원탈퇴</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
+ 회원 검색을 실시간으로 필터링
<label for="searchMember"></label>
<input type="text" id="searchMember" placeholder="회원 검색 ( ID를 입력하세요 )">
// 검색 입력에 따른 실시간 필터링 기능
$(document).ready(function() {
$('#searchMember').on('input', function() {
const searchValue = $(this).val().toLowerCase();
$('#memberTableBody tr').filter(function() {
$(this).toggle($(this).find('td:first').text().
toLowerCase().indexOf(searchValue) > -1);
});
});
});
- $(document).ready(function() {... : 문서가 완전히 로드된 후에 코드를 실행합니다. jQuery로 DOM을 조작할 때 필수적으로 사용되는 구문입니다.
- $('#searchMember').on('input', function() {... : #searchMember(검색 입력 필드)에 사용자가 글자를 입력할 때마다 input 이벤트가 발생합니다. on('input', : 입력 필드에 변화가 있을 때마다 호출됩니다.
- const searchValue = $(this).val().toLowerCase(); : 현재 입력 필드에 있는 텍스트 $(this).val()를 가져옵니다. .toLowerCase();를 사용하여 대소문자 구분 없이 검색할 수 있도록 변환합니다.
- $('#memberTableBody tr').filter(function() {... : #memberTableBody는 회원 목록이 포함된 테이블의 tbody 요소로 가정됩니다. tr은 테이블의 각 행(row)을 나타내며, filter()는 각 행에 대해 조건을 검사하는 함수입니다.
- $(this).toggle($(this).find('td:first').text().toLowerCase().indexOf(searchValue) > -1); : $(this)는 현재 행(tr)을 참조하고, .find('td:first')는 그 행에서 첫 번째 td 요소를 찾습니다..text()는 해당 셀의 텍스트(회원 ID)를 추출합니다 .toLowerCase()를 사용하여 대소문자 구분 없이 비교합니다. .indexOf()는 텍스트 내에서 searchValue가 포함된 위치를 찾습니다.(-1은 찾을 수 없음 >>> searchValue가 해당 텍스트에 포함된 경우로 간주하여 true를 반환.)
+ 회원코드 수정
<button class="update-btn" type="button" th:alt="${member.membercode}"
th:data-memberid="${member.id}" th:data-membercode="${member.membercode}"
onclick="updateMemberCode(this)">수정</button>
버튼 클릭 시 updateMemberCode(button)함수 호출
// 회원코드 수정 함수
function updateMemberCode(button) {
const memberId = button.getAttribute('data-memberid');
const currentMemberCode = button.getAttribute('th:alt');
Swal.fire({
title: '회원코드를 수정합니다.',
input: 'number',
inputLabel: '새로운 회원코드를 입력하세요.',
inputPlaceholder: '0 또는 1을 입력하세요.',
showCancelButton: true,
confirmButtonText: '수정',
cancelButtonText: '취소',
preConfirm: (newMemberCode) => {
if (!newMemberCode || newMemberCode < 0 || newMemberCode > 1) {
Swal.showValidationMessage('올바른 회원코드를 입력하세요. (0 또는 1)');
return false; // 유효성 검사 실패 시 false 반환
}
return newMemberCode; // 유효성 검사 통과 시 새로운 회원코드 반환
}
}).then((result) => {
if (result.isConfirmed) {
// AJAX 요청을 통해 서버에 업데이트 요청을 보냄
$.ajax({
url: `/update-membercode`,
type: 'post',
data: {
id: memberId, // 회원 ID 추가
newMemberCode: result.value // 새로운 회원코드를 포함
},
success: function(response) {
Swal.fire({
title: '성공',
text: response,
icon: 'success'
}).then(() => {
location.reload(); // 확인 버튼 클릭 시 페이지 새로고침
});
},
error: function(xhr) {
// 오류 발생 시 처리
console.error('Error details:', xhr.status, xhr.statusText); // 오류 로그
if (xhr.status === 401) {
Swal.fire({
title: '권한 오류',
text: '로그인 후 다시 시도하세요.',
icon: 'warning'
}).then(() => {
window.location.href = '/admin/admin_login'; // 관리자 로그인 페이지로 리다이렉트
});
} else {
Swal.fire('오류', '회원코드 수정에 실패했습니다. 다시 시도해주세요.', 'error');
}
}
});
}
});
}
- button.getAttribute() : 버튼에 포함된 th:data-memberid th:data-membercode, th:alt속성을 가져와 해당 정보를 memberId와 currentMemberCode 변수에 저장합니다.
- input: 'number', : 숫자만 입력되도록 합니다.
- preConfirm: (newMemberCode) => {...} : if (!newMemberCode || newMemberCode < 0 || newMemberCode > 1) { 함수에서 새로운 회원코드가 0 또는 1인지 확인합니다. 그렇지 않으면 유효성 검사 메시지를 표시하고, 올바른 값을 입력할 때까지 수정이 이루어지지 않도록 합니다.
repository, controller, service 메서드
/* Repository */
// 특정 회원 조회
@Query(value="SELECT * FROM member WHERE id =:id", nativeQuery=true)
Member findMemberById(@Param("id") String id);
/* ServiceImpl */
// 회원코드 수정 메서드
@Override
public void updateMemberCode(String id, int memberCode) {
Member member = memberRepo.findMemberById(id);
if (member != null) {
member.setMembercode(memberCode);
memberRepo.save(member); // 변경된 회원 정보를 저장
}
}
/* Controller */
// 회원코드 수정
@PostMapping("/update-membercode")
public ResponseEntity<String> updateMemberCode(HttpSession session, @RequestParam String id,
@RequestParam int newMemberCode, Model model) {
Member admin = (Member) session.getAttribute("admin");
if (admin == null) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body("로그인후 가능한 기능입니다."); // 401 Unauthorized 응답
}
memberService.updateMemberCode(id, newMemberCode); // 서비스 메서드 호출
return ResponseEntity.ok("회원코드가 수정되었습니다."); // 성공 메시지 반환
}
- memberService.updateMemberCode(id, newMemberCode); 메서드를 호출하여 실제로 회원의 회원코드를 수정합니다. 이 메서드는 @RequestParam String id와 @RequestParam int newMemberCode를 통해 받아온 값을 받아 해당 회원의 정보를 업데이트하는 로직을 처리합니다
'SpringBoot 프로젝트' 카테고리의 다른 글
Spring Boot - 관리자 페이지 (4) (0) | 2024.12.07 |
---|---|
Spring Boot - 관리자 페이지 (3) (0) | 2024.11.30 |
Spring Boot - 관리자 페이지 (1) (0) | 2024.11.25 |
Spring Boot - Q&A 페이지 구현하기 (2) (0) | 2024.11.25 |
Spring Boot - Q&A 페이지 구현하기 (1) (0) | 2024.11.23 |