관리 메뉴

거니의 velog

(21) 마이페이지 > 회원정보수정, 회원탈퇴 페이지 > 코드 리뷰 본문

대덕인재개발원_최종 포트폴리오

(21) 마이페이지 > 회원정보수정, 회원탈퇴 페이지 > 코드 리뷰

Unlimited00 2024. 2. 16. 17:03

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<c:set value="${pageContext.request.contextPath }" var="contextPath" />
<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta charset="UTF-8" />
        <meta name="author" content="부루마불" />
        <meta name="description" content="대덕인재개발원 7월반 4조 부루마불의 여기갈래 프로젝트입니다." />
        <meta name="keywords" content="부루마불, 여기갈래, 여행, 통합, 플랫폼" />
        <meta name="copyright" content="대덕인재개발원" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>여기갈래 &gt; 마이 페이지</title>
        
        <!-- 사용자 페이지 > 헤더세팅 영역 -->
        <tiles:insertAttribute name="headerSettings" />
    	
        <!-- 
    		내부 CSS 
    		- 내부 CSS는 외부 CSS의 스타일링을 건드리지 않기 위해서
    		개별적인 페이지에다 스타일을 적용할 때 종종 쓴다.
    		- 보통 프로토타이핑 테스트용이나, FE Leader의 판단에 따라 여기에
    		추가적인 스타일을 작성한다.
    	-->
    	<style>
    		.msub a {
    			color: #333;
    		}
    	</style>
        
    	<c:if test="${not empty message }">
		    <script type="text/javascript">
		        //alert("${message}");
		        $(function(){
		        	// 성공시
		        	<c:if test="${msgflag eq 'su'}">
		        		Swal.fire({
		                    title: "성공",
		                    text: "${message}",
		                    icon: "success"
		                });
		        	</c:if>
		        	// 실패시
		        	<c:if test="${msgflag eq 'fa'}">
			        	Swal.fire({
		                    title: "실패",
		                    text: "${message}",
		                    icon: "error"
		                });
		        	</c:if>
		        	// 정보성 메시지
		        	<c:if test="${msgflag eq 'in'}">
			        	Swal.fire({
		                    title: "안내",
		                    text: "${message}",
		                    icon: "info"
		                });
		        	</c:if>
		        });
		        <c:remove var="message" scope="request" />
			    <c:remove var="message" scope="session" />
		    </script>
		</c:if>
		
	</head>
    <body class="scroll">
        
        <!-- 사용자 페이지 > 헤더 영역 -->
        <tiles:insertAttribute name="header" />
        
        <!-- 사용자 페이지 > 마이 페이지 구현 영역 -->
        <tiles:insertAttribute name="myPageContainer" />
        
        <!-- 사용자 페이지 > 푸터 영역 -->
		<tiles:insertAttribute name="footer" />
		
		<!-- 사용자 페이지 > 자바스크립트 세팅 영역 -->
		<tiles:insertAttribute name="settings" />

    </body>
</html>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
    
<!-- 마이 페이지 css -->
<link href="${contextPath }/resources/css/mypage.css" rel="stylesheet" />

