Spring Boot Board Project_13 회원 탈퇴

송지윤·2024년 4월 20일
0

Spring Framework

목록 보기
46/65

1. 탈퇴하기 관련 요소 얻어와서 탈퇴 유효성 검사해주기

myPage.js

const secession = document.querySelector("#secession");

if(secession != null) {
    
    secession.addEventListener("submit", e => {

        const memberPw = document.querySelector("#memberPw");
        const agree = document.querySelector("#agree");

        // - 비밀번호 입력 되었는지 확인
        if(memberPw.value.trim().length == 0) {
            alert("비밀번호를 입력해주세요");
            e.preventDefault(); // 제출 막기
            return;
        }

        // 약관 동의 체크 확인
        // checkbox 또는 radio checked 속성
        // - checked -> 체크 시 true, 미체크시 false 반환

        if(!agree.checked) { // 체크 안 됐을 때
            alert("약관에 동의해주세요");
            e.preventDefault();
            return;
        }

        // 정말 탈퇴? 물어보기
        if(!confirm("정말 탈퇴 하시겠습니까?")) {
            // 취소 눌렀을 때
            alert("취소 되었습니다.");
            e.preventDefault();
            return;
        }
    });
}

2. 제출하기 눌렀을 때 Controller 에서 값 받아주기

myPage-secession.html

상대경로로 myPage/secession 으로 값 넘김

<form action="secession" method="POST" name="myPageFrm" id="secession">

SessionStatus

세션 완료 용도의 객체
-> @SessionAttributes 로 등록된 세션을 완료시킬 거

.setComplete(); 세션 완료 시킴

서비스 호출

MyPageController

	@PostMapping("secession")
	public String secession(
			@RequestParam("memberPw") String memberPw,
			@SessionAttribute("loginMember") Member loginMember,
			SessionStatus status,
			RedirectAttributes ra
			) {
		
		// session scope 에 있는 loginMember 를 지워줘야함
		// SessionStatus 이용 등록된 세션 완료
		
		// 서비스 호출
		int memberNo = loginMember.getMemberNo();
		
		int result = service.secession(memberPw, memberNo);

3. Service 에서 Controller 에서 넘겨준 값을 하나의 매개변수로 만들어서mapper.xml 호출

MyPageServiceImpl

	@Override
	public int secession(String memberPw, int memberNo) {

		String originPw = mapper.selectPw(memberNo);
		
		if(!bcrypt.matches(memberPw, originPw)) {
			return 0;
		}
		
		return mapper.secession(memberNo);
	}

myPage-mapper.xml
회원 탈퇴 여부 Y 로 변경

	<!-- 회원 탈퇴 -->
	<update id="secession">
		UPDATE "MEMBER" SET
		MEMBER_DEL_FL = 'Y'
		WHERE MEMBER_NO = #{memberNo}
	</update>

4. SQL 문 실행하고 돌아온 값에 따라 Controller 에서 분기 처리

MyPageController

		String message = null;
		String path = null;
		
		if(result > 0) {
			// 탈퇴 성공시
			message = "탈퇴 되었습니다.";
			path = "/";
			
			// loginMember 세션 만료
			status.setComplete(); // 세션 완료 시킴
			
		} else {
			// 탈퇴 실패시
			message = "비밀번호가 일치하지 않습니다.";
			path = "secession";
		}
		
		ra.addFlashAttribute("message", message);
		
		return "redirect:" + path;
    }

빠른 로그인

main.html

        <h3>빠른 로그인</h3>

        <button class="quick-login">user01@kh.or.kr</button>
        <button class="quick-login">board1@home.com</button>
        <button class="quick-login">board2@home.com</button>
        <button class="quick-login">delete@home.com</button>

1. main.html 과 연결된 main.js 에서 요소 얻어와서 click 됐을 때 Controller 로 값 넘겨주기

main.js

const quickLoginBtns = document.querySelectorAll(".quick-login");

