<td th:text="${x.userId}">kdew0308@naver.com</td>
를 아래와 같이 수정
<td >
<a th:text="${x.userId}"
th:href="${'detail.do?userId=' + x.userId}">
kdew0308@naver.com
</a>
</td>
String userId; // detail에 사용
추가
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>관리자 화면</title>
<style>
.detail table {
width: 100%;
border-collapse: collapse;
}
.detail table th, .detail table td {
border: solid 1px #000;
}
</style>
</head>
<body>
<h1>관리자 회원 관리 - 회원 상세 정보</h1>
<div>
<a href="/admin/main.do">관리자 메인</a>
|
<a href="/admin/member/list.do">회원 관리</a>
|
<a href="#">카테고리 관리</a>
|
<a href="#">강의 관리</a>
|
<a href="/member/logout">로그아웃</a>
<br/>
<hr/>
</div>
<div class="detail">
<table>
<tbody>
<tr>
<th>아이디</th>
<td>
<p th:text="${member.userId}"></p>
</td>
</tr>
<tr>
<th>이름</th>
<td>
<p th:text="${member.userName}"></p>
</td>
</tr>
<tr>
<th>연락처</th>
<td>
<p th:text="${member.phone}"></p>
</td>
</tr>
<tr>
<th>가입일</th>
<td>
<p th:text="${member.regDt}"></p>
</td>
</tr>
<tr>
<th>이메일 인증</th>
<td>
<p th:text="${member.emailAuthYn}"></p>
</td>
</tr>
<tr>
<th>관리자 여부</th>
<td>
<p th:text="${member.adminYn}"></p>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
MemberDto detail(String userId);
추가
detail은 jpa 사용하는 것이 유리!
@Override
public MemberDto detail(String userId) {
Optional<Member> optionalMember = memberRepository.findById(userId);
if (!optionalMember.isPresent()) {
return null;
}
Member member = optionalMember.get();
return MemberDto.of(member);
}
@AllArgsConstructor
@NoArgsConstructor
@Builder
추가
public static MemberDto of(Member member) {
return MemberDto.builder()
.userId(member.getUserId())
.userName(member.getUserName())
.phone(member.getPhone())
.regDt(member.getRegDt())
.emailAuthYn(member.isEmailAuthYn())
.emailAuthDt(member.getEmailAuthDt())
.emailAuthKey(member.getEmailAuthKey())
.resetPasswordKey(member.getResetPasswordKey())
.resetPasswordLimitDt(member.getResetPasswordLimitDt())
.adminYn(member.isAdminYn())
.build();
}
detail 추가
@GetMapping("/admin/member/detail.do")
public String detail(Model model, MemberParam parameter) {
parameter.init();
MemberDto member = memberService.detail(parameter.getUserId());
model.addAttribute("member", member);
return "admin/member/detail";
}
목록 클릭 시 회원 관리 화면으로 이동
회원 상태를 위해
private String userStatus;
MemberCode 연관성을 위해 상속받기
public class Member implements MemberCode
public interface MemberCode {
String MEMBER_STATUS_ING = "ING"; // 현재 이용중인 상태
String MEMBER_STATUS_STOP = "STOP"; // 현재 정지된 상태
}
.userStatus(Member.MEMBER_STATUS_REQ)
추가member.setUserStatus(Member.MEMBER_STATUS_ING);
추가if (Member.MEMBER_STATUS_REQ.equals(member.getUserStatus())) {
throw new MemberNotEmailAuthException("이메일 활성화 이후에 로그인을 해주세요.");
}
if (Member.MEMBER_STATUS_STOP.equals(member.getUserStatus())) {
throw new MemberStopUserException("정지된 회원입니다.");
}
public class MemberStopUserException extends RuntimeException {
public MemberStopUserException(String error) {
super(error);
}
}
<th>회원 상태</th>
<td>
<p>
현재상태: <span th:text="${member.userStatus}"></span>
</p>
<div>
<form method="post" action="/admin/member/status.do">
<input th:value="${member.userId}" type="hidden" name="userId" >
<select name="userStatus">
<option value="REQ">가입승인중</option>
<option value="ING">정상이용중</option>
<option value="STOP">정지중</option>
</select>
<button type="submit">상태 변경</button>
</form>
</div>
</td>
String userStatus;
매핑 부분에 .userStatus(member.getUserStatus())
@PostMapping("/admin/member/status.do")
public String status(Model model, MemberStatusInput parameter) {
boolean result = memberService.updateStatus(parameter.getUserId(), parameter.getUserStatus());
return "redirect:/admin/member/detail.do?userId=" + parameter.getUserId();
}
@Data
public class MemberInput {
String userId;
String userStatus;
}
/**
* 회원 상태 변경
*/
boolean updateStatus(String userId, String userStatus);
@Override
public boolean updateStatus(String userId, String userStatus) {
Optional<Member> optionalMember = memberRepository.findById(userId);
if (!optionalMember.isPresent()) {
throw new UsernameNotFoundException("회원 정보가 존재하지 않습니다.");
}
Member member = optionalMember.get();
member.setUserStatus(userStatus);
memberRepository.save(member);
return true;
}
<tr>
<th>비밀번호 초기화</th>
<td>
<div>
<form method="post" action="/admin/member/password.do">
<input th:value="${member.userId}" type="hidden" name="userId">
<input type="text" name="password" >
<button type="submit">비밀번호 초기화</button>
</form>
</div>
</td>
</tr>
@PostMapping("/admin/member/password.do")
public String password(Model model, MemberInput parameter) {
boolean result = memberService.updatePassword(parameter.getUserId(), parameter.getUserStatus());
return "redirect:/admin/member/detail.do?userId=" + parameter.getUserId();
}
String password;
/**
* 회원 비밀번호 초기화
*/
boolean updatePassword(String userId, String userStatus);
이후에 에러 발생해서
/**
* 회원 비밀번호 초기화
*/
boolean updatePassword(String userId, String password);
위와 같이 변경
@Override
public boolean updatePassword(String userId, String password) {
Optional<Member> optionalMember = memberRepository.findById(userId);
if (!optionalMember.isPresent()) {
throw new UsernameNotFoundException("회원 정보가 존재하지 않습니다.");
}
Member member = optionalMember.get();
String encPassword = BCrypt.hashpw(password, BCrypt.gensalt());
member.setPassword(encPassword);
memberRepository.save(member);
return true;
}
java.lang.NullPointerException: null
컨트롤러에서 서비스로 가져오는 사이에 null값을 가져옴
컨트롤러에서
boolean result = memberService.updatePassword(parameter.getUserId(), parameter.getUserStatus());
를 boolean result = memberService.updatePassword(parameter.getUserId(), parameter.getPassword());
로 수정
서비스에서
boolean updatePassword(String userId, String userStatus);
변경
boolean updatePassword(String userId, String password);
변경된 비밀번호로 로그인 성공