<!-- 마이 페이지 화면 영역 -->
<section class="myInfoContainer emptySpace cen">
    <aside class="myPageLnbContents">
        <nav class="myPageLnbCont">
            <ul>
                <li><a href="/mypage/myinfo.do">마이페이지</a></li>
                <li><a href="/mypage/boardinfo.do">게시글관리</a></li>
                <li><a href="/mypage/paymentinfo.do">결제관리</a></li>
            </ul>
        </nav>
    </aside>
    <article class="mypageContainer">
        <div class="myPageTabbtnGroup">
            <div class="tabbtn tactive">
				내 정보
            </div>
            <div class="tabbtn">
				좋아요내역
            </div>
            <div class="tabbtn">
				알림내역
            </div>
            <c:if test="${sessionInfo.memCategory ne '03' }">
	            <div class="tabbtn">
					회원탈퇴
	            </div>
            </c:if>
        </div>
        <div class="myPageTabcontBox">
            <div class="tabcont">
               <!-- 내 정보 -->
                <div class="myInfoContents">
                    <div class="myInfoContLefts">
                        <div class="myInfoImgBox">
                            <img src="${sessionInfo.memProfileimg }" alt="프로필 이미지" />
                        </div>
                        <label>
                            <span>아이디</span>
                            <input class="form-control memId" type="text" readonly value="${sessionInfo.memId }" />
                        </label>
                        <label>
                            <span>이름</span>
                            <input class="form-control memName" type="text" readonly value="${sessionInfo.memName }" />
                        </label>
                        <label>
                            <span>성별</span>
                            <c:if test="${sessionInfo.memGender eq 'M' }">
	                            <input class="form-control memGender" type="text" readonly value="남자" />
                            </c:if>
                            <c:if test="${sessionInfo.memGender eq 'F' }">
	                            <input class="form-control memGender" type="text" readonly value="여자" />
                            </c:if>
                        </label>
                        <label>
                            <span>생년월일</span>
                            <fmt:parseDate var="parseData" value="${sessionInfo.memAgedate }" pattern="yyyy-MM-dd" />
                            <input class="form-control memAgedate" type="text" readonly value="<fmt:formatDate value="${parseData }" pattern="yyyy년 MM월 dd일"/>" />
                        </label>
                        <label>
                            <span>이메일</span>
                            <input class="form-control memEmail" type="text" readonly value="${sessionInfo.memEmail }" />
                        </label>
                        <label>
                            <span>핸드폰번호</span>
                            <input class="form-control memPhone" type="text" readonly value="${sessionInfo.memPhone }" />
                        </label>
                        <label>
                            <span>우편번호</span>
                            <input class="form-control memPostcode" type="text" readonly value="${sessionInfo.memPostcode }" />
                        </label>
                        <label>
                            <span>기본주소</span>
                            <input class="form-control memAddress1" type="text" readonly value="${sessionInfo.memAddress1 }" />
                        </label>
                        <label>
                            <span>상세주소</span>
                            <input class="form-control memAddress2" type="text" readonly value="${sessionInfo.memAddress2 }" />
                        </label>
                    </div>
                    <div class="myInfoContRights">
                        <div class="updBlockLayer">
                            <button id="updBlockBtn" type="button" class="btn btn-warning">회원정보수정 활성화</button>
                        </div>
                        <form id="myinfoupdForm" name="myinfoupdForm" action="/mypage/myinfoupd.do" method="post" enctype="multipart/form-data">
                            <div style="position: relative;">
                                <div class="myInfoImgBox">
                                    <img id="profileImg" src="${contextPath }/resources/images/default_profile.png" alt="프로필 이미지" />
                                </div>
                                <div class="profileIcon">
                                    <i class="fas fa-camera"></i>
                                </div>
                            </div>
                            <label style="display: none;">
                                <span>프로필 사진</span>
                                <input class="form-control" type="file" id="imgFile" name="imgFile" />
                            </label>
                            <label>
                                <span>아이디</span>
                                <input class="form-control" type="text" id="memId" name="memId" value="${sessionInfo.memId }" readonly />
                            </label>
                            <label>
                                <span>비밀번호</span>
                                <input class="form-control" type="password" id="memPw" name="memPw" value="" autocomplete="off" />
                            </label>
                            <label>
                                <span>이름</span>
                                <input class="form-control" type="text" id="memName" name="memName" value="${sessionInfo.memName }" autocomplete="off" />
                            </label>
                            <label>
                                <span class="nonBlock">성별</span>
                                <input type="radio" id="memGender1" name="memGender" value="M" <c:if test="${sessionInfo.memGender eq 'M' }">checked</c:if> />
                                <label for="memGender1">남성</label>
                                <input type="radio" id="memGender2" name="memGender" value="F" <c:if test="${sessionInfo.memGender eq 'F' }">checked</c:if> />
                                <label for="memGender2">여성</label>
                            </label>
                            <label>
                                <span>생년월일</span>
                                <input class="form-control" type="date" id="memAgedate" name="memAgedate" value="${sessionInfo.memAgedate }" autocomplete="off" />
                            </label>
                            <label>
                                <span>
									이메일
                                    <span class="emailChkMsg">
                                        <span class="badge bg-success">이메일 사용가능</span>
                                    </span>
                                </span>
                                <input class="form-control" id="memEmail" name="memEmail" type="text" value="${sessionInfo.memEmail }" autocomplete="off" />
                            </label>
                            <label>
                                <span>핸드폰번호</span>
                                <input class="form-control" id="memPhone" name="memPhone" type="text" value="${sessionInfo.memPhone }" autocomplete="off" />
                            </label>
                            <label>
                                <span>
									우편번호
                                    <span class="badge bg-secondary postcodeBtn" style="cursor: pointer;" onclick="DaumPostcode()">우편번호 찾기</span>
                                </span>
                                <input class="form-control" type="text" id="memPostcode" name="memPostcode" autocomplete="off" value="${sessionInfo.memPostcode }" />
                            </label>
                            <label>
                                <span>기본주소</span>
                                <input class="form-control" type="text" id="memAddress1" name="memAddress1" autocomplete="off" value="${sessionInfo.memAddress1 }" />
                            </label>
                            <label>
                                <span>상세주소</span>
                                <input class="form-control" type="text" id="memAddress2" name="memAddress2" autocomplete="off" value="${sessionInfo.memAddress2 }" />
                            </label>
                            <div style="text-align: right;">
                                <button type="button" class="btn btn-primary myInfoUpdBtn">회원정보수정</button>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
            <div class="tabcont">
                <!-- 좋아요내역 -->
                <table class="table table-striped table-hover likeTbl">
                	<thead>
                		<tr>
                			<th>플랜 제목</th>
                			<th>좋아요 날짜</th>
                			<th>바로가기</th>
                			<th>취소</th>
                		</tr>
                	</thead>
                	<tbody>
                		<c:choose>
                			<c:when test="${not empty likeList }">
                				<c:forEach items="${likeList }" var="likeItem">
	                				<tr>
			                			<td style="text-align:center;">
			                				${likeItem.plTitle }
			                			</td>
			                			<td style="text-align:center;">
			                				${likeItem.plLikeDate }
			                			</td>
			                			<td>
	                						<a class="btn btn-primary btn-sm" href="/myplan/planDetail.do?plNo=${likeItem.plNo }">바로 가기</a>
			                			</td>
			                			<td>
			                				<form class="plLikeCancelForm" action="/mypage/likeDelete.do" method="post">
			                					<input class="plLikeNo" name="plLikeNo" type="hidden" value="${likeItem.plLikeNo }" />
			                				</form>
			                				<button class="btn btn-danger btn-sm plRemoveBtn" type="button">취소</button>
			                			</td>
			                		</tr>
                				</c:forEach>
                			</c:when>
                			<c:otherwise>
                				<tr>
                					<td colspan="4">좋아요 내역이 존재하지 않습니다.</td>
                				</tr>
                			</c:otherwise>
                		</c:choose>
                		
                	</tbody>
                </table>
            </div>
            <div class="tabcont container">
                <!-- 알림내역 -->
                <style>
                	.rtAlertTbl th {
                		text-align: center;
                	}
                	.rtAlertTbl th:first-of-type {
                		width: 190px;
                	}
                	.rtAlertTbl th:nth-of-type(3) {
                		width: 100px;
                	}
                	.rtAlertTbl th:last-of-type {
                		width: 90px;
                	}
                	.rtAlertTbl td:nth-of-type(3),
                	.rtAlertTbl td:last-of-type {
                		text-align: center;
                	}
                	.rtAlertTbl td:first-of-type {
                		overflow: auto;
                	}
                	.rtAlertTbl td:first-of-type>div,
                	.rtAlertTbl td:first-of-type>span {
                		float: left;
                	}
               		.rtAlertProfileImgBox {
               			position: relative;
               			width: 50px;
               			height: 50px;
               			border-radius: 50%;
               			overflow: hidden;
               		}
               		.rtAlertProfileImgBox img {
               			position: absolute;
               			top: 50%;
               			left: 50%;
               			transform: translate(-50%, -50%);
               		}
                </style>
                <table class="table table-striped table-hover rtAlertTbl">
                	<thead>
                		<tr>
                			<th>이름(아이디)</th>
                			<th>알림 내용</th>
                			<th>바로가기</th>
                			<th>내역 삭제</th>
                		</tr>
                	</thead>
                	<tbody>
                		<c:choose>
                			<c:when test="${not empty rtAlertList }">
                				<c:forEach items="${rtAlertList }" var="rtAlert">
	                				<tr>
			                			<td>
			                				<div class="rtAlertProfileImgBox">
			                					<img src="${rtAlert.realsenPfimg }" alt="프로필 이미지" />
			                				</div>
			                				<span>${rtAlert.realsenName }(${rtAlert.realsenId })</span>
			                			</td>
			                			<td>
			                				${rtAlert.realsenContent }
			                			</td>
			                			<td>
			                				<c:choose>
			                					<c:when test="${not empty rtAlert.realsenUrl }">
			                						<a class="btn btn-primary btn-sm" href="${rtAlert.realsenUrl }">바로 가기</a>
			                					</c:when>
			                					<c:otherwise>
			                						<a class="btn btn-secondary btn-sm" href="javascript:void(0);">바로 가기 없음</a>
			                					</c:otherwise>
			                				</c:choose>
			                			</td>
			                			<td>
			                				<form class="rtAlertOneDeleteForm" action="/mypage/rtAlertOneDelete.do" method="post">
			                					<input class="realrecNo" name="realrecNo" type="hidden" value="${rtAlert.realrecNo }" />
			                				</form>
			                				<button class="btn btn-danger btn-sm reAlertRemoveBtn" type="button">삭제</button>
			                			</td>
			                		</tr>
                				</c:forEach>
                			</c:when>
                			<c:otherwise>
                				<tr>
                					<td colspan="4">실시간 알림 내역이 존재하지 않습니다.</td>
                				</tr>
                			</c:otherwise>
                		</c:choose>
                		
                	</tbody>
                </table>
            </div>
            <c:if test="${sessionInfo.memCategory ne '03' }">
	            <div class="tabcont">
	                <!-- 회원탈퇴 -->
					<div class="memResign">
	                    <div>
	                        <div>
	                            <h1>회원탈퇴</h1>
	                        </div>
	                        <div>
	                            <h2>회원을 탈퇴하시겠습니까?</h2>
	                            <p>
									회원탈퇴 시 개인정보 및 여기갈래에서 만들어진 모든 데이터는 삭제됩니다.
	                                <br />
	                                (단, 아래 항목은 표기된 법률에 따라 특정 기간 동안 보관됩니다.)
	                            </p>
	                            <article>
	                                <ol>
	                                    <li>
											계약 또는 청약철회 등에 관한 기록 보존 이유 : 전자상거래 등에서의 소비자보호에 관한 법률 / 보존 기간 : 5년
	                                    </li>
	                                    <li>
											대금결제 및 재화 등의 공급에 관한 기록 보존 이유 : 전자상거래 등에서의 소비자보호에 관한 법률 / 보존 기간 : 5년
	                                    </li>
	                                    <li>
											전자금융 거래에 관한 기록 보존 이유 : 전자금융거래법 보존 기간 / 보존 기간 : 5년
	                                    </li>
	                                    <li>
											소비자의 불만 또는 분쟁처리에 관한 기록 보존 이유 : 전자상거래 등에서의 소비자보호에 관한 법률 보존 기간 / 보존 기간 : 3년
	                                    </li>
	                                    <li>
											신용정보의 수집/처리 및 이용 등에 관한 기록 보존 이유 : 신용정보의 이용 및 보호에 관한 법률 보존 기간 / 보존 기간 : 3년
	                                    </li>
	                                    <li>
											전자(세금)계산서 시스템 구축 운영하는 사업가가 지켜야 할 사항 고시(국세청 고시 제 2016-3호)(전자세금계산서 사용자에 한함) / 보존 기간 5년
	                                        <br />
	                                        (단, (세금)계산서 내 개인식별번호는 3년 경과 후 파기)
	                                    </li>
	                                </ol>
	                            </article>
	                        </div>
	                        <div>
	                            <h2>유의사항</h2>
	                            <article>
	                                <ul>
	                                    <li>
											회원탈퇴 처리 후에는 회원님의 개인정보를 복원할 수 없으며, 회원탈퇴 진행 시 해당 아이디는 영구적으로 삭제되어 재가입이 불가능합니다.
	                                    </li>
	                                    <li>
											탈퇴한 아이디가 존재할 경우, "탈퇴" 회원으로 조회됩니다.
	                                    </li>
	                                    <li>
											탈퇴한 아이디가 여기갈래 내에 존재하는 경우, 회사에 귀속된 데이터에 대해서는 보관됩니다.
	                                    </li>
	                                </ul>
	                            </article>
	                            <div>
	                                <input id="memRemove" name="memRemove" type="checkbox" />
	                                <label for="memRemove">해당 내용을 모두 확인했으며, 회원 탈퇴에 동의합니다.</label>
	                            </div>
	                        </div>
	                        <div>
	                            <button id="goToHome" type="button">홈으로</button>
	                            <button id="memExit" type="button">탈퇴하기</button>
	                        </div>
	                    </div>
	                </div>
	            </div>
            </c:if>
        </div>
    </article>
</section>

<!-- 마이 페이지 js -->
<script src="${contextPath }/resources/js/mypage.js"></script>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>