quickLoginBtns.forEach((item, index) => {
    // item : 현재 반복 시 꺼내온 객체
    // index : 현재 반복 중인 인덱스

    // quickLoginBtns 요소인 button 태그 하나씩 꺼내서 이벤트 리스너 추가
    item.addEventListener("click", () => { // 각 버튼에 클릭 이벤트 추가
        const email = item.innerText; // 버튼에 작성된 이메일 얻어오기

        location.href = "/member/quickLogin?memberEmail=" + email;
    })
});

2. MemberController 에서 값 받아서 Service 호출해주기

MemberController

	@GetMapping("quickLogin")
	public String quickLogin(
			@RequestParam("memberEmail") String memberEmail,
			Model model,
			RedirectAttributes ra
			) {
		
		Member loginMember = service.quickLogin(memberEmail);
		
		if(loginMember == null) {
			ra.addFlashAttribute("message", "해당 이메일이 존재하지 않습니다.");
		} else {
			model.addAttribute("loginMember", loginMember);
		}
		
		return "redirect:/";
	}

3. Service 에서 전달 받은 값으로 mapper.xml sql 조회 후 분기 처리

MemberServiceImpl

	@Override
	public Member quickLogin(String memberEmail) {
		
		Member loginMember = mapper.login(memberEmail);
		
		// 탈퇴 or 없는 회원
		if(loginMember == null) return null;
		
		// 조회된 비밀번호 null 로 변경
		loginMember.setMemberPw(null);
		
		return loginMember;
	}

버튼 클릭 시 로그인 됨

회원 목록 조회(비동기)

main.html

        <h3>
          회원 목록 조회(비동기)
          <button id="selectMemberList">조회</button>
        </h3>

        <table border="1">
          <thead>
            <th>회원번호</th>
            <th>이메일</th>
            <th>닉네임</th>
            <th>탈퇴 여부</th>
          </thead>

          <tbody id="memberList"></tbody>
        </table>

1. js 로 요소 얻어와서 조회 버튼 클릭 시 fetch 요청 보내기

// 조회 버튼
const selectMemberList = document.querySelector("#selectMemberList");

// tbody
const memberList = document.querySelector("#memberList");