<script>
$(function(){
    var myInfoUpdBtn = $(".myInfoUpdBtn");
    var myinfoupdForm = $("#myinfoupdForm");
    
    var imgFile = $("#imgFile");
    var profileImg = $("#profileImg");

    var memPw = $("#memPw");
    var memName = $("#memName");
    var memAgedate = $("#memAgedate");
    var memEmail = $("#memEmail");
    var memPhone = $("#memPhone");
    var memPostcode = $("#memPostcode");
    var memAddress1 = $("#memAddress1");
    var memAddress2 = $("#memAddress2");
    
    // 공통 함수
    $.lnbHequalContHFn();
    $.myPageTabbtnFn();
    $.profileImgClickTriggerFn();
    $.myInfoActivationFn();
    
    // 이미지 미리보기 함수
    $.imgPreviewFn(imgFile, profileImg);
    
    // 이메일 중복체크 여부
    var emailChkFlag = true;
    var emailObj = {
       	el: memEmail,
       	msgEl: ".emailChkMsg",
       	msg: "이메일",
       	col: "memEmail",
       	url: "/login/emailCheck.do"
    };
    $.matchKeyupEvent(emailObj, function(result){
    	emailChkFlag = result;
    });
    
    // 회원 정보 수정 validation 체크
    myInfoUpdBtn.click(function(){
    	var pwFlag = $.falsyCheckFn(memPw, "비밀번호");
        if(!pwFlag) return;
        var nameFlag = $.falsyCheckFn(memName, "이름");
        if(!nameFlag) return;
        var ageDateFlag = $.falsyCheckFn(memAgedate, "생년월일");
        if(!ageDateFlag) return;
        var emailFlag = $.falsyCheckFn(memEmail, "이메일");
        if(!emailFlag) return;
        var phoneFlag = $.falsyCheckFn(memPhone, "핸드폰번호");
        if(!phoneFlag) return;
        var postcodeFlag = $.falsyCheckFn(memPostcode, "우편번호");
        if(!postcodeFlag) return;
        var add1Flag = $.falsyCheckFn(memAddress1, "주소");
        if(!add1Flag) return;
        var add2Flag = $.falsyCheckFn(memAddress2, "상세주소");
        if(!add2Flag) return; 
    	
    	if(emailChkFlag) {
	    	myinfoupdForm.submit();
    	}else {
    		//alert("이메일 중복 체크를 해주세요.");
    		Swal.fire({
    			title: "중복 체크",
    			text: "이메일 중복 체크를 해주세요.",
    			icon: "info"
    		});
    	}
    });
    
	// 회원 탈퇴 함수
    var memExit = $("#memExit");
    memExit.click(function(){
    	var memRemove = $("#memRemove");
    	var memExitChkVal = memRemove.prop("checked");
    	if(memExitChkVal) { // 회원 탈퇴 동의
    		location.href = "/mypage/memDelete.do?memId=${sessionInfo.memId }";
    	}else { // 회원 탈퇴 거부
    		//alert("회원 탈퇴에 동의해 주셔야 합니다.");
    		Swal.fire({
    			title: "회원 탈퇴 동의",
    			text: "회원 탈퇴에 동의해 주셔야 합니다.",
    			icon: "warning"
    		});
    	}
    });
    
    // 메인 페이지로 이동
    var goToHome = $("#goToHome");
    goToHome.click(function(){
    	location.href = "/index.do";
    });
    
    // 알림내역 클릭한 상태로 보여주기
    var rtAlertIdxClk = location.href;
    console.log("rtAlertIdxClk : ", rtAlertIdxClk);
    if(rtAlertIdxClk.indexOf('?') > 0){	// 쿼리스트링 존재함
    	var rtaIdxTxt = rtAlertIdxClk.split("=");
        var rtaIdx = rtaIdxTxt[1];
        console.log("rtaIdx : ", rtaIdx);
    	$(".myPageTabbtnGroup .tabbtn").eq(rtaIdx).trigger("click");
    }else{	// 쿼리스트링 존재하지 않음
    	console.log("쿼리스트링이 존재하지 않음");
    }
    
    // 실시간 알림 > 내역 삭제
    var reAlertRemoveBtn = $(".reAlertRemoveBtn");
    reAlertRemoveBtn.click(function(){
    	var thisIs = $(this);
    	var rtAlertOneDeleteForm = thisIs.prev();
    	console.log("rtAlertOneDeleteForm : ", rtAlertOneDeleteForm);
    	Swal.fire({
    	  icon: "question",
   		  title: "실시간 알림 내역 > 삭제",
   		  text : "해당 실시간 알림 내역을 삭제하시겠습니까?",
   		  showDenyButton: true,
   		  confirmButtonText: "삭제",
   		  denyButtonText: "취소"
   		}).then((result) => {
   		  if (result.isConfirmed) {
   			rtAlertOneDeleteForm.submit();
   		  } else if (result.isDenied) {
   			Swal.fire({
   			  icon: "error",
   			  title: "삭제 취소",
   			  text: "해당 실시간 알림 내역의 삭제가 취소되었습니다."
   			});
   		  }
   		});
    });

    var plRemoveBtn = $(".plRemoveBtn");
    plRemoveBtn.click(function(){
    	var thisIs = $(this);
    	var plRemoveForm = thisIs.prev();
    	// console.log("rtAlertOneDeleteForm : ", rtAlertOneDeleteForm);
    	Swal.fire({
    	  icon: "question",
   		  title: "좋아요 > 취소",
   		  text : "좋아요를 취소하시겠습니까?",
   		  showDenyButton: true,
   		  confirmButtonText: "삭제",
   		  denyButtonText: "취소"
   		}).then((result) => {
   		  if (result.isConfirmed) {
			plRemoveForm.submit();
   		  } else if (result.isDenied) {
   			Swal.fire({
   			  icon: "error",
   			  title: "좋아요 취소",
   			  text: "좋아요를 취소하지 않습니다."
   			});
   		  }
   		});
    });
    
    // 종횡비 함수
    var myInfoImgBox = $(".myInfoImgBox");
    var myInfoImg = $(".myInfoImgBox img");
    $.ratioBoxH(myInfoImgBox, myInfoImg);
    
    var rtAlertTbl = $(".rtAlertTbl td:first-of-type");
    rtAlertTbl.each(function(){
    	var thisIs = $(this);
    	var rtAlertProfileImgBox = thisIs.find(".rtAlertProfileImgBox");
    	var rtAlertProfileImg = thisIs.find(".rtAlertProfileImgBox img");
    	$.ratioBoxH(rtAlertProfileImgBox, rtAlertProfileImg);
    });
});
</script>

/* 마이페이지 스타일링 */

/* cen 재정의 */
.cen {
    width: 1200px;
}

/* 내 정보 스타일링 */
.myInfoContainer {
    position: relative;
    overflow: auto;
}

.myPageLnbContents {
    float: left;
    width: 200px;
    background-color: #333;
    padding: 20px;
}

.myPageLnbContents .myPageLnbCont a {
    display: block;
    padding: 20px 15px;
    border-bottom: 1px solid #444;
    color: white;
    transition: all 0.4s;
}

.myPageLnbContents .myPageLnbCont a:hover {
    background-color: white;
    color: #333;
}

.mypageContainer {
    float: left;
    width: calc(100% - 200px);
    background-color: #eee;
}

.myPageTabbtnGroup {
    overflow: auto;
    padding-bottom: 20px;
}

.mypageContainer {
    padding: 20px;
}

.tabbtn {
    background-color: white;
    float: left;
    padding: 10px 15px;
    border-radius: 4px 4px 0px 0px;
    margin-right: 10px;
    cursor: pointer;
}

.tabbtn:last-of-type {
    margin-right: 0px;
}

.tactive {
    background-color: #333;
    color: white;
}

.tabcont {
    display: none;
}

.tabcont:first-of-type {
    display: block;
}

.myInfoContents {
    position: relative;
    overflow: auto;
}

.myInfoContents>div {
    float: left;
    width: 50%;
    padding: 20px;
}

.myInfoImgBox {
    width: 300px;
    height: 300px;
    overflow: hidden;
    border-radius: 50%;
    position: relative;
    margin: auto;
}

.myInfoImgBox img {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

.myInfoContLefts label {
    width: 100%;
    padding: 20px 0px;
    padding-bottom: 0px;
    overflow: auto;
}

.myInfoContLefts span {
    display: block;
    float: left;
    width: 100px;
    margin-top: 7px;
}

.myInfoContLefts input {
    float: left;
    width: calc(100% - 100px);
}

.myInfoContRights {
    border-left: 1px solid #ddd;
    position: relative;
}

.myInfoContRights>form>label {
    width: 100%;
    padding: 20px 0px;
    padding-bottom: 0px;
}

.myInfoContRights .nonBlock {
    display: inline!important;
    margin-right: 10px;
}

.myInfoContRights>form>label>span:first-of-type {
    margin-bottom: 10px;
    display: block;
}

.myInfoUpdBtn {
    margin-top: 20px;
}

.profileIcon {
    width: 60px;
    height: 60px;
    background-color: #333;
    color: white;
    font-size: 1.6rem;
    border-radius: 50%;
    text-align: center;
    line-height: 60px;
    position: absolute;
    right: 80px;
    bottom: 0px;
    cursor: pointer;
    transition: all 0.4s;
}

.profileIcon:hover {
    background-color: white;
    color: #333;
}

.updBlockLayer {
    position: absolute;
    background-color: rgba(0,0,0,0.6);
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 10;
    border-radius: 4px;
}

#updBlockBtn {
    position: absolute;
    left: 20px;
    top: 20px;
}

/* 회원 탈퇴 스타일링 */
.memResign {
    position: relative;
    border: 1px dashed #0070BC;
    padding: 30px;
    background-color: white;
    border-radius: 4px;
}

.memResign h1,
.memResign h2,
.memResign p {
    margin-bottom: 0px;
}

.memResign ol,
.memResign ul {
    margin-bottom: 0px;
}

.memResign>div>div:first-of-type {
    padding-bottom: 10px;
}

.memResign>div>div:nth-of-type(2) {
    padding-bottom: 10px;
}

.memResign h2 {
    font-size: 1.5em;
    color: #6021D0;
    margin-bottom: 10px;
}

.memResign>div>div:nth-of-type(2) p {
    color: #989898;
    margin-bottom: 10px;
}

.memResign>div>div:nth-of-type(2) article {
    background-color: #EEE8F2;
    padding: 20px 10px;
    border-radius: 4px;
}

.memResign>div>div:nth-of-type(3) article {
    background-color: #F3F3F3;
    padding: 20px 10px;
    border-radius: 4px;
}

.memResign>div>div:nth-of-type(3)>div {
    margin-top: 10px;
}

.memResign>div>div:last-of-type {
    margin-top: 20px;
    text-align: center;
}

.memResign>div>div:last-of-type button {
    background-color: transparent;
    border: none;
    padding: 10px 15px;
    border-radius: 4px;
}

#goToHome {
    border: 1px solid #5B18FD;
    margin-right: 20px;
    transition: all 0.4s;
}

#goToHome:hover {
    transform: scale(1.1);
}

#memExit {
    border: 1px solid #5B18FD;
    background-color: #5B18FD;
    color: white;
    transition: all 0.4s;
}

#memExit:hover {
    transform: scale(1.1);
}

.memResign>div>div:nth-of-type(3) {
    padding-bottom: 10px;
}



.taleair td{
	vertical-align: middle;
	text-align: center;
	
}
.taleair th{
	vertical-align: middle;
	text-align: center;
	
}

.taleStay td{
	vertical-align: middle;
	text-align: center;
	
}
.taleStay th{
	vertical-align: middle;
	text-align: center;
	
}

/* 모달 스타일 */

.modal-content{
	width: 1000px;
	height: 1000px;
}

.modal-body .headerModal{
   border: 1px solid black;
   border-bottom : none;
   height: 100px;
   width: 900px;
   background: rgb(255, 248, 220);	
}
.modal-body .passengerModal{
   border: 1px solid black;
   border-bottom : none;
   height: 115px;	
   background: rgb(220, 235, 245);
}
.modal-body .passengerModal p{
   height: 10px;
   padding-top: 10px;	
}
.modal-body .title{
   border: 1px solid black;
   height: 45px;	
   background: rgb(220, 235, 245);
}
.modal-body .flight-header{
    border-left : 1px solid black;
   border-right : 1px solid black;
   border-bottom : 3px dotted white;
   height: 55px;	
   background: rgb(220, 235, 245);
   padding-top: 12px;
}
.modal-body .flight-content1{
   border-left : 1px solid black;
   border-right : 1px solid black;
   height: 45px;	
   background: rgb(220, 235, 245);
   padding-top: 20px;
}
.modal-body .flight-content2{
   border-left : 1px solid black;
   border-right : 1px solid black;
   height: 40px;	
   background: rgb(220, 235, 245);
   border-bottom : 3px dotted white;
}
.modal-body .flight-content3{
   border-left : 1px solid black;
   border-right : 1px solid black;
   height: 40px;	
   background: rgb(220, 235, 245);
}
.modal-body .flight-content4{
   border-left : 1px solid black;
   border-right : 1px solid black;
   height: 40px;	
   background: rgb(220, 235, 245);
}
.modal-body .flight-content5{
   border-left : 1px solid black;
   border-right : 1px solid black;
   height: 40px;	
   background: rgb(220, 235, 245);
}
.modal-body .flight-fare1{
   border-left : 1px solid black;
   border-right : 1px solid black;
   height: 50px;	
   padding-top : 15px;
   background: rgb(220, 235, 245);
   border-bottom : 3px dotted white;
}
.modal-body .flight-fare2{
   border-left : 1px solid black;
   border-right : 1px solid black;
   height: 60px;	
   padding-top : 7px;
   background: rgb(220, 235, 245);
   border-bottom : 3px dotted white;
}


/*************** question 답변 모달창  START ****************/
.questionAnswerModalContents {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: rgba(0,0,0,0.3);
    z-index: 70;
    display: none;
}

.questionAnswerModalBox {
    position: absolute;
    top: 55%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: white;
    padding: 60px;
    overflow: auto;
    border-radius: 10px;
}

.questionAnswerModalClose {
    width: 30px;
    height: 30px;
    position: absolute;
    top: 20px;
    right: 20px;
    cursor: pointer;
    background-color: rgba(0,0,0,0.4);
    border-radius: 4px;
}

.questionAnswerModalClose div {
    width: 25px;
    height: 1px;
    background-color: white;
    position: absolute;
    top: 50%;
    left: 50%;
}

.questionAnswerModalClose div:first-of-type {
    transform: translate(-50%, -50%) rotate(45deg);
}

.questionAnswerModalClose div:last-of-type {
    transform: translate(-50%, -50%) rotate(-45deg);
}

.questionAnswerModalBox article {
    padding: 24px;
}

.questionAnswerModalBox article > div {
    height: 300px;
    position: relative;
}

/*************** question 모달창  END ****************/

.likeTbl th {
	text-align: center;
}
.likeTbl th:first-of-type {
	width: 190px;
}
.likeTbl th:nth-of-type(3) {
	width: 100px;
}
.likeTbl th:last-of-type {
	width: 90px;
}
.likeTbl td:nth-of-type(3),
.likeTbl td:last-of-type {
	text-align: center;
}
.likeTbl td:first-of-type {
	overflow: auto;
}
/* .likeTbl td:first-of-type>div,
.likeTbl td:first-of-type>span {
	float: left;
}
 */

// 높이 조절 함수
$.lnbHequalContHFn = function(){
    var myPageLnbContents = $(".myPageLnbContents");
    var mypageContainer = $(".mypageContainer");
    
    mypageContainer.outerHeight("auto");
    myPageLnbContents.outerHeight("auto");
    
    var myPageLnbContentsH = myPageLnbContents.outerHeight();
    console.log("myPageLnbContentsH : " + myPageLnbContentsH);
    var mypageContainerH = mypageContainer.outerHeight();
    console.log("mypageContainerH : " + mypageContainerH);
    
    if(myPageLnbContentsH > mypageContainerH) {
        mypageContainer.outerHeight(myPageLnbContentsH);
    }else if(myPageLnbContentsH < mypageContainerH) {
        myPageLnbContents.outerHeight(mypageContainerH);
    }
};

// 탭 버튼 함수
$.myPageTabbtnFn = function(){
    var myPageTabbtn = $(".myPageTabbtnGroup .tabbtn");
    var myPageTabcontBox = $(".myPageTabcontBox .tabcont");
    myPageTabbtn.click(function(){
        var thisIs = $(this);
        myPageTabbtn.removeClass("tactive");
        thisIs.addClass("tactive");
        var idx = thisIs.index();
        myPageTabcontBox.hide();
        myPageTabcontBox.eq(idx).show();
        $.lnbHequalContHFn();
        
        //구매상품 리스트 요청
        if(thisIs.attr('id') === 'product'){
            payListAjax(''); 
        }
    });
};

 /*구매상품 리스트 요청*/