// 조회 버튼 클릭 시
selectMemberList.addEventListener("click", () => {

    // 1) 비동기로 회원 목록 조회
    // (포함될 회원 정보 : 회원번호, 이메일, 닉네임, 탈퇴여부)

    fetch("/member/selectMemberList")

2. 요청 받은 Controller 에서 service 요청

	@ResponseBody
	@GetMapping("selectMemberList")
	public List<Member> selectMemberList() {
		
		return service.selectMemberList();
	}

3. Service 에서 mapper 호출

MemberServiceImpl

	@Override
	public List<Member> selectMemberList() {
		return mapper.selectMemberList();
	}

member-mapper.xml

	<select id="selectMemberList" resultType="Member">
		SELECT MEMBER_NO, MEMBER_EMAIL, MEMBER_NICKNAME, MEMBER_DEL_FL
		FROM "MEMBER"
		ORDER BY MEMBER_NO
	</select>

4. 돌아온 결과 값을 Controller 에서 js 로 넘겨줌 js 에서 넘어온 값 처리

넘어온 값이 memberList 라서 .json() 으로 바꿈

main.js

// td 요소를 만들고 text 추가 후 반환
const createTd = (text) => {
    const td = document.createElement("td");
    td.innerText = text;
    return td;
}

// 조회 버튼 클릭 시
selectMemberList.addEventListener("click", () => {

    // 1) 비동기로 회원 목록 조회
    // (포함될 회원 정보 : 회원번호, 이메일, 닉네임, 탈퇴여부)

    fetch("/member/selectMemberList")
    .then(resp => resp.json())
    .then(list => {
        // list 바로 이용 -> JS 객체 배열

        // 이전 내용 삭제
        memberList.innerHTML = "";

        //tbody에 들어갈 요소를 만들고 값 세팅 후 추가
        list.forEach((member,index) => {
            // member : 현재 반복 접근 중인 요소
            // index : 현재 접근 중인 인덱스

            // tr 만들어서 그 안에 td 만들고, append 후
            // tr 을 tbody에 append

            const keyList = ['memberNo', 'memberEmail', 'memberNickname', 'memberDelFl'];

            const tr = document.createElement("tr");

            keyList.forEach(key => tr.append(createTd(member[key])));
          
            // tbody 자식으로 tr 추가
            memberList.append(tr);
        });
    })
});

특정 회원 비밀번호 초기화

main.html

        <h3>특정 회원 비밀번호 초기화(Ajax)</h3>
        <div>
          회원번호:
          <input type="text" id="resetMemberNo">
          <button id="resetPw">비밀번호 초기화</button>
        </div>

1. js 에서 fetch 로 controller 에 값 보내주기

const resetMemberNo = document.querySelector("#resetMemberNo");
const resetPw = document.querySelector("#resetPw");

resetPw.addEventListener("click", () => {

    // 입력 받은 회원 번호 얻어오기
    const inputNo = resetMemberNo.value;

    if(inputNo.trim().length === 0) {
        alert("회원 번호를 입력해주세요.");
        return;
    }

    fetch("/member/resetPw", {
        method : "PUT", // PUT : 수정 요청 방식
        headers : {"Content-Type" : "application/json"},
        body : inputNo
    })

2. Controller 에서 값 받아서 service 호출

	@ResponseBody
	@PutMapping("resetPw")
	public int resetPw(@RequestBody int inputNo) {
		return service.resetPw(inputNo);
	}

3. Service 에서 초기화할 비밀번호를 암호화한 후 Map 에 넣어서 inputNo 와 같이 mapper 에 전달

	@Override
	public int resetPw(int inputNo) {

		// pass01! -> 암호화
		String encPw = bcrypt.encode("pass01!");
		
		Map<String, Object> map = new HashMap<>();
		map.put("inputNo", inputNo);
		map.put("encPw", encPw);
		
		return mapper.resetPw(map);
	}

mapper.xml

	<update id="resetPw">
		UPDATE "MEMBER" SET
		MEMBER_PW = #{encPw}
		WHERE MEMBER_NO = #{inputNo}
	</update>

4. js 에서 돌려받은 값으로 분기처리

    .then(resp => resp.text())
    .then(result => {

        if(result > 0) {
            alert("초기화 성공");
        } else {
            alert("해당 회원이 존재하지 않습니다.");
        }
    });

특정 회원 탈퇴 복구 (ajax)

main.html

        <h3>특정 회원(회원번호) 탈퇴 복구 (Ajax)</h3>
        <div>
          회원번호 : 
          <input type="text" id="restorationMemberNo">
          <button id="restorationBtn">복구하기</button>
        </div>

1. 요소 얻어와서 Controller 로 값 보내주기

const restorationBtn = document.querySelector("#restorationBtn");
const restorationMemberNo = document.querySelector("#restorationMemberNo");

restorationBtn.addEventListener("click", () => {

    if(restorationMemberNo.value.trim().length == 0) {
        alert("회원번호를 입력해주세요");
        return;
    } else {
        
        const memberNo = restorationMemberNo.value;
    
        fetch("/member/restorationMemberNo", {
            method : "PUT",
            headers : {"Content-Type" : "application/json"},
            body : memberNo
        })

2. Controller 에서 값 받아서 Service 호출

	@ResponseBody
	@PutMapping("restorationMemberNo")
	public int restorationMemberNo(@RequestBody int memberNo) {
		return service.restorationMemberNo(memberNo);
	}

3. Service 에서 값 받아서 mapper 호출

	@Override
	public int restorationMemberNo(int memberNo) {
		return mapper.restorationMemberNo(memberNo);
	}

4. 값 가지고 돌아와서 js 분기처리

        .then(resp => resp.text())
        .then(result => {
            // update 결과값 반환
            if(result > 0) {
                restorationMemberNo.value = "";
                alert("탈퇴 복구 성공");
            } else {
                restorationMemberNo.value = "";
                alert("존재하지 않는 회원 번호입니다.");
            }
        })
    }

0개의 댓글