function payListAjax(pageNo){
      var number;
      if(pageNo == ''){   //페이지 번호 전달
        number = 1;
      }else{
        number = pageNo;
      }
        $.ajax({
          url : '/mypage/payHistoryList.do?page='+number,
          type : 'get',
          dataType : 'json',
          success : function(res){
            var payList = res.pageVO.dataList;
            var pagingHTML = res.pageVO.pagingHTML;
            var tbody = $('.taleair tbody');
            tbody.empty();   //모든 리스트 지우기
            
            var listHtml = '';
            var cnt  = 0;
            $.each(payList, function(i, pay){
             cnt++;
             listHtml += '<tr style="height: 80px;">';
             listHtml += '   <td>'+cnt+'</td>';
             listHtml += '   <td>';
             listHtml += '      <span>'+pay.airlineName+'</span><br>';
             listHtml += '      <img src="'+pay.airlineLogo+'" style="width: 100px; height: 80px;">';
             listHtml += '   </td>';
             listHtml += '   <td>동행<br>(그룹명 : '+pay.plTitle+')</td>';
             listHtml += '   <td>왕복<br>('+typeFormatter(pay.ticketType)+')</td>';
             listHtml += '   <td>'+pay.flightDepairport+'<br>';
             listHtml += '   ('+timeFormatter(pay.flightDeptime)+')</td>';
             listHtml += '   <td>'+pay.flightArrairport+'<br>('+timeFormatter(pay.flightArrtime)+')</td>';
             listHtml += '   <td>'+pay.airPersonnum+'명</td>';
             listHtml += '   <td>'+numberFormatter2(pay.ticketTotalprice)+'</td>';
             listHtml += '   <td>'+pay.airPayday+'</td>';
             listHtml += '   <td>'+pay.memId+'</td>';
             listHtml += '   <td>';
             listHtml += '     <button class="btn btn-primary ticketBtn" id="'+pay.airReserveno+'_'+pay.ticketType+'" data-bs-toggle="modal" data-bs-target="#myModal" style="margin-left: 10px; width: 80px;">항공권 확인</button>';
             listHtml += '   </td>';
             listHtml += '</tr>';
            });
            tbody.append(listHtml);
            var paging = $('#paging').find('div').eq(1);
            paging.empty();
            paging.append(pagingHTML);
          }
        })
}


/* 페이지 버튼 클릭 시 이벤트 */
$(document).on('click', '#pagingArea a', function(e){
   e.preventDefault();
   var pageNo = $(this).data('page');

   payListAjax(pageNo);
});



/* 항공권 확인 버튼 클릭 시 이벤트*/
$(document).on('click', '.ticketBtn', function(e){
   var arr = $(this).attr('id').split('_');
   var reNo = arr[0].trim();
   var tType = arr[1].trim();
   
   $.ajax({
     url : '/mypage/ticketView.do?airReserveno='+reNo+'&ticketType='+tType,
     type : 'get',
     dataType : 'json',
     success : function(res){
        if(res.msg == 'FAILED'){
            Swal.fire({
                title: "실패",
                text: "조회된 항공권이 없습니다!",
                icon: "error"
            });
            return false;
        }else if(res.msg == 'SUCCESS'){
            var first = res.receiptList[0];
            var ticketHTML = '<div class="row passengerModal">';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '     <p>탑승객 성명</p>';
            ticketHTML += '     <p></p>';
            ticketHTML += '     <p>예약번호</p>';
            ticketHTML += '     <p>항공권 코드</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '     <p>Passenger</p>';
            ticketHTML += '     <p></p>';
            ticketHTML += '     <p>Booking Reference</p>';
            ticketHTML += '     <p>Ticket Number</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-7">';
            $.each(res.receiptList, function(i, value){
                if((i+1) % 2 == 0){
                    ticketHTML += '<span style="margin-top: 12px;">'+value.ticketFirstname+' '+value.ticketName+'</span>, <br>';  
                }
                if((i+1) % 2 != 0){
                    ticketHTML += '<span style="margin-top: 12px;">'+value.ticketFirstname+' '+value.ticketName+'</span>, ';  
                }
            });
            ticketHTML += '     <p>'+first.airReserveno+'</p>';
            ticketHTML += '     <p>'+first.ticketCode+'</p>';
            ticketHTML += '   </div>';
            ticketHTML += '</div>';
            ticketHTML += '<div class="row title">';
            ticketHTML += '   <div class="col-sm-12">';
            ticketHTML += '      <h6 style="padding-top: 12px; padding-left: 10px;">여정 (Itinerary)</h6>';
            ticketHTML += '   </div>';
            ticketHTML += '</div>';
            ticketHTML += '<div class="row flight-header">';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '       <p>편명 Flight</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-6">';
            ticketHTML += '       <p>'+first.flightCode+' Operated by '+first.airlineName+'('+first.airlineCode+')</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '       <p>경유 Via : -직항</p>';
            ticketHTML += '   </div>';
            ticketHTML += '</div>';
            ticketHTML += '<div class="row flight-content1">';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '     <p>출발 Departure</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '     <p>'+first.flightDepairport+' ('+first.flightDepportcode+')</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-4">';
            ticketHTML += '    <p>'+first.flightDeptime+' Local Time</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '     <p>Terminal No : T1</p>';
            ticketHTML += '   </div>';
            ticketHTML += '</div>';
            ticketHTML += '<div class="row flight-content2">';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '     <p>도착 Arrival</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '     <p>'+first.flightArrairport+' ('+first.flightArrportcode+')</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-4">';
            ticketHTML += '     <p>'+first.flightArrtime+' Local Time</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '     <p>Terminal No : C2</p>';
            ticketHTML += '   </div>';
            ticketHTML += '</div>';
            ticketHTML += '<div class="row flight-content3">';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '     <p>예약등급 Class</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-3">';
            var grade;
            if(first.ticketClass.toLowerCase() == 'economy'){
               grade = '일반석 등급';
            }else if(first.ticketClass.toLowerCase() == 'business'){
               grade = '비즈니스 등급';
            }else if(first.ticketClass.toLowerCase() == 'first'){
               grade = '일등석 등급';
            }
            ticketHTML += '     <p>'+first.ticketClass+'('+grade+')</p>';
            
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '     <p>항공권 유효기간</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '     <p>Not Valid Before - </p>';
            ticketHTML += '   </div>';
            ticketHTML += '</div>';
            ticketHTML += '<div class="row flight-content4">';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '     <p>예약상태 Status</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '     <p>OK(확 약)</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '     <p></p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '    <p>Not Valid After 94MAY11</p>';
            ticketHTML += '   </div>';
            ticketHTML += '</div>';
            ticketHTML += '<div class="row flight-content5">';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '     <p>수하물</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '     <p>Baggage</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '     <p>20K</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-3">';
            ticketHTML += '   </div>';
            ticketHTML += '</div>';
            ticketHTML += '<div class="row title">';
            ticketHTML += '   <div class="col-sm-12">';
            ticketHTML += '        <h6 style="padding-top: 12px; padding-left: 10px;">운임 (Fare Basis) - SLXP15</h6>';
            ticketHTML += '   </div>';
            ticketHTML += '</div>';
            ticketHTML += '<div class="row flight-fare1">';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '     <p>탑승객</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '     <p>항공운임</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '    <p>유류할증료</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '     <p>제세공과금</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '     <p>발권수수료</p>';
            ticketHTML += '   </div>';
            ticketHTML += '   <div class="col-sm-2">';
            ticketHTML += '     <p>총액</p>';
            ticketHTML += '   </div>';
            ticketHTML += '</div>';
            $.each(res.receiptList, function(i, receipt){
                ticketHTML += '<div class="row flight-fare2">';
                ticketHTML += '   <div class="col-sm-2">';
                ticketHTML += '    <p>'+receipt.ticketFirstname+' '+receipt.ticketName+'</p>';
                ticketHTML += '  </div>';
                ticketHTML += '   <div class="col-sm-2">';
                ticketHTML += '    <p>'+numberFormatter2(receipt.ticketAircharge)+'</p>';
                ticketHTML += '  </div>';
                ticketHTML += '  <div class="col-sm-2">';
                ticketHTML += '    <p>'+numberFormatter2(receipt.ticketFuelsurcharge)+'</p>';
                ticketHTML += '  </div>';
                ticketHTML += '  <div class="col-sm-2">';
                ticketHTML += '    <p>'+numberFormatter2(receipt.ticketTax)+'</p>';
                ticketHTML += '  </div>';
                ticketHTML += '  <div class="col-sm-2">';
                ticketHTML += '     <p>'+numberFormatter2(receipt.ticketCommission)+'</p>';
                ticketHTML += '  </div>';
                ticketHTML += '  <div class="col-sm-2">';
                ticketHTML += '     <p>'+numberFormatter2(receipt.ticketTotalprice)+'</p>';
                ticketHTML += '  </div>';
                ticketHTML += '</div>';
            });
        } 
        var modalbody = $('.modal-body').empty();
        modalbody.append(basicHTML);
        $('.headerModal').after(ticketHTML);
     }  //success끝
   }); //ajax끝
});


//시간형태를 변환하는 함수
function timeFormatter(date){
    var time = date.substr(8);
    var hourStr = time.substr(0, 2);
    var minute = time.substr(2);
    
    var hour = parseInt(hourStr, 10) % 12;
    var ampm = parseInt(hourStr, 10) >= 12 ? '오후' : '오전';
    
    return ampm+' '+hour+':'+minute;
}

//숫자의 형태를 변환하는 함수
function numberFormatter2(number){
    return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')+'원';
}



//가는편,오는편 구분하는 함수
function typeFormatter(type){
  var str;
  if(type == 'DAPARTURE'){
     str = '가는편';
  }
  if(type == 'RETURN'){
     str = '오는편';
  }
   return str;
}




// 이미지 업로드 트리거 함수
$.profileImgClickTriggerFn = function(){
    var profileIcon = $(".profileIcon");
    profileIcon.click(function(){
        $("#imgFile").trigger("click");
    });
};

// 회원정보수정 활성화 함수
$.myInfoActivationFn = function(){
    var updBlockBtn = $("#updBlockBtn");
    updBlockBtn.click(function(){
        $(".updBlockLayer").hide();
    });
};

// 이메일 검증 함수
$.matchKeyupEvent = function({el, msgEl, msg, col, url}, callback){
    el.keyup(function(){
        var valTxt = $(this).val();
        //console.log("valTxt : ",valTxt);
        if(!valTxt) {
        	$(msgEl).html("<span class='badge bg-danger'>"+msg+" 사용불가</span>");
        	callback(false);
        }else {
            var data = {
                [col] : valTxt
            };
            //console.log("data : ", data);
            $.ajax({
                type: "post",
                url: url,
                data: JSON.stringify(data),
                contentType: "application/json;charset=utf-8",
                success: function(res){
                    if(res === "NOTEXIST") {
                        $(msgEl).html("<span class='badge bg-success'>"+msg+" 사용가능</span>");
                        callback(true);
                    }else {
                        $(msgEl).html("<span class='badge bg-danger'>"+msg+" 사용불가</span>");
                        callback(false);
                    }
                }
            });
        }
    });
};

// daum 주소 API(주소 찾기)
function DaumPostcode() {
    new daum.Postcode({
        oncomplete: function(data) {
            // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

            // 각 주소의 노출 규칙에 따라 주소를 조합한다.
            // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
            var addr = ''; // 주소 변수
            var extraAddr = ''; // 참고항목 변수

            //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
            if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                addr = data.roadAddress;
            } else { // 사용자가 지번 주소를 선택했을 경우(J)
                addr = data.jibunAddress;
            }

            // 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
            if (data.userSelectedType === 'R') {
                // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                if (data.bname !== '' && /[동|로|가]$/g.test(data.bname)) {
                    extraAddr += data.bname;
                }
                // 건물명이 있고, 공동주택일 경우 추가한다.
                if (data.buildingName !== '' && data.apartment === 'Y') {
                    extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                }
            }

            // 우편번호와 주소 정보를 해당 필드에 넣는다.
            document.getElementById("memPostcode").value = data.zonecode;
            document.getElementById("memAddress1").value = addr;
            // 커서를 상세주소 필드로 이동한다.
            document.getElementById("memAddress2").focus();
        }
    }).open();
}

var basicHTML = '<div class="row headerModal"><div class="col-sm-1"><img src="/resources/images/logo.png" width="80px;" height="80px;" style="padding-top: 13px;"></div><div class="col-sm-2">&nbsp;&nbsp;<h4 style="padding-top: 10px; padding-left: 10px;">여기갈래</h4></div><div class="col-sm-5"><h4 style="padding-top: 30px;">e-Ticket Intinerary & Receipt</h4></div><div class="col-sm-4" style="padding-top: 35px;"></div></div>';


// 문의사항 답변등록 모달 창
$.questionModalFn = function() {

      // 모달창(답변등록) 닫기
      var questionAnswerModalClose = $(".questionAnswerModalClose");
      var questionAnswerModalContents = $(".questionAnswerModalContents");
      questionAnswerModalClose.click(function () {
        questionAnswerModalContents.hide();
        questionAnswerModalContents.css("opacity","0");
      });
  }

function modalOn(idx) {
var questionAnswerModalContents = $(".questionAnswerModalContents");
questionAnswerModalContents.show();
questionAnswerModalContents.animate({opacity:"1"},200);

$.ajax({
    type: "post",
    url: "/question/questionInfoPost.do",
    data: {
    idx:idx
    },
    success: function(data) {
    console.log("data 값 : ", data);
    let boTitle = data.boTitle;
    let boContent = data.boContent;
    
    $("#title").val(boTitle);
    $("#content").val(boContent.replaceAll('<br/>','\n'));
    
    if(data.answer == '' || data.answer == null) {
        $("#answer").val('');
        $("#questionAnswerBtn").attr("onclick","questionAnswerComplete("+idx+")");
        document.getElementById("answer").disabled = false;
        return;
    }
    else {
        $("#answer").val(data.answer.replaceAll('<br/>','\n'));
        document.getElementById("answer").disabled = true;
    }
    
    },
    error: function() {
    alert("전송 오류");
    }
});

}

package kr.or.ddit.users.mypage.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import kr.or.ddit.users.board.vo.QuestionVO;
import kr.or.ddit.users.login.vo.MemberVO;
import kr.or.ddit.users.mypage.service.MyPageService;
import kr.or.ddit.users.myplan.vo.PlannerLikeVO;
import kr.or.ddit.utils.ServiceResult;
import kr.or.ddit.vo.RealTimeSenderVO;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
@RequestMapping("/mypage")
public class MyPageController {

	@Inject
	private MyPageService mypageService;
	
	// 마이페이지 이동
	@CrossOrigin(origins = "http://localhost")
	@RequestMapping(value = "/myinfo.do", method = RequestMethod.GET)
	public String myinfo(
			HttpSession session,
			Model model
			) {
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		MemberVO memberVO = (MemberVO) session.getAttribute("sessionInfo");
		log.info("memberVO.getMemId() : {}", memberVO.getMemId());
		param.put("memId", memberVO.getMemId());
		
		/** 서비스 호출 */
		// 1. 좋아요 내역 리스트 가져오기
		List<PlannerLikeVO> plList = mypageService.getLikeList(memberVO.getMemId());
		
		// 2. 알림 내역 리스트 가져오기
		mypageService.getRtAlertList(param);
		
		/** 반환 자료 */
		List<RealTimeSenderVO> rtAlertList = (List<RealTimeSenderVO>) param.get("rtAlertList");
		
		/** 자료 검증 */
		log.info("rtAlertList : {}", rtAlertList);
		
		/** 자료 반환 */
		model.addAttribute("rtAlertList", rtAlertList);
		model.addAttribute("likeList", plList);
		
		return "mypage/myInfo";
	}
	
	// 회원정보수정 메서드
	@RequestMapping(value = "/myinfoupd.do", method = RequestMethod.POST)
	public String myinfoUpd(
			HttpSession session,
			HttpServletRequest req,
			MemberVO memberVO,
			Model model,
			RedirectAttributes ra
			) {
		
		String goPage = "";
		
		ServiceResult result = mypageService.myinfoUpd(req, memberVO);
		if(result.equals(ServiceResult.OK)) {
			MemberVO member = mypageService.updCheck(memberVO);
			if(member != null) {
				session.setAttribute("sessionInfo", member);
				int intervalInSeconds = 60 * 60; // 1시간을 초로 계산합니다
				session.setMaxInactiveInterval(intervalInSeconds);
				ra.addFlashAttribute("message", "회원 정보 수정이 완료되었습니다.");
				ra.addFlashAttribute("msgflag", "su");
				goPage = "redirect:/mypage/myinfo.do";
			}else {
				model.addAttribute("message", "서버에러, 다시 시도해 주세요.");
				model.addAttribute("msgflag", "in");
				model.addAttribute("member", memberVO);
				goPage = "login/signin";
			}
		}else {
			model.addAttribute("message", "회원 정보 수정에 실패했습니다.");
			model.addAttribute("msgflag", "fa");
			goPage = "mypage/myInfo";
		}
		
		return goPage;
		
	}
	
	// 회원 탈퇴 메서드
	@RequestMapping(value = "/memDelete.do", method = RequestMethod.GET)
	public String memDelete(
			String memId,
			HttpSession session,
			RedirectAttributes ra,
			Model model
			) {
		
		String goPage = "";
		
		ServiceResult result = mypageService.memDelete(memId);
		if(result.equals(ServiceResult.OK)) { // 회원 삭제 성공
			session.invalidate();
			ra.addFlashAttribute("message", "회원 탈퇴가 되었습니다. 안녕히 가세요.");
			ra.addFlashAttribute("msgflag", "su");
			goPage = "redirect:/login/signin.do";
		}else { // 회원 삭제 실패
			model.addAttribute("message", "서버 에러, 다시 시도해주세요!");
			model.addAttribute("msgflag", "in");
			goPage = "mypage/myInfo";
		}
		
		return goPage;
		
	}
	
	// 실시간 알림 내역 > 내역 삭제 메서드
	@PostMapping("/rtAlertOneDelete.do")
	public String rtAlertOneDelete(
			RealTimeSenderVO rtSenderVO,
			Model model,
			RedirectAttributes ra
			) {
		
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		log.info("rtAlertOneDelete > realrecNo : {}", rtSenderVO.getRealrecNo());
		param.put("realrecNo", rtSenderVO.getRealrecNo());
		
		/** 서비스 호출 */
		mypageService.rtAlertOneDelete(param);
		
		/** 반환 자료 */
	    ServiceResult result = (ServiceResult) param.get("result");
	    String message = (String) param.get("message");
	    String goPage = (String) param.get("goPage");
	    
	    /** 자료 검증 */
	    log.info("result : " + result);
	    log.info("message : " + message);
	    log.info("goPage : " + goPage);

	    if(result.equals(ServiceResult.OK)) { // 업데이트 성공
	        ra.addFlashAttribute("message", message);
	        ra.addFlashAttribute("msgflag", "su");
	    }else { // 업데이트 실패
	    	ra.addFlashAttribute("message", message);
	    	ra.addFlashAttribute("msgflag", "fa");
	    }

	    /** 자료 반환 */
	    return goPage;
		
	}
	
	// 실시간 알림 내역 > 내역 삭제 메서드
	@PostMapping("/likeDelete.do")
	public String likeDelete(
			PlannerLikeVO plLikeVO,
			Model model,
			RedirectAttributes ra
			) {
		
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
//		log.info("rtAlertOneDelete > realrecNo : {}", plLikeVO.getPlLikeNo());
		param.put("plLikeNo", plLikeVO.getPlLikeNo());
		
		/** 서비스 호출 */
		mypageService.plLikeDelete(param);
		
		/** 반환 자료 */
	    ServiceResult result = (ServiceResult) param.get("result");
	    String message = (String) param.get("message");
	    String goPage = (String) param.get("goPage");
	    
	    /** 자료 검증 */
	    log.info("result : " + result);
	    log.info("message : " + message);
	    log.info("goPage : " + goPage);

	    if(result.equals(ServiceResult.OK)) { // 업데이트 성공
	        ra.addFlashAttribute("message", message);
	        ra.addFlashAttribute("msgflag", "su");
	    }else { // 업데이트 실패
	    	ra.addFlashAttribute("message", message);
	    	ra.addFlashAttribute("msgflag", "fa");
	    }

	    /** 자료 반환 */
	    return goPage;
		
	}
	
	// 게시글 관리 이동
	@CrossOrigin(origins = "http://localhost")
	@RequestMapping(value = "/boardinfo.do", method = RequestMethod.GET)
	public String boardinfo(
			HttpSession session,
			Model model
			) {
		
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		MemberVO memberVO = (MemberVO) session.getAttribute("sessionInfo");
		log.info("memberVO.getMemId() : {}", memberVO.getMemId());
		// 로그인 정보 가져오기
		param.put("memId", memberVO.getMemId());
		
		/** 서비스 호출 */
		// 1. 나의 여행 후기 리스트 가져오기
		
		// 2. 나의 문의 리스트 가져오기
		mypageService.getQnaList(param);
		
		/** 반환 자료 */
		List<QuestionVO> qnaList = (List<QuestionVO>) param.get("qnaList");
		
		/** 자료 검증 */
		log.info("qnaList : {}", qnaList);
		
		/** 자료 반환 */
		model.addAttribute("qnaList", qnaList);
		
		return "mypage/boardInfo";
	}
	
	// 나의 문의 내역 > 내역 삭제 메서드
	@PostMapping("/qnaOneDelete.do")
	public String qnaOneDelete(
			QuestionVO questionVO,
			Model model,
			RedirectAttributes ra
			) {
		
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		log.info("qnaOneDelete > boNo : {}", questionVO.getBoNo());
		param.put("boNo", questionVO.getBoNo());
		
		/** 서비스 호출 */
		mypageService.qnaOneDelete(param);
		
		/** 반환 자료 */
	    ServiceResult result = (ServiceResult) param.get("result");
	    String message = (String) param.get("message");
	    String goPage = (String) param.get("goPage");
	    
	    /** 자료 검증 */
	    log.info("result : " + result);
	    log.info("message : " + message);
	    log.info("goPage : " + goPage);

	    if(result.equals(ServiceResult.OK)) { // 업데이트 성공
	        ra.addFlashAttribute("message", message);
	        ra.addFlashAttribute("msgflag", "su");
	    }else { // 업데이트 실패
	    	ra.addFlashAttribute("message", message);
	    	ra.addFlashAttribute("msgflag", "fa");
	    }

	    /** 자료 반환 */
	    return goPage;
		
	}
	
}

package kr.or.ddit.users.mypage.service;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import kr.or.ddit.users.login.vo.MemberVO;
import kr.or.ddit.users.myplan.vo.PlannerLikeVO;
import kr.or.ddit.utils.ServiceResult;

public interface MyPageService {

	public ServiceResult myinfoUpd(HttpServletRequest req, MemberVO memberVO);
	public MemberVO updCheck(MemberVO memberVO);
	public ServiceResult memDelete(String memId);
	public void getRtAlertList(Map<String, Object> param);
	public void rtAlertOneDelete(Map<String, Object> param);
	public void getQnaList(Map<String, Object> param);
	public void qnaOneDelete(Map<String, Object> param);
	public List<PlannerLikeVO> getLikeList(String string);
	public void plLikeDelete(Map<String, Object> param);

}

package kr.or.ddit.users.mypage.service.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import kr.or.ddit.mapper.MyPageMapper;
import kr.or.ddit.users.board.vo.QuestionVO;
import kr.or.ddit.users.login.vo.MemberVO;
import kr.or.ddit.users.mypage.service.MyPageService;
import kr.or.ddit.users.myplan.vo.PlannerLikeVO;
import kr.or.ddit.utils.ServiceResult;
import kr.or.ddit.vo.RealTimeSenderVO;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class MyPageServiceImpl implements MyPageService {

	@Inject
	private MyPageMapper mypageMapper;
	
	@Override
	public ServiceResult myinfoUpd(HttpServletRequest req, MemberVO memberVO) {
		ServiceResult result = null;
		
		// 회원 정보 수정 시, 프로필 이미지로 파일 업로드 할 서버 경로 지정
		String uploadPath = req.getServletContext().getRealPath("/resources/profile");
		File file = new File(uploadPath);
		if (!file.exists()) {
			file.mkdirs();
		}
		
		String profileImg = ""; // 회원정보에 추가될 프로필 이미지 경로
		try {
			
			// 넘겨받은 회원정보에서 파일 데이터 가져오기
			MultipartFile profileImgFile = memberVO.getImgFile();
			
			// 넘겨받은 파일 데이터가 존재할 때
			if(profileImgFile.getOriginalFilename() != null && !profileImgFile.getOriginalFilename().equals("")) {
				String fileName = UUID.randomUUID().toString(); // UUID 파일명 생성
				fileName += "_" + profileImgFile.getOriginalFilename(); // UUID_원본파일명으로 생성
				uploadPath += "/" + fileName; // /resources/profile/UUID_원본파일명
				
				profileImgFile.transferTo(new File(uploadPath)); // 해당 위치에 파일 복사
				profileImg = "/resources/profile/" + fileName; // 파일 복사가 일어난 파일의 위치로 접근하기 위한 URI 설정
			}
			
			memberVO.setMemProfileimg(profileImg);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		int status = mypageMapper.myinfoUpd(memberVO);
		if(status > 0) { // 수정 성공
			result = ServiceResult.OK;
		}else { // 수정 실패
			result = ServiceResult.FAILED;
		}
		
		return result;
	}

	@Override
	public MemberVO updCheck(MemberVO memberVO) {
		return mypageMapper.updCheck(memberVO);
	}

	@Override
	public ServiceResult memDelete(String memId) {
		ServiceResult result = null;
		
		int status = mypageMapper.memDelete(memId);
		if(status > 0) { // 회원 탈퇴 성공
			result = ServiceResult.OK;
		}else { // 회원 탈퇴 실패
			result = ServiceResult.FAILED;
		}
		
		return result;
	}

	@Override
	public void getRtAlertList(Map<String, Object> param) {
		/** 파라미터 조회 */
		String memId = (String) param.get("memId");
		log.info("memId : {}", memId);
		
		/** 파라미터 정의 */
		List<RealTimeSenderVO> rtAlertList = new ArrayList<RealTimeSenderVO>();
		
		/** 메인로직 처리 */
		// 알림 내역 리스트 가져오기
		rtAlertList = mypageMapper.getRtAlertList(memId);
		log.info("rtAlertList : {}", rtAlertList);
		
		/** 예외처리 - rtAlertList가 null인 경우 */
	    if (rtAlertList == null) {
	        System.out.println("Warning: rtAlertList is null");
	        return;
	    }

	    /** 반환자료 저장 */
	    param.put("rtAlertList", rtAlertList);
	}

	@Override
	public void rtAlertOneDelete(Map<String, Object> param) {
		/** 파라미터 조회 */
		int realrecNo = (int) param.get("realrecNo");
		
		/** 파라미터 정의 */
		int status = 0;
		ServiceResult result = null;
	    String message = "";
	    String goPage = "";
	    
	    /** 메인로직 처리 */
	    // 수신자 번호에 해당하는 실시간 알림 1건 삭제하기
	    status = mypageMapper.rtAlertOneDelete(realrecNo);
	    
	    if(status > 0) { // 삭제 완료
	    	result = ServiceResult.OK;
	    	message = "실시간 알림 내역 삭제에 성공했습니다.";
	    	goPage = "redirect:/mypage/myinfo.do?submenu=2";
	    }else { // 삭제 실패
	    	result = ServiceResult.FAILED;
	    	message = "실시간 알림 내역 삭제에 실패했습니다.";
	    	goPage = "redirect:/mypage/myinfo.do?submenu=2";
	    }
	    
	    /** 반환자료 저장 */
	    param.put("result", result);
	    param.put("message", message);
	    param.put("goPage", goPage);
	}

	@Override
	public void getQnaList(Map<String, Object> param) {
		/** 파라미터 조회 */
		String memId = (String) param.get("memId");
		log.info("memId : {}", memId);
		
		/** 파라미터 정의 */
		List<QuestionVO> qnaList = new ArrayList<QuestionVO>();
		
		/** 메인로직 처리 */
		// 문의 내역 리스트 가져오기
		qnaList = mypageMapper.getQnaList(memId);
		log.info("qnaList : {}", qnaList);
		
		/** 예외처리 - rtAlertList가 null인 경우 */
	    if (qnaList == null) {
	    	log.info("Warning: rtAlertList is null");
	        return;
	    }

	    /** 반환자료 저장 */
	    param.put("qnaList", qnaList);
		
	}

	@Override
	public void qnaOneDelete(Map<String, Object> param) {
		/** 파라미터 조회 */
		int boNo = (int) param.get("boNo");
		
		/** 파라미터 정의 */
		int status = 0;
		ServiceResult result = null;
	    String message = "";
	    String goPage = "";
	    
	    /** 메인로직 처리 */
	    // 수신자 번호에 해당하는 실시간 알림 1건 삭제하기
	    status = mypageMapper.qnaOneDelete(boNo);
	    
	    if(status > 0) { // 삭제 완료
	    	result = ServiceResult.OK;
	    	message = "실시간 알림 내역 삭제에 성공했습니다.";
	    	goPage = "redirect:/mypage/boardinfo.do?submenu=1";
	    }else { // 삭제 실패
	    	result = ServiceResult.FAILED;
	    	message = "실시간 알림 내역 삭제에 실패했습니다.";
	    	goPage = "redirect:/mypage/boardinfo.do?submenu=1";
	    }
	    
	    /** 반환자료 저장 */
	    param.put("result", result);
	    param.put("message", message);
	    param.put("goPage", goPage);
		
	}

	@Override
	public List<PlannerLikeVO> getLikeList(String memId) {
		return mypageMapper.getLikeList(memId);
	}

	@Override
	public void plLikeDelete(Map<String, Object> param) {
		/** 파라미터 조회 */
		int plLikeNo = (int) param.get("plLikeNo");
		
		/** 파라미터 정의 */
		int status = 0;
		ServiceResult result = null;
	    String message = "";
	    String goPage = "";
	    
	    /** 메인로직 처리 */
	    // 수신자 번호에 해당하는 실시간 알림 1건 삭제하기
	    status = mypageMapper.plLikeDelete(plLikeNo);
	    
	    if(status > 0) { // 삭제 완료
	    	result = ServiceResult.OK;
	    	message = "좋아요 취소에 성공했습니다.";
	    	goPage = "redirect:/mypage/myinfo.do?submenu=1";
	    }else { // 삭제 실패
	    	result = ServiceResult.FAILED;
	    	message = "좋아요 취소에 실패했습니다.";
	    	goPage = "redirect:/mypage/myinfo.do?submenu=1";
	    }
	    
	    /** 반환자료 저장 */
	    param.put("result", result);
	    param.put("message", message);
	    param.put("goPage", goPage);
		
	}
	
}

package kr.or.ddit.mapper;

import java.util.List;

import kr.or.ddit.users.board.vo.QuestionVO;
import kr.or.ddit.users.login.vo.MemberVO;
import kr.or.ddit.users.myplan.vo.PlannerLikeVO;
import kr.or.ddit.vo.RealTimeSenderVO;

public interface MyPageMapper {

	public int myinfoUpd(MemberVO memberVO);
	public MemberVO updCheck(MemberVO memberVO);
	public int memDelete(String memId);
	public List<RealTimeSenderVO> getRtAlertList(String memId);
	public int rtAlertOneDelete(int realrecNo);
	public List<QuestionVO> getQnaList(String memId);
	public int qnaOneDelete(int boNo);
	public List<PlannerLikeVO> getLikeList(String memId);
	public int plLikeDelete(int plLikeNo);

}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.or.ddit.mapper.MyPageMapper">

	<update id="myinfoUpd" parameterType="memberVO">
		UPDATE members
		SET
		    mem_pw = #{memPw},
		    mem_name = #{memName},
		    mem_gender = #{memGender},
		    mem_email = #{memEmail},
		    mem_phone = #{memPhone},
		    mem_postcode = #{memPostcode},
		    mem_address1 = #{memAddress1},
		    mem_address2 = #{memAddress2},
		    mem_agedate = #{memAgedate}
		    <if test="memProfileimg != null and !memProfileimg.equals('')">
            , mem_profileimg = #{memProfileimg}
        	</if>  
		WHERE
		    mem_id = #{memId}
	</update>
	
	<select id="updCheck" parameterType="memberVO" resultType="memberVO">
		SELECT
		    mem_no,
		    mem_id,
		    mem_pw,
		    mem_name,
		    mem_gender,
		    mem_email,
		    mem_phone,
		    mem_postcode,
		    mem_address1,
		    mem_address2,
		    mem_profileimg,
		    grade_code,
		    enabled,
		    mem_category,
		    mem_regdate,
		    mem_agedate
		FROM
		    members
		WHERE 1=1 
		  AND mem_id = #{memId}
		  AND mem_pw = #{memPw}
	</select>
	
	<update id="memDelete" parameterType="string">
		UPDATE members
		SET
		    enabled = 0
		WHERE
		    mem_id = #{memId}
	</update>
	
	<select id="getRtAlertList" parameterType="String" resultType="rtsenderVO">
		select a.*
		     , b.realrec_no
		     , b.realrec_id
		     , b.realsen_readyn
		  from realtimesender a
		     , realtimereceiver b
		 where 1=1
		   and a.realsen_no = b.realsen_no
		   and b.realsen_readyn = 'Y'
		   and b.realrec_id = #{memId}
		   order by a.realsen_no desc
	</select>
	
	<delete id="rtAlertOneDelete" parameterType="int">
		DELETE FROM realtimereceiver
		WHERE
		    realrec_no = #{realrecNo}
	</delete>
	
	<select id="getQnaList" parameterType="String" resultType="kr.or.ddit.users.board.vo.QuestionVO" >
		select
		bo_no 
		,	bo_title
		,	cont
		,	bo_date
		,	bo_content
		,	answer
		,	bo_answerDay
		from question
		where 1 = 1
		and bo_writer = #{memId}
		order by bo_no
	</select>
	
	<delete id="qnaOneDelete" parameterType="int">
		DELETE FROM question
		where bo_no = #{boNo}
	</delete>
	
	<select id="getLikeList" parameterType="String" resultType="plannerLikeVO">
		SELECT * FROM planer a, planer_like b WHERE a.pl_no = b.pl_no and b.mem_id = #{memId}
	</select>
	
	<delete id="plLikeDelete" parameterType="int">
		DELETE FROM planer_like
		WHERE
		    pl_like_no = #{plLikeNo}
	</delete>

</mapper>