관리 메뉴

거니의 velog

(15) 마이 트립 > 플래너 리스트 페이지 > 코드 리뷰 본문

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

(15) 마이 트립 > 플래너 리스트 페이지 > 코드 리뷰

Unlimited00 2024. 2. 16. 14:39

 

<%@ 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>
        
        <!-- 사용자 페이지 > 헤더 영역 -->
        <tiles:insertAttribute name="header" />
        
        <!-- 사용자 페이지 > 파트너 구현 영역 -->
        <tiles:insertAttribute name="userPartnerContainer" />
        
        <!-- 사용자 페이지 > 푸터 영역 -->
		<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" %>
<!-- 2024.01.26 이건정 커밋점 지정 -->
<!-- 마이 트립 css -->
<link href="${contextPath }/resources/css/myTrip.css" rel="stylesheet" />

<section class="myTripListContainer emptySpace">
    <article class="myTripHeadStyle">
        <div class="myTripImgBox">
            <img src="${contextPath }/resources/images/myTripBgImg.jpg" alt="마이 트립 배경 이미지" />
        </div>
        <div>
            <h3>마이 트립</h3>
            <span>MY TRIP</span>
        </div>
    </article>
    <article class="meetAreaListContents cen">
        <h3>플래너 리스트</h3>
        <div class="meetAreaSearchCont">
            <div>
                <input type="text" class="form-control" id="meetAreaSearchInput" name="meetAreaSearchInput" placeholder="제목(한글) 혹은 인원(숫자)을 입력하세요." />
                <button type="button" id="meetAreaSearchBtn">
                    <i class="fas fa-search"></i>
                </button>
            </div>
        </div>
        <div class="meetAreaListCont">
            <ul>
            	<!-- 반복 구간 -->
            	<c:choose>
            		<c:when test="${empty planerList }">
            			<li id="dontHoverSty" style="display: flex; justify-content: center;">
	            			<div style="background-color: #333; color: white; padding: 20px; width: 50%; margin: 0px auto; text-align: center;">
	            				${sessionInfo.memName }님이 등록/참여한 플래너가 없습니다.
	            			</div>
	            		</li>
	            		<script>
						  $(document).ready(function() {
							// 해당 ID를 가진 li 요소에서 mouseover 이벤트를 무시
						    $("#dontHoverSty").on("mouseover", function() {
						      $(this).css("pointer-events", "none");
						    });
						  });
						</script>	
            		</c:when>
            		<c:otherwise>
            			<c:forEach items="${planerList }" var="planer" varStatus="stat">
            				<c:if test="${planer.getSType() eq '동행참가' and planer.mategroupStatus ne '4단계'}">
	            				<li>
				                    <div class="meetAreaThumbnailCont">
				                    	<c:choose>
				                    		<c:when test="${empty planer.plThumburl }">
				                    			<img src="/resources/images/testimg/noimg.png" alt="플래너 리스트 썸네일 이미지" />
				                    		</c:when>
				                    		<c:otherwise>
				                    			<img src="${planer.plThumburl }" alt="플래너 리스트 썸네일 이미지" />
				                    		</c:otherwise>
				                    	</c:choose>
				                    </div>
				                    <div class="meetAreaLists">
				                        <a href="/partner/meetsquare.do?plNo=${planer.plNo }">
				                            <span class="meetTitle textDrop">
				                                <span class="badge bg-dark">제목</span>
				                                ${planer.plTitle }
				                            </span>
				                            <span class="meetTheme textDrop">
				                                <span class="badge bg-dark">테마</span>
				                                ${planer.plTheme }
				                            </span>
				                            <span class="meetMsize textDrop">
				                                <span class="badge bg-dark">현재멤버</span>
				                                <!-- ${planer.plMsize }명 -->
												${planer.mategroupCurrentnum}명
				                            </span>
				                            <fmt:parseDate var="impParseData" value="${planer.plRdate }" pattern="yyyy-MM-dd HH:mm:ss" />
				                            <span class="meetRdate textDrop">
				                                <span class="badge bg-dark">등록일자</span>
				                                <fmt:formatDate value="${impParseData }" pattern="yyyy-MM-dd"/>
				                            </span>
				                            <span class="meetName textDrop">
				                                <span class="badge bg-dark">그룹장</span>
				                                ${planer.memName }
				                            </span>
				                        </a>
				                    </div>
				                    <c:if test="${planer.memId eq sessionInfo.memId }">
					                    <div class="myTripListBtnGroup">
					                        <form action="/partner/chgStatusPlan.do" method="post" id="chgStatusPlan" name="chgStatusPlan">
					                        	<input type="hidden" value="${planer.memId }" id="memIdVal" name="memId" />
					                        	<input type="hidden" value="${planer.plNo }" id="plNoVal" name="plNo" />
					                        	<input type="hidden" value="${planer.plPrivate }" id="plPrivateVal" name="plPrivate" />
					                        </form>
					                        <c:choose>
					                        	<c:when test="${planer.mategroupStatus eq '1단계' }">
							                        <button type="button" class="btn btn-danger myTripDeleteBtn">일정 삭제</button>
							                        <c:if test="${planer.plPrivate eq 'N' }">
							                        	<button type="button" class="btn btn-primary myTripPrivatePublicBtn">공개</button>
							                        </c:if>
							                        <c:if test="${planer.plPrivate eq 'Y' }">
							                        	<button type="button" class="btn btn-warning myTripPrivatePublicBtn">비공개</button>
							                        </c:if>
					                        	</c:when>
					                        	<c:when test="${planer.mategroupStatus eq '4단계' }">
							                        <button type="button" class="btn btn-secondary myTripStatusPlanerBtn">여행종료</button>
					                        	</c:when>
					                        	<c:otherwise>
					                        		<button type="button" class="btn btn-secondary myTripStatusPlanerBtn">모집 마감</button>
					                        	</c:otherwise>
					                        </c:choose>
					                    </div>
				                    </c:if>
				                    <c:if test="${planer.memId ne sessionInfo.memId }">
				                    	<div class="myTripListBtnGroup">
					                        <form action="/partner/chgStatusJoiner.do" method="post" id="chgStatusJoiner" name="chgStatusJoiner">
					                        	<input type="hidden" value="${planer.mategroupId }" id="memIdVal" name="memId" />
					                        	<input type="hidden" value="${planer.plNo }" id="plNoVal" name="plNo" />
					                        </form>
					                        
					                        <c:if test="${planer.mategroupApply eq 'Y' }">
					                        	<button type="button" class="btn btn-success myTripConfirmBtn">승인</button>
					                        </c:if>
					                        <c:if test="${planer.mategroupApply eq 'N' }">
					                        	<button type="button" class="btn btn-danger myTripRejectBtn">거절</button>
					                        </c:if>
					                        <c:if test="${planer.mategroupApply eq 'W' }">
					                        	<button type="button" class="btn btn-warning myTripWaitrBtn">대기</button>
					                        </c:if>
					                        <c:if test="${planer.mategroupApply eq 'E' }">
					                        	<button type="button" class="btn btn-dark myTripEndBtn">모집 마감</button>
					                        </c:if>
					                        
					                        <c:if test="${planer.mategroupApply ne 'C' }">
						                        <button type="button" class="btn btn-info myTripCancelBtn">일정 취소</button>
					                        </c:if>
					                        <c:if test="${planer.mategroupApply eq 'C' }">
					                        	<button type="button" class="btn btn-secondary myTripStatusJoinerBtn">취소</button>
					                        </c:if>
					                        
					                    </div>
				                    </c:if>
				                </li>
			                </c:if>
            			</c:forEach>
            		</c:otherwise>
            	</c:choose>
            </ul>
        </div>
    </article>
</section>

<!-- 마이 트립 js -->
<script src="${contextPath }/resources/js/myTrip.js"></script>
<script>
    $(function(){
    	/* 공통 함수 */
    	var memId = '${sessionInfo.memId}';
    	$.ajaxPlannerListSearchFn(memId);
    	
    	var rtAlertPPChgObj = {
    		realsenId: '${sessionInfo.memId}',
    		realsenName: '${sessionInfo.memName}',
    		realsenPfimg: '${sessionInfo.memProfileimg}'
    	};
    	console.log("rtAlertPPChgObj : ", rtAlertPPChgObj);
    	$.myTripPrivatePublicChgFn(rtAlertPPChgObj);
    	
    	$.myTripDeleteFn();
    	$.excludeNonUserFn(memId);
    	$.myTripCancelFn();
    	
    	/* 종횡비 함수 */
        var myTripImgBox = $(".myTripImgBox");
        var myTripImg = $(".myTripImgBox img");
        $.ratioBoxH(myTripImgBox, myTripImg);
        $.eachPlannerInfoImgResizeFn();
    });
</script>

/* 마이 트립 스타일링 */
.myTripListContainer {
    position: relative;
}

.myTripHeadStyle {
    position: relative;
    height: 310px;
}

.myTripImgBox {
    position: relative;
    overflow: hidden;
    height: inherit;
}

.myTripImgBox img {
    position: absolute;
    left: 50%;
    top: 90%;
    transform: translate(-50%, -50%);
    width: 100%;
}

.myTripHeadStyle div:last-of-type {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	padding: 20px 50px;
	border-radius: 4px;
	background-color: rgba(255, 255, 255, 0.6);
	text-align: center;
}

.myTripHeadStyle div:last-of-type h3 {
	font-weight: 700;
	font-size: 2.3rem;
}

.myTripHeadStyle div:last-of-type span {
	font-size: 1.3rem;
}

.meetAreaListContents {
    position: relative;
    padding: 50px 0px;
}

.meetAreaListContents h3 {
    padding: 40px 0px 20px;
    text-align: center;
    font-size: 1.5rem;
    font-weight: 700;
    margin-bottom: 0px;
}

.meetAreaSearchCont {
    padding: 30px 0px;
}

.meetAreaSearchCont>div {
    overflow: auto;
    position: relative;
    width: 600px;
    margin: 0px auto;
}

.meetAreaSearchCont input {
    width: 100%;
}

.meetAreaSearchCont button {
    display: block;
    width: 20px;
    height: 100%;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    right: 10px;
    border: none;
    background-color: transparent;
    color: #dee2e6;
    transition: all 0.4s;
}

.meetAreaSearchCont button:hover {
    color: #333;
}

.meetAreaListCont {
    position: relative;
}

.meetAreaListCont ul {
    list-style: none;
    padding-left: 0px;
    margin-bottom: 0px;
}

.meetAreaListCont li {
    overflow: auto;
    padding: 10px 10px;
    transition: all 0.4s;
    border-radius: 4px;
}

.meetAreaListCont li:hover {
    background-color: #333;
}

.meetAreaListCont li:hover a {
    color: white;
}

.meetAreaListCont li:hover .meetAreaLists>a>span>span {
    background-color: white!important;
    color: #333!important;
}

.meetAreaListCont div {
    float: left;
}

.meetAreaThumbnailCont {
    width: 200px;
    height: 150px;
    overflow: hidden;
    position: relative;
    border-radius: 4px;
}

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

.meetAreaLists {
    width: calc(100% - 200px);
    height: 150px;
    padding: 0px 20px;
}

.meetAreaLists a {
    color: #333;
}

.meetAreaLists>a>span {
    display: block;
}

.meetAreaLists>a>span>span {
    margin-right: 10px;
    width: 60px;
    text-align: left;
    margin-bottom: 7px;
    transition: all 0.4s;
}

.myTripListBtnGroup {
    width: 100%;
    padding-top: 10px;
    text-align: right;
}

.myTripListBtnGroup button {
    margin-left: 10px;
}

/* 만남의 광장 스타일링 */
.myTripChatRoomContainer {
    position: relative;
}

.myTripChatRoomContents {
    position: relative;
    overflow: auto;
    padding: 60px 0px;
}

.myTripChatRoomContents>div {
    float: left;
    width: 50%;
}

.chatRoomTabbtnBox {
    overflow: auto;
}

.chatRoomTabbtnBox .tabbtn {
    background-color: #eee;
    color: #333;
    float: left;
    padding: 10px 20px;
    border-radius: 4px 4px 0px 0px;
    margin-right: 10px;
    cursor: pointer;
}

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

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

.chatRoomTabcontBox {
    position: relative;
    height: 660px;
    overflow: auto;
}

.tabcont {
    display: none;
}

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

.tabcont ul {
    list-style: none;
    padding-left: 0px;
    margin-bottom: 0px;
}

.tabcont li {
    overflow: auto;
    position: relative;
    margin-bottom: 10px;
    padding: 10px 10px;
    border-bottom: 1px solid #eee;
    transition: all 0.4s;
}

.tabcont li:last-of-type {
    border-bottom: none;
}

.tabcont li:not(:first-of-type):hover {
    background-color: #333;
    color: white;
}

.tabcont li:first-of-type {
    margin-bottom: 0px;
    font-weight: 700;
    font-size: 1.05rem;
}

.tabcont span {
    display: block;
    float: left;
    height: 50px;
    line-height: 50px;
}

.chatProfileImgBox {
    position: relative;
    overflow: hidden;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    margin-right: 10px;
}

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

.currentMemList>li>span:first-of-type {
    width: calc(100% - 280px);
}

.currentMemList>li>span:nth-of-type(2) {
    width: 60px;
    text-align: center;
}

.currentMemList>li>span:nth-of-type(3) {
    width: 60px;
    text-align: center;
}

.currentMemList>li>span:nth-of-type(4) {
    width: 80px;
    text-align: center;
}

.currentMemList>li>span:last-of-type {
    width: 80px;
    text-align: center;
}

.tabcont .textDrop {
    position: relative;
}

.tabcont .textDrop .fa-crown {
    position: absolute;
    left: 40px;
    top: 0px;
    z-index: 10;
    color: gold;
    transform: rotate(30deg);
}

.chatRoomInfoBox {
    overflow: auto;
    padding-top: 20px;
    border-top: 1px solid #eee;
}

.chatRoomInfoBox label,
.chatRoomInfoBox input {
    display: block;
    float: left;
    margin-bottom: 20px;
}

.chatRoomInfoBox label:last-of-type,
.chatRoomInfoBox input:last-of-type {
    margin-bottom: 0px;
}

.chatRoomInfoBox label {
    width: 120px;
    height: 38px;
    line-height: 38px;
}

.chatRoomInfoBox input {
    width: calc(100% - 120px);
}

.tabcont .textDrop .fa-circle {
    color: red;
    font-size: 0.9rem;
    margin-left: 5px;
}

.waitMemList>li>span:first-of-type {
    width: calc(100% - 350px);
}

.waitMemList>li>span:nth-of-type(2) {
    width: 60px;
    text-align: center;
}

.waitMemList>li>span:nth-of-type(3) {
    width: 60px;
    text-align: center;
}

.waitMemList>li>span:nth-of-type(4) {
    width: 80px;
    text-align: center;
}

.waitMemList>li>span:last-of-type {
    width: 150px;
    text-align: center;
}

.waitMemList>li>span:last-of-type button {
    margin-right: 5px;
}

.waitMemList>li>span:last-of-type button:last-of-type {
    margin-right: 0px;
}

#meetName {
    transition: all 0.4s;
    cursor: pointer;
}

#meetName:hover {
    background-color: #333;
    color: white;
}

#groupPoint {
    transition: all 0.4s;
    cursor: pointer;
}

#groupPoint:hover {
    background-color: #333;
    color: white;
}

#meetStatus {
    transition: all 0.4s;
    cursor: pointer;
}

#meetStatus:hover {
    background-color: #333;
    color: white;
}

/* 여기어때 채팅방 스타일링 */
.yogiChatRoomContBox {
    background-color: #B6CCD9;
    padding: 20px;
    margin-left: 20px;
    border-radius: 4px;
}

.chatRoomName {
    text-align: center;
    padding: 0px 0px 15px;
    font-size: 1.1rem;
    font-weight: 700;
}

.chatRoomContents {
    background-color: #88a6b8;
    height: 600px;
    overflow: auto;
    border-radius: 4px;
    padding: 20px 0px;
}

.chatRoomBtnGroup {
    padding: 10px 0px;
}

.chatRoomBtnGroup button {
    border: none;
    margin-right: 5px;
}

.chatRoomInputArea {
    overflow: auto;
}

.chatRoomInputArea>textarea,
.chatRoomInputArea>div {
    float: left;
}

.chatRoomInputArea>textarea {
    width: calc(100% - 50px);
    height: 150px;
}

.chatRoomInputArea>div {
    width: 50px;
    height: 150px;
    position: relative;
}

.chatRoomInputArea button {
    display: block;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background-color: yellow;
    border: none;
    position: absolute;
    bottom: 0;
    right: 0;
    transition: all 0.4s;
}

.chatRoomInputArea button:hover {
    background-color: #333;
    color: yellow;
}

.chatRoomContents p {
    margin-bottom: 0px;
}

.outerTalker {
    position: relative;
    padding: 0px 20px;
}

.talkerImgBox {
    width: 50px;
    height: 50px;
    position: relative;
    overflow: hidden;
    border-radius: 50%;
}

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

.outerstartDialogContBox {
    overflow: auto;
}

.outerstartDialogContBox>div {
    float: left;
}

.outerstartDialogContBox>div:last-of-type {
    width: calc(100% - 60px);
    margin-left: 10px;
}

.outerName {
    color: #66869a;
    margin-bottom: 5px;
}

/* 날짜 표기(외부자) 시작 */

.outerStartDialog {
    overflow: auto;
}

.outerStartDialog p {
    max-width: 340px;
    background-color: white;
    padding: 5px 10px;
    border-radius: 4px;
    margin-bottom: 10px;
    float: left;
}

.outerStartDialog .chatDateInfo {
    width: 90px;
    font-size: 0.7rem;
    float: left;
    padding: 0px 10px;
    position: relative;
}

.outerStartDialog .chatDateInfo>div {
	position: absolute;
	bottom: 0px;
}

.outerLongtakeDialog>div {
    overflow: auto;
}

.outerLongtakeDialog>div>p {
    max-width: 340px;
    float: left;
}

.outerLongtakeDialog .chatDateInfo {
    width: 90px;
    font-size: 0.7rem;
    float: left;
    padding: 0px 10px;
    position: relative;
}

.outerLongtakeDialog .chatDateInfo>div {
	position: absolute;
	bottom: 0px;
}

/* 날짜 표기(외부자) 끝 */

.outerLongtakeDialog {
    padding-left: 60px;
}

.outerLongtakeDialog p {
    background-color: white;
    padding: 5px 10px;
    border-radius: 4px;
    margin-bottom: 10px;
    text-align: left;
    float: left;
}

.innerTalker {
    position: relative;
    padding: 0px 20px;
}

.innerstartDialogContBox {
    overflow: auto;
}

.innerstartDialogContBox>div {
    float: right;
}

.innerstartDialogContBox>div:last-of-type {
    width: calc(100% - 60px);
    margin-right: 10px;
    text-align: right;
}

.innerName {
    color: #66869a;
    margin-bottom: 5px;
}

/* 날짜 표기(내부자) 시작 */

.innerStartDialog  {
    overflow: auto;
}

.innerStartDialog p {
    max-width: 340px;
    background-color: white;
    padding: 5px 10px;
    border-radius: 4px;
    margin-bottom: 10px;
    float: right;
}

.innerStartDialog .chatDateInfo {
    width: 90px;
    font-size: 0.7rem;
    float: right;
    padding: 0px 10px;
    position: relative;
}

.innerStartDialog .chatDateInfo>div {
	position: absolute;
	bottom: 0px;
	right: 10px;
}

.innerLongtakeDialog>div {
    overflow: auto;
}

.innerLongtakeDialog>div>p {
    max-width: 340px;
    float: right;
}

.innerLongtakeDialog .chatDateInfo {
    width: 90px;
    font-size: 0.7rem;
    float: right;
    padding: 0px 10px;
    text-align: right;
    position: relative;
}

.innerLongtakeDialog .chatDateInfo>div {
	position: absolute;
	bottom: 0px;
	right: 10px;
}

/* 날짜 표기(내부자) 끝 */

.innerLongtakeDialog {
    padding-right: 60px;
}

.innerLongtakeDialog p {
    background-color: white;
    padding: 5px 10px;
    border-radius: 4px;
    margin-bottom: 10px;
    text-align: right;
    float: right;
}

.memberInLog,
.memberOutLog {
    text-align: center;
}

.memberInLog p,
.memberOutLog p {
    color: #ddd;
    background-color: #66869a;
    padding: 4px 20px;
    border-radius: 4px;
    margin-bottom: 10px;
}

.moveBackBtnBox {
	padding-top: 20px;
	text-align: right;
}

/* 구매계획 페이지 스타일링 */
.buyPlanBox {
	overflow: auto;
	padding: 60px 0px;
}

.groupPlanContents,
.buyPlanContents {
	float: left;
	width: 50%;
	border: 1px solid #eee;
	padding: 20px;
}

// 2024.01.26 이건정 커밋점 지정 

// ajax > 플래너 리스트 실시간 검색 기능
$.ajaxPlannerListSearchFn = function(memId){
	var meetAreaSearchInput = $("#meetAreaSearchInput");
	meetAreaSearchInput.keyup(function(){
	
		var thisIs = $(this);
		var thisVal = thisIs.val();
		console.log("thisVal : ", thisVal);
		
		var languageType = detectLanguage(thisVal);
		console.log("languageType : ", languageType);
		
		var planerVO = {};
		planerVO.memId = memId;
		
		if(languageType == "korean") { // 제목을 검색할 거얌
			planerVO.plTitle = thisVal;
			planerVO.plMsize = "";
		}else if(languageType == "number") { // 인원이얌
			planerVO.plTitle = "";
			planerVO.plMsize = thisVal;
		}else { // 검색어 값을 넘기면 안되요!
			planerVO.plTitle = "";
			planerVO.plMsize = "";
		}
		
		$.ajax({
			type: "get",
			url: "/partner/ajaxSearch.do",
			data: planerVO,
			dataType: "json",
			success: function(res){
				console.log("res : ", res);
				var searchHtml = "";
				if(res.length == 0){
					searchHtml = `
					<article style="text-align: center; width: 50%; margin: 0px auto; float: none; cursor: auto; background-color: #333; color: white; padding: 20px; border-radius: 4px;">
						검색된 플래너 정보가 없습니다.
					</article>
					`;
				} 
				for(var i=0; i<res.length; i++) {
					if(res[i].stype == "동행참가"){
						console.log("memId : ", memId);
						var dateRes = convertToYYYYMMDD(res[i].plRdate);

						searchHtml += `<li>
											<div class="meetAreaThumbnailCont">`;
						
						if(!res[i].plThumburl) {
							searchHtml += `<img src="/resources/images/testimg/noimg.png" alt="플래너 리스트 썸네일 이미지" />`;
						}else {
							searchHtml += `<img src="${res[i].plThumburl}" alt="플래너 리스트 썸네일 이미지" />`;
						}

						searchHtml += `		</div>
											<div class="meetAreaLists">
												<a href="/partner/meetsquare.do?plNo=${res[i].plNo }">
													<span class="meetTitle textDrop">
														<span class="badge bg-dark">제목</span>
														${res[i].plTitle}
													</span>
													<span class="meetTheme textDrop">
														<span class="badge bg-dark">테마</span>
														${res[i].plTheme}
													</span>
													<span class="meetMsize textDrop">
														<span class="badge bg-dark">인원</span>
														${res[i].plMsize}명
													</span>
													<span class="meetRdate textDrop">
														<span class="badge bg-dark">등록일자</span>
														${dateRes}
													</span>
													<span class="meetName textDrop">
														<span class="badge bg-dark">그룹장</span>
														${res[i].memName}
													</span>
												</a>
											</div>`;

						if(res[i].memId == memId) {
							searchHtml += `
								<div class="myTripListBtnGroup">
									<form action="/partner/chgStatusPlan.do" method="post" id="chgStatusPlan" name="chgStatusPlan">
										<input type="hidden" value="${res[i].memId }" id="memIdVal" name="memId" />
										<input type="hidden" value="${res[i].plNo }" id="plNoVal" name="plNo" />
										<input type="hidden" value="${res[i].plPrivate }" id="plPrivateVal" name="plPrivate" />
									</form>
									<button type="button" class="btn btn-danger myTripDeleteBtn">일정 삭제</button>`;

							if(res[i].plPrivate == 'N') {
								searchHtml += `<button type="button" class="btn btn-primary myTripPrivatePublicBtn">공개</button>`;
							}else if(res[i].plPrivate == 'Y') {
								searchHtml += `<button type="button" class="btn btn-warning myTripPrivatePublicBtn">비공개</button>`;
							}

							searchHtml += `</div>`;
						}

						if(res[i].memId != memId) {
							searchHtml += `
								<div class="myTripListBtnGroup">
									<form action="/partner/chgStatusJoiner.do" method="post" id="chgStatusJoiner" name="chgStatusJoiner">
										<input type="hidden" value="${res[i].mategroupId}" id="memIdVal" name="memId" />
										<input type="hidden" value="${res[i].plNo}" id="plNoVal" name="plNo" />
									</form>`;

							if(res[i].mategroupApply != 'C'){
								searchHtml += `<button type="button" class="btn btn-info myTripCancelBtn">일정 취소</button>`;
							}
							if(res[i].mategroupApply == 'Y') {
								searchHtml += `<button type="button" class="btn btn-success myTripStatusJoinerBtn">승인</button>`;
							}
							if(res[i].mategroupApply == 'N') {
								searchHtml += `<button type="button" class="btn btn-danger myTripStatusJoinerBtn">거절</button>`;
							}
							if(res[i].mategroupApply == 'W') {
								searchHtml += `<button type="button" class="btn btn-warning myTripStatusJoinerBtn">대기</button>`;
							}
							if(res[i].mategroupApply == 'C') {
								searchHtml += `<button type="button" class="btn btn-secondary myTripStatusJoinerBtn">취소</button>`;
							}

							searchHtml += `
								</div>
							`;
						}

						searchHtml += `</li>`;
					}
				}

				// 최종 결과 출력
				var plannerInfoContents = $(".meetAreaListCont>ul");
				plannerInfoContents.html(searchHtml);

				// 종횡비 맞추기 함수
				$.eachPlannerInfoImgResizeFn();
				
				// 공개/비공개 함수
				$.myTripPrivatePublicChgFn();
				
				// 삭제 처리 함수
				$.myTripDeleteFn();
				
				// 취소 처리 함수
				$.myTripCancelFn();

				// 대기 상태가 W, N, C, E인 녀석은 못들어오게 막아!
				$.excludeNonUserFn(memId);
			}
		});
		
	});
};

function detectLanguage(inputValue) {
    // 정규표현식을 사용하여 문자열이 한글인지 영어인지, 숫자인지 판별
    var koreanRegex = /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/;
    var englishRegex = /^[a-zA-Z]*$/;
    var numberRegex = /^[0-9]*$/;

    if (koreanRegex.test(inputValue)) {
        return "korean";
    } else if (englishRegex.test(inputValue)) {
        return "english";
    } else if (numberRegex.test(inputValue)) {
        return "number";
    } else {
        return "etc";
    }
}

function convertToYYYYMMDD(inputDateString) {
	// 입력된 문자열을 Date 객체로 변환
	var inputDate = new Date(inputDateString);
  
	// 날짜 부분만 추출
	var yyyy = inputDate.getFullYear();
	var mm = String(inputDate.getMonth() + 1).padStart(2, '0'); // 월은 0부터 시작하므로 1을 더하고 2자리로 만듭니다.
	var dd = String(inputDate.getDate()).padStart(2, '0'); // 일자를 2자리로 만듭니다.
  
	// yyyy-MM-dd 형식으로 조합
	var outputDateString = `${yyyy}-${mm}-${dd}`;
  
	return outputDateString;
}

// 플래너 정보 각각의 이미지 종횡비 변경 함수
$.eachPlannerInfoImgResizeFn = function(){
    $(".meetAreaListCont li").each(function(i, v){
        var thisIs = $(this);
        var infoThumbnailBox = thisIs.find(".meetAreaThumbnailCont");
        var infoThumbnailImg = thisIs.find(".meetAreaThumbnailCont img");
        $.ratioBoxH(infoThumbnailBox, infoThumbnailImg);
    });
};

// 만남의 광장 > 현재 멤버/신청 멤버 각각의 이미지 종횡비 변경 함수
$.eachStartingMemberImgResizeFn = function(){
	var currentMemList = $(".currentMemList");
	var waitMemList = $(".waitMemList");
	currentMemList.each(function(){
		var thisIs = $(this);
		var curChatProfileImgBox = thisIs.find(".chatProfileImgBox");
        var curChatProfileImgBoxImg = thisIs.find(".chatProfileImgBox img");
        $.ratioBoxH(curChatProfileImgBox, curChatProfileImgBoxImg);
	});
	waitMemList.each(function(){
		var thisIs = $(this);
		var waitChatProfileImgBox = thisIs.find(".chatProfileImgBox");
        var waitChatProfileImgBoxImg = thisIs.find(".chatProfileImgBox img");
        $.ratioBoxH(waitChatProfileImgBox, waitChatProfileImgBoxImg);
	});
};

// 만남의 광장 > 채팅 참여 멤버 각각의 이미지 종횡비 변경 함수
$.eachChatingMemberImgResizeFn = function(){
	var outerTalker = $(".outerTalker");
	var innerTalker = $(".innerTalker");
	outerTalker.each(function(){
		var thisIs = $(this);
		var outerTalkerImgBox = thisIs.find(".talkerImgBox");
		var outerTalkerImgBoxImg = thisIs.find(".talkerImgBox img");
		$.ratioBoxH(outerTalkerImgBox, outerTalkerImgBoxImg);
	});
	innerTalker.each(function(){
		var thisIs = $(this);
		var innerTalkerImgBox = thisIs.find(".talkerImgBox");
		var innerTalkerImgBoxImg = thisIs.find(".talkerImgBox img");
		$.ratioBoxH(innerTalkerImgBox, innerTalkerImgBoxImg);
	});
};

// 공개/비공개 처리 함수
$.myTripPrivatePublicChgFn = function({realsenId, realsenName, realsenPfimg}){
	var myTripPrivatePublicBtn = $(".myTripPrivatePublicBtn");
	myTripPrivatePublicBtn.click(function(){

		var thisIs = $(this);
		
		var btnTxtVal = thisIs.text();
		
		var aHref = thisIs.parent().prev().find("a").attr("href");
		console.log("aHref : ", aHref);
		aHref = aHref.split("=");
		var plNo = aHref[1];
		console.log("plNo : ", plNo);

		// var changeYN = confirm(`플래너를 ${btnTxtVal}하시겠습니까?`);
		// if(changeYN) {
		// 	thisIs.parent().find("#chgStatusPlan").submit();
		// }
		
		Swal.fire({
			title: "플래너 공개/비공개",
		    text: `플래너를 ${btnTxtVal}하시겠습니까?`,
			icon: "question",
		    showDenyButton: true,
		    confirmButtonText: "예",
		    denyButtonText: "아니오"
		}).then((result) => {
		    if (result.isConfirmed) {

				// 실시간 알림 기능 > 플래너 공개/비공개 변경 알림
				if(btnTxtVal == "공개"){

					var realrecIdArr; // 모든 유저를 대상으로 알림
					$.ajaxMembersIdListGetFn(function(result){
    		        	
						realrecIdArr = result;
						console.log("realrecIdArr : ", realrecIdArr);
						
						var realsenTitle = "플래너 " + btnTxtVal; // 실시간 알림 제목
						var realsenContent = realsenName+"("+realsenId+")님이 새로운 플래너를 "+btnTxtVal+" 하였습니다."; // 실시간 알림 내용
						var realsenType = "mygroup"; // 여행정보 타입 알림
						var realsenReadyn = "N"; // 안 읽음
						var realsenUrl = "/myplan/planDetail.do?plNo=" + plNo; // 여행 정보 페이지로 이동
						
						var dbSaveFlag = true; // db에 저장
    			        var userImgSrc = realsenPfimg; // 유저 프로파일 이미지 정보
    			        var realrecNo = "empty";
						
						var rtAlert = {
							"realrecIdArr": realrecIdArr,
							"realsenId": realsenId,
							"realsenName": realsenName,
							"realsenTitle": realsenTitle,
							"realsenContent": realsenContent,
							"realsenType": realsenType,
							"realsenReadyn": realsenReadyn,
							"realsenUrl": realsenUrl,
							"realsenPfimg": realsenPfimg
						};
						console.log("플래너 등록 알림 저장 > rtAlert : ", rtAlert);
						
						$.realTimeAlertWebSocketFn(rtAlert, dbSaveFlag, userImgSrc, realrecNo);
						
					});

				}

				// 플래너 공개/비공개 등록
		    	thisIs.parent().find("#chgStatusPlan").submit();

		    } else if (result.isDenied) {
		        Swal.fire({
					title: "플래너 공개/비공개",
					text: "플래너 공개/비공개를 취소합니다.",
					icon: "error"
				});
		    }
		});

	});
};

// 플래너 삭제 처리 함수
$.myTripDeleteFn = function(){
	var myTripDeleteBtn = $(".myTripDeleteBtn");
	myTripDeleteBtn.click(function(){

		var thisIs = $(this);

		// var delYN = confirm("일정을 삭제하시겠습니까?");
		// if(delYN) {
		// 	thisIs.parent().find("#chgStatusPlan").attr("action", "/partner/deletePlan.do");
		// 	thisIs.parent().find("#chgStatusPlan").submit();
		// }

		Swal.fire({
			title: "일정 삭제",
		    text: "일정을 삭제하시겠습니까?",
			icon: "question",
		    showDenyButton: true,
		    confirmButtonText: "예",
		    denyButtonText: "아니오"
		}).then((result) => {
		    if (result.isConfirmed) {
		    	thisIs.parent().find("#chgStatusPlan").attr("action", "/partner/deletePlan.do");
				thisIs.parent().find("#chgStatusPlan").submit();
		    } else if (result.isDenied) {
		        Swal.fire({
					title: "일정 삭제",
					text: "일정 삭제를 취소합니다.",
					icon: "error"
				});
		    }
		});

	});
};

// 탭 버튼 기능
$.myTripChatroomTabbtnFn = function(){
    var chatRoomTabbtnBox = $(".chatRoomTabbtnBox .tabbtn");
    var chatRoomTabcontBox = $(".chatRoomTabcontBox .tabcont");
    chatRoomTabbtnBox.click(function(){
        var thisIs = $(this);
        chatRoomTabbtnBox.removeClass("tactive");
        thisIs.addClass("tactive");
        var idx = thisIs.index();
        chatRoomTabcontBox.hide();
        chatRoomTabcontBox.eq(idx).show();
    });
};

// 모임이름 클릭 > 플래너 상세 페이지 이동
$.meetNameClickEvent = function(plNo){
    var meetName = $("#meetName");
    meetName.click(function(){
        // var thisIs = $(this);
        // var moveYN = confirm("해당 모임의 플래너 상세 페이지로 이동하시겠습니까?");
        // if(moveYN) {
		// 	alert("플래너 상세 페이지로 이동합니다.");
	    // }
        
		Swal.fire({
			title: "페이지 이동",
		    text: "해당 모임의 플래너 상세 페이지로 이동하시겠습니까?",
			icon: "question",
		    showDenyButton: true,
		    confirmButtonText: "예",
		    denyButtonText: "아니오"
		}).then((result) => {
		    if (result.isConfirmed) {
		    	Swal.fire({
					title: "페이지 이동",
					text: "플래너 상세 페이지로 이동합니다.",
					icon: "info"
				}).then((result) => {
				    // 모달이 닫힌 후에 실행될 코드
				    if (result.isConfirmed) {
				        // 확인 버튼이 클릭되었을 때
				        location.href = "/myplan/planDetail.do?plNo=" + plNo;
				    }
				});
		    } else if (result.isDenied) {
		        Swal.fire({
					title: "페이지 이동",
					text: "플래너 상세 페이지 이동을 취소합니다.",
					icon: "error"
				});
		    }
		});
		
    });
};

// 그룹 포인트 > 구매계획 페이지 이동
$.shoppingPlanFn = function(plNo){
    var groupPoint = $("#groupPoint");
    groupPoint.click(function(){
        // var thisIs = $(this);
        // var shoppingYN = confirm("해당 모임의 구매계획 페이지로 이동하시겠습니까?");
        // if(shoppingYN) {
        //    alert("구매계획 페이지로 이동합니다.");
        //    location.href = "/partner/buyPlan.do?plNo=" + plNo;
        // }
        
        Swal.fire({
			title: "페이지 이동",
		    text: "해당 모임의 구매계획 페이지로 이동하시겠습니까?",
			icon: "question",
		    showDenyButton: true,
		    confirmButtonText: "예",
		    denyButtonText: "아니오"
		}).then((result) => {
		    if (result.isConfirmed) {
		    	Swal.fire({
				    title: "페이지 이동",
				    text: "구매계획 페이지로 이동합니다.",
				    icon: "info"
				}).then((result) => {
				    // 모달이 닫힌 후에 실행될 코드
				    if (result.isConfirmed) {
				        // 확인 버튼이 클릭되었을 때
				        location.href = "/partner/buyPlan.do?plNo=" + plNo + "&stay=true";
				    }
				});
		    } else if (result.isDenied) {
		        Swal.fire({
					title: "페이지 이동",
					text: "구매계획 페이지 이동을 취소합니다.",
					icon: "error"
				});
		    }
		});
    });
};

// 모집상태 > 모집중 -> 마감 처리 기능
$.groupRecruitEndedFn = function(){
	var meetStatus = $("#meetStatus");
    meetStatus.click(function(){
		var thisIs = $(this);
		var endedStat = thisIs.val();
		console.log("endedStat : ", endedStat);
        // var changeYN = confirm("현재 모집을 마감하시겠습니까?");
        // if(changeYN) {
        //    alert("모집이 마감되었습니다.");
        // }
        
        Swal.fire({
			title: "페이지 이동",
		    text: "현재 모집을 마감하시겠습니까?",
			icon: "question",
		    showDenyButton: true,
		    confirmButtonText: "예",
		    denyButtonText: "아니오"
		}).then((result) => {
		    if (result.isConfirmed) {
		    	if(endedStat == "모집마감") {
		    		Swal.fire({
						title: "모집 마감",
						text: "해당 플랜은 이미 모집 마감되었습니다.",
						icon: "info"
					});
		    	}else if(endedStat == "결제완료"){
		    		Swal.fire({
						title: "결제 완료",
						text: "해당 플랜은 결제가 완료되었습니다. 환불이 불가능합니다.",
						icon: "info"
					});
		    	}else if(endedStat == "여행종료") {
					Swal.fire({
						title: "여행종료",
						text: "해당 플랜은 여행이 종료되었습니다.",
						icon: "info"
					});
				}else {
					var groupRecruitEnded = $("#groupRecruitEnded");
					groupRecruitEnded.submit();
		    	}
		    } else if (result.isDenied) {
		        Swal.fire({
					title: "모집 마감",
					text: "모집 마감을 취소합니다.",
					icon: "error"
				});
		    }
		});
    });
};

// 채팅방, 멤버 박스 높이 맞추기
$.memBoxEqualChatBoxH = function(){
    var chatRoomLeft = $(".chatRoomLeft");
    var chatRoomRight = $(".chatRoomRight");
    var chatRoomLeftH = chatRoomLeft.outerHeight();
    console.log("chatRoomLeftH : ", chatRoomLeftH);
    var chatRoomRightH = chatRoomRight.outerHeight();
    console.log("chatRoomRightH : ", chatRoomRightH);
    if(chatRoomLeftH < chatRoomRightH) {
        chatRoomLeft.outerHeight(chatRoomRightH);
    }else {
        chatRoomRight.outerHeight(chatRoomLeftH);
    }
};

// 나이 계산 함수
function calculateAge(birthdate) {
  var today = new Date();
  var birthdate = new Date(birthdate);
  var age = today.getFullYear() - birthdate.getFullYear();

  // 생일이 지났는지 체크
  if (today.getMonth() < birthdate.getMonth() || (today.getMonth() == birthdate.getMonth() && today.getDate() < birthdate.getDate())) {
	age--;
  }

  return age;
}

// 나이 계산 함수 실행부
$.ageCalculateFn = function(birth){
	// 나이 계산 및 결과 출력
    var age = calculateAge(birth);
    //console.log("나이: " + age);
    return age;
};

// 대기 상태가 W, N, C, E인 녀석은 못들어오게 막아!
$.excludeNonUserFn = function(userId){
	var meetAreaListCont = $(".meetAreaLists a");
	meetAreaListCont.click(function(event){
		event.preventDefault();
		var thisIs = $(this);
		var hrefTxt = thisIs.attr("href");
		var splitHrefTxt = hrefTxt.split("=");
		var plNo = splitHrefTxt[1];
		console.log("대기자 id : ", userId);
		console.log("플랜 번호 : ", plNo);
		var planerVO = {
			"memId": userId,
			"plNo": plNo
		};
		$.ajax({
			type: "get",
			url: "/partner/excludeNonUser.do",
			data: planerVO,
			dataType: "json",
			success: function(res){
				console.log("res : ", res);
				console.log("res.mategroupApply : ", res.mategroupApply);
				if(res.mategroupApply == 'W'){
					//alert("현재 플래너 일정 참여 대기중입니다.");
					Swal.fire({
						title: "대기중",
						text: "현재 플래너 일정 참여 대기중입니다.",
						icon: "info"
					});
					return false;
				}
				if(res.mategroupApply == 'N'){
					//alert("현재 플래너 일정에 참가하실 수 없습니다.");
					Swal.fire({
						title: "참가 거절",
						text: "현재 플래너 일정에 참가하실 수 없습니다.",
						icon: "error"
					});
					return false;
				}
				if(res.mategroupApply == "C"){
					//alert("현재 플래너 일정을 취소하셨습니다. 재참여가 불가능합니다.");
					Swal.fire({
						title: "참가 취소",
						text: "현재 플래너 일정을 취소하셨습니다. 재참여가 불가능합니다.",
						icon: "warning"
					});
					return false;
				}
				if(res.mategroupApply == "E"){
					Swal.fire({
						title: "모집 마감",
						text: "현재 플래너 일정이 마감되었습니다. 다른 플랜에 참여를 부탁드립니다.",
						icon: "info"
					});
					return false;
				}
				location.href = hrefTxt;
			}
		});
	});
};

// 채팅방 > 목록으로 돌아가기 기능
$.moveBackListBtnClickFn = function(){
	var moveBackList = $(".moveBackList");
	moveBackList.click(function(){
		location.href = "/partner/mygroup.do";
	});
};

// 신청멤버 > 멤버 승인 기능
$.acceptMemBtnClickFn = function(plNo){
	var acceptMemBtn = $(".acceptMemBtn");
	acceptMemBtn.click(function(){
		var thisIs = $(this);
		var memId = thisIs.parent().prev().text();
		console.log("memId : ", memId);
		console.log("plNo : ", plNo);

		var rejectObj = {
			"url" : "/partner/acceptMem.do",
			"message" : "해당 멤버의 신청이 승인되었습니다."
		};

		var planerVO = {
			"memId": memId,
			"plNo": plNo
		};
		
		$.ajaxMemBtnClickFn(planerVO, rejectObj);
	});
};

// 신청멤버 > 멤버 거절 기능
$.rejectMemBtnClickFn = function(plNo){
	var rejectMemBtn = $(".rejectMemBtn");
	rejectMemBtn.click(function(){
		var thisIs = $(this);
		var memId = thisIs.parent().prev().text();
		console.log("memId : ", memId);
		console.log("plNo : ", plNo);

		var rejectObj = {
			"url" : "/partner/rejectMem.do",
			"message" : "해당 멤버의 신청이 거절되었습니다."
		};

		var planerVO = {
			"memId": memId,
			"plNo": plNo
		};
		
		$.ajaxMemBtnClickFn(planerVO, rejectObj);
	});
};

// 강퇴 기능
$.kickOutFn = function(plNo){
    var kickoutEl = $(".currentMemList li:not(:first-of-type):not(:nth-of-type(2))");
    kickoutEl.click(function(){
        var thisIs = $(this);
        var kickOutId = thisIs.find("span:nth-of-type(4)").text();
        console.log("kickOutId : " + kickOutId);
        var kickOutName = thisIs.find(".kickOutNameTxt").text().trim();
        console.log("kickOutName : " + kickOutName);
        
        // var kickYN = confirm(kickOutName + "님을 강퇴하시겠습니까?");
        // if(kickYN) {
		// 	var memId = thisIs.children().eq(3).text();
		// 	console.log("memId : ", memId);
		// 	console.log("plNo : ", plNo);

		// 	var rejectObj = {
		// 		"url" : "/partner/rejectMem.do",
		// 		"message" : kickOutName + "님이 강퇴되었습니다."
		// 	};
	
		// 	var planerVO = {
		// 		"memId": memId,
		// 		"plNo": plNo
		// 	};
			
		// 	$.ajaxMemBtnClickFn(planerVO, rejectObj);
        // }
        
        Swal.fire({
			title: "멤버 강퇴",
			text: kickOutName + "님을 강퇴하시겠습니까?",
			icon: "question",
		    showDenyButton: true,
		    confirmButtonText: "예",
		    denyButtonText: "아니오"
		}).then((result) => {
		    if (result.isConfirmed) {

				var memId = thisIs.children().eq(3).text();
				console.log("memId : ", memId);
				console.log("plNo : ", plNo);

				var rejectObj = {
					"url" : "/partner/rejectMem.do",
					"message" : kickOutName + "님이 강퇴되었습니다."
				};
		
				var planerVO = {
					"memId": memId,
					"plNo": plNo
				};
				
				$.ajaxMemBtnClickFn(planerVO, rejectObj);

		    } else if (result.isDenied) {

		        Swal.fire({
					title: "채팅방 강퇴",
					text: kickOutName + "님이 강퇴를 취소합니다.",
					icon: "error"
				});

		    }
		});

    });
};

// ajax > 멤버 승인/거절 공통 함수
$.ajaxMemBtnClickFn = function(planerVO, {url, message}){
	$.ajax({
		type: "get",
		url: url,
		data: planerVO,
		dataType: "json",
		success: function(res){
			console.log("res : ", res);

			// var recruiter = res.recruiter;
			// var mateList = res.mateList;
			var mateCnt = res.mateCnt;

			// // 현재 멤버 리스트 시작
			// var currentMemListHtmlTxt = `
			// 	<li>
			// 		<span>이름</span>
			// 		<span>성별</span>
			// 		<span>나이</span>
			// 		<span>ID</span>
			// 		<span>결제여부</span>
			// 	</li>
			// `;

			// if(Object.keys(recruiter).length === 0){ // 플래너가 없는 경우
			// 	currentMemListHtmlTxt += `
			// 		<div style="text-align: center; width: 50%; margin: 0px auto; float: none; cursor: auto; background-color: #333; color: white; padding: 20px; border-radius: 4px;">
			// 			현재 플래너가 없습니다.
			// 		</div>
			// 	`;
			// }else {
			// 	// 플래너 리스트
			// 	var recruiterHtmlTxt = `
			// 		<li>
			// 			<span class="textDrop">
			// 				<i class="fas fa-crown"></i>
			// 				<span class="chatProfileImgBox">
			// 					<img src="${recruiter.memProfileimg }" alt="프로필 이미지" />
			// 				</span>
			// 				${recruiter.memName }(플래너)
			// 				<i class="fas fa-circle"></i>
			// 			</span>
			// 			<span>`;

			// 			if(recruiter.memGender == "M") {
			// 				recruiterHtmlTxt += `남자`;
			// 			}else if(recruiter.memGender == "F") {
			// 				recruiterHtmlTxt += `여자`;
			// 			}

			// 	recruiterHtmlTxt += `
			// 			</span>
			// 			<span class="recruitAge">00세</span>
			// 			<span class="textDrop">${recruiter.memId }</span>
			// 			<span>`;

			// 			if(recruiter.mategroupAgree == 0) {
			// 				recruiterHtmlTxt += `차감 전`;
			// 			}else if(recruiter.mategroupAgree == 1) {
			// 				recruiterHtmlTxt += `차감 완료`;
			// 			}else if(recruiter.mategroupAgree == 2) {
			// 				recruiterHtmlTxt += `결제 완료`;
			// 			}

			// 	recruiterHtmlTxt += `
			// 			</span>
			// 		</li>
			// 	`;

			// 	// 현재 리스트에 플래너 리스트를 먼저 붙이고 시작한다.
			// 	currentMemListHtmlTxt += recruiterHtmlTxt;
			// }

			// if(mateList.length == 0) {
			// 	currentMemListHtmlTxt += `
			// 		<div style="text-align: center; width: 50%; margin: 0px auto; float: none; cursor: auto; background-color: #333; color: white; padding: 20px; border-radius: 4px;">
			// 			현재 멤버가 없습니다.
			// 		</div>
			// 	`;
			// }

			// for(var i=0; i<mateList.length; i++) {
			// 	if(mateList[i].mategroupApply == 'Y') { // 현재 멤버로 업데이트 된 녀석만 가져와서 반복문 돌릴거임
			// 		currentMemListHtmlTxt += `
			// 			<li class="textDropVerticalAlign">
			// 				<span class="textDrop">
			// 					<span class="chatProfileImgBox">
			// 						<img src="${mateList[i].memProfileimg }" alt="프로필 이미지" />
			// 					</span>
			// 					${mateList[i].memName }
			// 					<i class="fas fa-circle"></i>
			// 				</span>
			// 				<span>`;

			// 			if(mateList[i].memGender == 'M') {
			// 				currentMemListHtmlTxt += `남자`;
			// 			}else if(mateList[i].memGender == 'F') {
			// 				currentMemListHtmlTxt += `여자`;
			// 			}

			// 		currentMemListHtmlTxt +=`
			// 				</span>
			// 				<span id="lgj${i}">00세</span>
			// 				<span class="textDrop">${mateList[i].memId }</span>
			// 				<span>`;
							
			// 			if(mateList[i].mategroupAgree == 0) {
			// 				currentMemListHtmlTxt += `차감 전`;
			// 			}else if(mateList[i].mategroupAgree == 1) {
			// 				currentMemListHtmlTxt += `차감 완료`;
			// 			}else if(mateList[i].mategroupAgree == 2) {
			// 				currentMemListHtmlTxt += `결제 완료`;
			// 			}

			// 		currentMemListHtmlTxt +=`
			// 				</span>
			// 			</li>
			// 		`;
			// 	}
			// }

			// // 신청 멤버 리스트 시작
			// var waitMemListHtmlTxt = `
			// 	<li>
			// 		<span>이름</span>
			// 		<span>성별</span>
			// 		<span>나이</span>
			// 		<span>ID</span>
			// 		<span>승인/거절</span>
			// 	</li>
			// `;

			// for(var i=0; i<mateList.length; i++) {
			// 	if(mateList[i].mategroupApply == 'W'){ // 대기 중인 멤버만 가져와서 반복문 돌릴거임
			// 		waitMemListHtmlTxt += `
			// 			<li class="textDropVerticalAlign memChk">
			// 				<span class="textDrop">
			// 					<span class="chatProfileImgBox">
			// 						<img src="${mateList[i].memProfileimg }" alt="프로필 이미지" />
			// 					</span>
			// 					${mateList[i].memName }
			// 					<i class="fas fa-circle"></i>
			// 				</span>
			// 				<span>`;

			// 			if(mateList[i].memGender == 'M') {
			// 				waitMemListHtmlTxt += `남자`;
			// 			}else if(mateList[i].memGender == 'F') {
			// 				waitMemListHtmlTxt += `여자`;
			// 			}

			// 		waitMemListHtmlTxt +=`
			// 				</span>
			// 				<span id="lgj${i}">00세</span>
			// 				<span class="textDrop findId">${mateList[i].memId }</span>
			// 				<span>
			// 					<button class="btn btn-success acceptMemBtn" type="button">승인</button>
			// 					<button class="btn btn-danger rejectMemBtn" type="button">거절</button>
			// 				</span>
			// 			</li>
			// 		`;
			// 	}
			// }

			// // 현재 멤버 리스트 갱신
			// var currentMemList = $(".currentMemList");
			// currentMemList.html(currentMemListHtmlTxt);

			// // 신청 멤버 리스트 갱신
			// var waitMemList = $(".waitMemList");
			// waitMemList.html(waitMemListHtmlTxt);

			// // 플래너 나이 계산
			// var recruiterAgeDate = recruiter.memAgedate;
			// var recruiterCalcAgeTxt = $.ageCalculateFn(recruiterAgeDate);
			// console.log("ajax > recruiterCalcAgeTxt : ", recruiterCalcAgeTxt);
			// $(".recruitAge").html(recruiterCalcAgeTxt + "세");

			// // 참여자 나이 계산(현재멤버)
			// for(var i=0; i<mateList.length; i++) {
			// 	if(mateList[i].mategroupApply == 'Y') {
			// 		console.log("mateList[i].memAgedate : ", mateList[i].memAgedate);
			// 		$("#lgj" + i).html(`${$.ageCalculateFn(mateList[i].memAgedate)}세`);
			// 	}
			// }

			// // 참여자 나이 계산(신청멤버)
			// for(var i=0; i<mateList.length; i++) {
			// 	if(mateList[i].mategroupApply == 'W') {
			// 		console.log("mateList[i].memAgedate : ", mateList[i].memAgedate);
			// 		$("#lgj" + i).html(`${$.ageCalculateFn(mateList[i].memAgedate)}세`);
			// 	}
			// }
			
			// // 신청멤버 > 멤버 승인 기능
			// $.acceptMemBtnClickFn();

			// // 신청멤버 > 멤버 거절 기능
			// $.rejectMemBtnClickFn();

			// 화면 재 갱신
			var encodedMessage = encodeURIComponent(message);
			location.href = "/partner/meetsquare.do?plNo=" + planerVO.plNo + "&message=" + encodedMessage + "&mateCnt=" + mateCnt;
		}
	});
};

// 플래너 리스트 > 일정 취소 처리 함수
$.myTripCancelFn = function(){
	var myTripCancelBtn = $(".myTripCancelBtn");
	myTripCancelBtn.click(function(){

		// var thisIs = $(this);
		// var cancleYN = confirm("플래너 일정을 취소하시겠습니까?");
		// if(cancleYN) {
		// 	thisIs.parent().find("#chgStatusJoiner").submit();
		// }

		var thisIs = $(this);
		Swal.fire({
		    title: "플래너 일정을 취소하시겠습니까?",
		    showDenyButton: true,
		    confirmButtonText: "예",
		    denyButtonText: "아니오"
		}).then((result) => {
		    if (result.isConfirmed) {
				thisIs.parent().find("#chgStatusJoiner").submit();
		    } else if (result.isDenied) {
		        Swal.fire({
					title: "일정 유지",
					text: kickOutName + "님이 일정을 유지합니다.",
					icon: "info"
				});
		    }
		});

	});
};

// 채팅 기능
$.chatingFn = function(roomNo, {chatMemId, chatMemName, chatMemProfileimg, chatRoomNo}){
	var chatingWebSocket; // 페이지가 바뀌지 않도록 주의!

	var chatRoomContents = $(".chatRoomContents"); // 채팅방 > 채팅 표출 영역 EL
	var chatInputMsg = $(".chatInputMsg"); // 채팅입력 EL
	var sendChatMessage = $(".sendChatMessage"); // 전송버튼 EL
	var moveBackList = $(".moveBackList"); // 목록으로 돌아가기 버튼 EL
	
	var endpoint = "/chat";
	
	// 공통 함수 선언
	function chatingConnect(){
		chatingWebSocket = new SockJS(endpoint); // 엔드 포인트
		
		chatingWebSocket.onopen = function(event) {
			console.log("WebSocket connection opened:", event);
			var enterUser = `
				<div class="memberInLog">
					<p style="display: inline-block;">
						${chatMemName} 님이 입장하셨습니다.
						</p>
					<span class="inFlag" style="display: none;">in</span>
					<span class="roomChkFlg" style="display: none;">${roomNo}</span>
				</div>
				,0
			`;
			chatingWebSocket.send(enterUser); // 기존 chatOpen 함수와 합침
		};
		
		chatingWebSocket.onmessage = function(event) {
			console.log("WebSocket message received:", event.data);
			chatMessage(event, chatMemId); // event 매개변수를 chatMessage 함수에 전달
		};
		
		chatingWebSocket.onclose = function(event) {
			console.log("WebSocket connection closed:", event);
		};
		
		chatingWebSocket.onerror = function(event) {
			console.error("WebSocket error:", event);
		};
	}

	// 연결시 실행되는 함수
	var parseHtmlConvert;
	function chatMessage(event, id){ // event 매개변수 추가
		var data = event.data;

		// html 객체로 변환
		parseHtmlConvert = $.parseHTML(data);
		console.log("parseHtmlConvert : ", parseHtmlConvert);

		// dataHtmlConvert는 배열이므로 첫 번째 요소에 대해 jQuery 객체로 변환
		var dataHtmlConvert = $(parseHtmlConvert[0]);
		console.log("dataHtmlConvert : ", dataHtmlConvert);

		var roomChkFlg = dataHtmlConvert.find(".roomChkFlg").text();
		console.log("roomNo : ", roomNo);
		console.log("roomChkFlg : ", roomChkFlg);

		var chatRoomContentsTxt = chatRoomContents.html();
		if(roomChkFlg != roomNo) {
			console.log("다른방 채팅입니다.");
			return;
		}
		
		chatRoomContents.html(chatRoomContentsTxt + "" + data);
		
		// 채팅방 채팅 내역, 날짜 박스 크기 같게 조절하기
		$.chatBoxEqualDateBoxFn();
		
		// 채팅사진 종횡비
		$.eachChatingMemberImgResizeFn();

		/*
			받아야 하는 파라미터 값 정리
			1. memId (0)
			2. roomNo (0)
			3. chatFile : null 허용, empty 텍스트 넣기
			4. chatContent (0)
			4. chatYmd (0)
			5. chatHms (0)
			6. chatCnt (0)
		*/

		var memberInLog = dataHtmlConvert.find(".inFlag").text();
		console.log("memberInLog : ", memberInLog);
		var memberOutLog = dataHtmlConvert.find(".outFlag").text();
		console.log("memberOutLog : ", memberOutLog);

		// 객체 안에 담긴 요소를 뽑아서 변수에 담기
		var chatMemId = dataHtmlConvert.find(".sendMemId").text();
		console.log("chatMemId : ", chatMemId);
		var chatMsgTxt = dataHtmlConvert.find(".chatMsgTxt").text();
		console.log("chatMsgTxt : ", chatMsgTxt);
		var yymmdd = dataHtmlConvert.find(".yymmdd").text();
		console.log("yymmdd : ", yymmdd);
		var hhmmss = dataHtmlConvert.find(".hhmmss").text();
		console.log("hhmmss : ", hhmmss);
		var myChatCnt = dataHtmlConvert.find(".myChatCnt").text();
		console.log("myChatCnt : ", myChatCnt);
		
		// 메시지 전송할 때 안에 들어 있는 값을 객체로 말아서 파라미터 값 전달
		var chatroomVO = {
			"memId" : chatMemId,
			"roomNo" : roomNo,
			"chatFile" : "empty",
			"chatContent" : chatMsgTxt,
			"chatYmd" : yymmdd,
			"chatHms" : hhmmss,
			"chatCnt" : myChatCnt
		};

		// 현재 로그인한 멤버와 채팅 멤버가 다르다면 1번만 쳐라!
		if(id == chatMemId){
			// 채팅방 입장, 퇴장시에는 예외 처리
			if (!memberInLog && !memberOutLog) {
				// ajax > 채팅 내역 저장
				$.ajaxChatContSaveFn(chatroomVO);
			}
		}
	}

	// ajax > 채팅 내역 저장
	$.ajaxChatContSaveFn = function(chatroomVO){
		$.ajax({
			type : "post",
			url : "/partner/ajaxChatInsert.do",
			data : chatroomVO,
			dataType : "text",
			success : function(res){
				console.log("res : ", res);
			}
		});
	};

	// 채팅 입력시 실행되는 함수
	var cnt = 0; // 현재 내가 채팅을 날린 '총 횟수'
	function chatingSend({senderMemId, senderMemName, senderMemProfileimg, senderRoomNo}){
		cnt++;
		var msg = chatInputMsg.val().trim();
		console.log("msg : ", msg);
		
		if(msg == "") {
			//alert("채팅 메시지를 입력 후 전송해 주세요.");
			Swal.fire({
				title: "안내",
				text: "채팅 메시지를 입력 후 전송해 주세요.",
				icon: "info"
			});
			chatInputMsg.val("");
			return false;
		}
		
		console.log("senderMemId : ", senderMemId);
		console.log("senderMemName : ", senderMemName);
		console.log("senderMemProfileimg : ", senderMemProfileimg);
		console.log("senderRoomNo : ", senderRoomNo);

		if(!senderMemId) {
			senderMemId = "empty";
		}
		if(!senderMemName) {
			senderMemName = "empty";
		}
		if(!senderMemProfileimg) {
			senderMemProfileimg = "empty";
		}
		
		var innerTalkerMsgTxt = `${msg},${cnt},${senderMemId},${senderMemName},${senderMemProfileimg},${senderRoomNo}`;
		chatingWebSocket.send(innerTalkerMsgTxt);
		chatInputMsg.val("");
		
		// 메시지 전송 후 채팅 영역 최하단으로 스크롤
    	scrollToBottom();
	}
	
	// 스크롤을 최하단으로 이동하는 함수
	function scrollToBottom(){
	    // .chatRoomContents 요소의 스크롤을 최하단으로 이동
		var scrollHeight = chatRoomContents.prop("scrollHeight");
		console.log("chatRoomContents/scrollHeight : ", scrollHeight);
		chatRoomContents.scrollTop(scrollHeight);
	}
	
	// 채팅방을 나갈 시 실행되는 함수
	function chatingDisconnect(){
		var leaveUser = `
				<div class="memberOutLog">
					<p style="display: inline-block;">
						${chatMemName} 님이 퇴장하셨습니다.
					</p>
					<span class="outFlag" style="display: none;">out</span>
					<span class="roomChkFlg" style="display: none;">${roomNo}</span>
				</div>
				,0
			`;
		chatingWebSocket.send(leaveUser);
		chatingWebSocket.close();
	}

	// 연결
	chatingConnect();

	// 전역 변수 선언
	var senderObj = {
		senderMemId: chatMemId,
		senderMemName: chatMemName,
		senderMemProfileimg: chatMemProfileimg,
		senderRoomNo: chatRoomNo
	};

	// 이벤트 핸들러 선언
	sendChatMessage.click(function(){
		chatingSend(senderObj);
	});
	
	// 뒤로 돌아가기 버튼 클릭 시 채팅 웹 소켓 종료
	moveBackList.click(function(){
		chatingDisconnect();
	});
	
	// 페이지를 떠날 때 웹 소켓 종료
	$(window).on('unload', function() {
	    chatingDisconnect();
	});
	
	// 다른 페이지로 이동할 때 웹 소켓 종료
	$(window).on('beforeunload', function() {
	    chatingDisconnect();
	});
	
	// 엔터키 입력시 채팅 전송
	$(".chatInputMsg").keyup(function(e){
	    // 엔터키 : 13
	    if(e.keyCode == 13) {
	        if (e.shiftKey) {
	            // 만약 Shift 키와 함께 Enter 키가 눌렸다면, 새로운 줄 문자를 입력값에 추가합니다.
	            $(this).val(function(i, val) {
	                return val;
	            });
	        } else {
	            // 만약 Enter 키만 눌렸다면, click 이벤트를 트리거합니다.
	            sendChatMessage.trigger("click");
	        }
	    }
	});
	
	// 시작하자 마자 스크롤 하단으로 이동
	scrollToBottom();
	
};

// 채팅방, 멤버 박스 높이 맞추기
$.memBoxEqualChatBoxH = function(){
    var chatRoomLeft = $(".chatRoomLeft");
    var chatRoomRight = $(".chatRoomRight");
    var chatRoomLeftH = chatRoomLeft.outerHeight();
    var chatRoomRightH = chatRoomRight.outerHeight();
    if(chatRoomLeftH < chatRoomRightH) {
        chatRoomLeft.outerHeight(chatRoomRightH);
    }else {
        chatRoomRight.outerHeight(chatRoomLeftH);
    }
};

// 채팅방 채팅 내역, 날짜 박스 크기 같게 조절하기
function eachCompareBoxHFn(eachEl){
    eachEl.each(function(){
        var thisIs = $(this);
        var thisCompareEl1 = thisIs.find("p");
        var thisCompareEl2 = thisIs.find(".chatDateInfo");
        var thisCompareElOutH1 = thisCompareEl1.outerHeight();
        var thisCompareElOutH2 = thisCompareEl2.outerHeight();
        if(thisCompareElOutH1 > thisCompareElOutH2) {
            thisCompareEl2.outerHeight(thisCompareElOutH1);
        }else {
            thisCompareEl1.outerHeight(thisCompareElOutH2);
        }
    });
}

$.chatBoxEqualDateBoxFn = function(){
    var outerStartDialog = $(".outerStartDialog");
    eachCompareBoxHFn(outerStartDialog);
    
    var outerLongtakeDialog = $(".outerLongtakeDialog");
    eachCompareBoxHFn(outerLongtakeDialog);
    
    var innerStartDialog = $(".innerStartDialog");
    eachCompareBoxHFn(innerStartDialog);
    
    var innerLongtakeDialog = $(".innerLongtakeDialog");
    eachCompareBoxHFn(innerLongtakeDialog);
};

// 찬섭 여행종료 추가
$(".travelTheEndBtn").on("click", function() {
	let plNoNo = $("#plNo").val();
	Swal.fire({
		title: "여행종료",
		text: "정말로 여행을 종료하시겠습니까?",
		icon: "question",
		showDenyButton: true,
		confirmButtonText: "예",
		denyButtonText: "아니오",
	}).then((result) => {
		if(result.isConfirmed) {
			$.travelTheEndFn(plNoNo);
		} else if(result.isDenied) {
			$.sweetAlertFn("여행종료", "취소되었습니다.", "success");
		}
	});

});

$.travelTheEndFn = function(plNo) {
	$.ajax({
		url:'/partner/travelTheEndAjax.do',
		data:{"plNo" : plNo},
		type:"get",
		success : function(res) {
			if(res === "OK") {
				$.sweetAlertFn("여행종료", "여행을 종료하였습니다.", "success").then((result) => {
					location.href="/partner/meetsquare.do?plNo=" + plNo;
				});
			}
		}
	});
}

// 찬섭 채팅 저장 추가

/* sweetAlert 유틸  */
$.sweetAlertFn = function(title, text, icon) {
	return Swal.fire({
		title: title,
		text: text,
		icon: icon,
		confirmButtonText : "확인"
	})
}

$.sweetAlertConfirmFn = function(title, html, icon) {
	return Swal.fire({
		title: title,
		html: html,
		icon: icon,
		showDenyButton: true,
		confirmButtonText: "예",
		denyButtonText: "아니오",
	})
}


/* 사용할 ajax 함수 정의 */
// 채팅 다운로드 ajax
$.chatContTxtDownAjax = function(plNo) {
	return new Promise((resolve) => {
		$.ajax({
			type: "GET",
			url: "/partner/chatContTxtDown.do",
			data: { plNo: plNo },
			success: function(data) {
				// console.log("data", data);
				if(data == null || data == "") {
					$.sweetAlertFn("채팅내역 저장", "저장할 채팅 내역이 없습니다.", "error");
				} else {
					// 다운로드 링크 생성 및 클릭
					var blob = new Blob([data], { type: 'text/plain' });
					var link = document.createElement('a');
					link.href = window.URL.createObjectURL(blob);
					link.download = "Chat_Log_" + new Date().toISOString().replace(/[:.]/g, "_") + ".txt";
					document.body.appendChild(link);
					link.click();
					document.body.removeChild(link);
				}
				resolve(data);
			}
		});
	});
};

// 채팅 삭제 ajax
$.chatContDeleteAjax = function(plNo) {
	return new Promise((resolve) => {
		$.ajax({
			type: "GET",
			url: "/partner/chatContDelete.do",
			data: { plNo: plNo },
			success: function(data) {
				
				if(data.delRes === "success") {
					$.sweetAlertFn("이전 채팅 삭제", "이전 날짜의 채팅을 삭제하였습니다.", "success").then((result) => {
						if(result.isConfirmed) {
							location.href = "/partner/meetsquare.do?plNo=" + plNo;
						}
					});
				} else {
					$.sweetAlertFn("이전 채팅 삭제", "오늘 날짜 이전의 채팅내역이 존재하지 않아 삭제에 실패하였습니다.", "error")
				}
				resolve(data);
			}
		});
	});
};

/* 실제 로직 */

// 채팅내역 버튼을 클릭해서 채팅 다운로드
$.chatContTxtDownFn = function(plNo) {
	let chatContTxtDownEl = $(".chatContTxtDown");
	chatContTxtDownEl.on("click", function() {
		$.chatContTxtDownAjax(plNo)
	});
};

// 이전 채팅 삭제 버튼을 클릭해서 채팅 삭제
$.chatContDeleteFn = function(plNo) {
	let chatContDeleteEl = $(".chatContDelete");
	
	chatContDeleteEl.on("click", function() {
		$.sweetAlertConfirmFn("이전 채팅 삭제", "오늘 날짜보다 이전의 채팅을 삭제하시겠습니까?", "question")
		.then((result) => {

			// 위의 sweetAlertConfirmFn 결과가 '예'라면 채팅을 저장할지를 다시 묻는다. (아니오라면 아무일도 안 일어남)
			if (result.isConfirmed) {
				$.sweetAlertConfirmFn("채팅내역 저장", "지금까지의 채팅을 저장하시겠습니까?", "question")
				.then((result) => {

					// 위의 sweetAlertConfirmFn 결과가 '예'라면
					if(result.isConfirmed) {

						// 채팅을 저장하고,
						$.chatContTxtDownAjax(plNo)
						.then((result) => {

							// 채팅을 삭제한다
							$.chatContDeleteAjax(plNo);
						});

					// sweetAlertConfirmFn 결과가 '아니오'라면 그냥 삭제
					} else if (result.isDenied) {
						$.chatContDeleteAjax(plNo);
					}
				});
			}
			 
		});
	});
}

// 일정공유 버튼을 클릭해서 pdf 다운로드
$.planShareFn = function(plNo) {
	let planShareEl = $(".planShare");
	planShareEl.on("click", function() {
		// alert("클릭됨" + plNo);
		$.planShareAjax(plNo)
	});
};

$.planShareAjax = function(plNo) {

	Swal.fire({
		title: "일정공유",
		text: "해당 플랜에 대한 일정을 PDF형식으로 다운받으시겠습니까?",
		icon: "info",
		showDenyButton: true,
		confirmButtonText: "예",
		denyButtonText: "아니오",
	}).then((result) => {
		if(result.isConfirmed) {
			location.href="/partner/planShare.do?plNo="+plNo;
		} else if(result.isDenied) {
			$.sweetAlertFn("일정공유", "일정공유를 취소합니다.", "info");
		}
	});
	
};

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

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
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.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
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.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import kr.or.ddit.users.login.vo.MemberVO;
import kr.or.ddit.users.partner.service.MyTripService;
import kr.or.ddit.users.partner.vo.ChatroomVO;
import kr.or.ddit.users.partner.vo.PlanerVO;
import kr.or.ddit.utils.ServiceResult;
import lombok.extern.slf4j.Slf4j;
 
@Slf4j
@Controller
@RequestMapping("/partner")
public class MyGroupPartnerController {

	@Inject
	private MyTripService myTripService;
	
	// 플래너 리스트 페이지 이동
	@CrossOrigin(origins = "http://localhost")
	@RequestMapping(value = "/mygroup.do", method = RequestMethod.GET)
	public String mygroup(
			HttpSession session,
			Model model
			) {
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		
		MemberVO memberVO = (MemberVO) session.getAttribute("sessionInfo");
		if(memberVO != null) {
			String memId = memberVO.getMemId(); // 작성자
			param.put("memId", memId);
		}
		
		/** 서비스 호출 */
		myTripService.myTripList(param);
		
		/** 반환 자료 */
		List<PlanerVO> planerList = (List<PlanerVO>) param.get("planerList");
		
		/** 자료 검증 */
		log.info("planerList : " + planerList.toString());
		
		/** 자료 반환 */ 
		model.addAttribute("planerList", planerList);
		
		return "partner/mygroup";
	}
	
	// ajax > 실시간 플래너 리스트 검색
	@GetMapping("/ajaxSearch.do")
	@ResponseBody
	public List<PlanerVO> planerList(PlanerVO planerVO) {
		log.info("planerVO : {}" , planerVO);
		return myTripService.searchPlanerList(planerVO);
	}
	
	// 플래너 공개/비공개 처리 메서드
	@PostMapping("/chgStatusPlan.do")
	public String chgStatusPlan(
			PlanerVO planerVO,
			Model model,
			RedirectAttributes ra
			) {
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("memId", planerVO.getMemId());
		param.put("plNo", planerVO.getPlNo());
		param.put("plPrivate", planerVO.getPlPrivate());
		
		/** 서비스 호출 */
		myTripService.chgStatusPlan(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 { // 업데이트 실패
			model.addAttribute("message", message);
			model.addAttribute("msgflag", "fa");
		}
		
		/** 자료 반환 */
		return goPage;
	}
	
	// 플래너 삭제 메서드
	@PostMapping("/deletePlan.do")
	public String deletePlan(
			PlanerVO planerVO,
			Model model,
			RedirectAttributes ra
			) {
		
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("plNo", planerVO.getPlNo());
		
		/** 서비스 호출 */
		myTripService.deletePlan(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 { // 삭제 실패
			model.addAttribute("message", message);
			model.addAttribute("msgflag", "fa");
		}
		
		/** 자료 반환 */
		return goPage;
		
	}
	
	// 만남의 광장 상세 페이지 이동
	@CrossOrigin(origins = "http://localhost")
	@GetMapping("/meetsquare.do")
	public String meetsquareRoom(
			int plNo,
			Model model
			) {
		
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("plNo", plNo);
		
		/** 서비스 호출 */
		myTripService.meetsquareRoom(param);
		
		/** 반환 자료 */
		PlanerVO recruiter = (PlanerVO) param.get("recruiter");
		List<PlanerVO> mateList = (List<PlanerVO>) param.get("mateList");
		int mateCnt = (int) param.get("mateCnt");
		List<PlanerVO> chatRoomInfo = (List<PlanerVO>) param.get("chatRoomInfo");
		List<PlanerVO> chatInfoList = (List<PlanerVO>) param.get("chatInfoList");
		
		/** 자료 검증 */
		log.info("recruiter : " + recruiter);
		log.info("mateList : " + mateList);
		log.info("mateCnt : " + mateCnt);
		log.info("chatRoomInfo : " + chatRoomInfo);
		log.info("chatInfoList : " + chatInfoList);
		
		model.addAttribute("recruiter", recruiter);
		model.addAttribute("mateList", mateList);
		model.addAttribute("mateCnt", mateCnt);
		model.addAttribute("chatRoomInfo", chatRoomInfo);
		model.addAttribute("chatInfoList", chatInfoList);
		
		return "partner/meetsquareRoom";
		
	}
	
	// ajax > 대기자, 거부/강퇴자 검색
	@GetMapping("/excludeNonUser.do")
	@ResponseBody
	public PlanerVO excludeNonUser(PlanerVO planerVO) {
		log.info("planerVO : {}" , planerVO);
		return myTripService.excludeNonUser(planerVO);
	}
	
	// ajax > 멤버 승인 메서드
	@GetMapping("/acceptMem.do")
	@ResponseBody
	public ResponseEntity<Object> acceptMem(PlanerVO planerVO) {
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("memId", planerVO.getMemId());
		param.put("plNo", planerVO.getPlNo());
		
		Map<String, Object> responseData = new HashMap<String, Object>();
		
		/** 서비스 호출 */
		myTripService.acceptMem(param);
		
		/** 반환 자료 */
		PlanerVO recruiter = (PlanerVO) param.get("recruiter");
		List<PlanerVO> mateList = (List<PlanerVO>) param.get("mateList");
		int mateCnt = (int) param.get("mateCnt");
		
		/** 자료 검증 */
		log.info("recruiter : " + recruiter);
		log.info("mateList : " + mateList);
		log.info("mateCnt : " + mateCnt);
		
		/** 자료 반환 */
		responseData.put("recruiter", recruiter);
		responseData.put("mateList", mateList);
		responseData.put("mateCnt", mateCnt);
		
		return ResponseEntity.ok(responseData);
	}
	
	// ajax > 멤버 거절 메서드
	@GetMapping("/rejectMem.do")
	@ResponseBody
	public ResponseEntity<Object> rejectMem(PlanerVO planerVO) {
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("memId", planerVO.getMemId());
		param.put("plNo", planerVO.getPlNo());
		
		Map<String, Object> responseData = new HashMap<String, Object>();
		
		/** 서비스 호출 */
		myTripService.rejectMem(param);
		
		/** 반환 자료 */
		PlanerVO recruiter = (PlanerVO) param.get("recruiter");
		List<PlanerVO> mateList = (List<PlanerVO>) param.get("mateList");
		int mateCnt = (int) param.get("mateCnt");
		
		/** 자료 검증 */
		log.info("recruiter : " + recruiter);
		log.info("mateList : " + mateList);
		log.info("mateCnt : " + mateCnt);
		
		/** 자료 반환 */
		responseData.put("recruiter", recruiter);
		responseData.put("mateList", mateList);
		responseData.put("mateCnt", mateCnt);
		
		return ResponseEntity.ok(responseData);
	}
	
	// 참여자 > 플래너 취소 기능
	@PostMapping("/chgStatusJoiner.do")
	public String chgStatusJoiner(
			PlanerVO planerVO,
			Model model,
			RedirectAttributes ra
			) {
		
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("memId", planerVO.getMemId());
		param.put("plNo", planerVO.getPlNo());
		
		/** 서비스 호출 */
		myTripService.chgStatusJoiner(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 { // 업데이트 실패
	        model.addAttribute("message", message);
	        model.addAttribute("msgflag", "fa");
	    }

	    /** 자료 반환 */
	    return goPage;
		
	}
	
	// ajax > 채팅 내역 저장 메서드
	@PostMapping("/ajaxChatInsert.do")
	@ResponseBody
	public String ajaxChatContSave(ChatroomVO chatroomVO) {
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("chatroomVO", chatroomVO);
		
		/** 서비스 호출 */
		myTripService.ajaxChatContSave(param);
		
		/** 반환 자료 */
		String result = (String) param.get("result");
		
		/** 자료 검증 */
		log.info("result : {}", result);
		
		/** 자료 반환 */
		return result;
	}
	
	// 모집 마감 처리 메서드
	@PostMapping("/groupRecruitEnded.do")
	public String groupRecruitEnded(
			PlanerVO planerVO,
			Model model,
			RedirectAttributes ra
			) {
		
		/** 자료 수집 및 정의 */
	    Map<String, Object> param = new HashMap<String, Object>();
	    param.put("plNo", planerVO.getPlNo());
	    log.info("plNo : {}", planerVO.getPlNo());
	    
	    /** 서비스 호출 */
	    myTripService.groupRecruitEnded(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;
		
	}
	
	@RequestMapping(value = "/planShare.do", method = RequestMethod.GET)
	public ResponseEntity<Void> planShare(
			HttpServletResponse response,
			HttpServletRequest request, @RequestParam("plNo") int plNo) throws IOException {
		ResponseEntity<byte[]> entity = null;
	    Map<String, Object> param = new HashMap<>();
	    param.put("plNo", plNo);
	    Map<String, Object> result = myTripService.planShare(request, param);
	    
	    String filename = (String) result.get("filename");
	    File saveFile = new File(request.getServletContext().getRealPath("/resources/pdf/"+plNo + "/"+filename));
	    
		response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");

		// try with resource
		// () 안에 명시한 객체는 finally로 최종 열린 객체에 대한 close를 처리하지 않아도 자동 close()가 이루어진다.
		try(
				OutputStream os = response.getOutputStream();
		) {
			FileUtils.copyFile(saveFile, os);
		} 
		return new ResponseEntity<Void>(HttpStatus.OK);
	}


	// 채팅내역 다운로드 메소드
	@GetMapping("/chatContTxtDown.do")
	public ResponseEntity<byte[]> chatContTxtDown(@RequestParam int plNo) {
		log.debug("chatContTxtDown() 실행...!");
		
		try {
			
			/** 자료 수집 및 정의 */
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("plNo", plNo);
			
			/** 서비스 호출 */
			myTripService.chatContTxtDown(param);
			
			/** 반환 자료 */
			byte[] contentBytes = (byte[])param.get("contentBytes");
			
			/** 자료 검증 */
			log.debug("plNo : {}", plNo);
			
			
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.parseMediaType("text/plain"));
			/** 자료 반환 */	
			if(contentBytes == null) {
				return ResponseEntity.ok().body(null);
			} else {
				return ResponseEntity.ok()
						.headers(headers)
						.body(contentBytes);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
		}
		
	}
	
	// 오늘 날짜 이전의 채팅을 삭제하는 메소드
	@GetMapping("/chatContDelete.do")
	@ResponseBody
	public ResponseEntity<Object> chatContDelete(@RequestParam int plNo) {
		log.debug("chatContDelete() 실행...!");
		
		/** 자료 수집 및 정의 */
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("plNo", plNo);
		
		/** 서비스 호출 */
		myTripService.chatContDelete(param);

		/** 반환 자료 */	
		String delRes = (String)param.get("delRes");
		
		/** 자료 검증 */
		log.debug("plNo은 왔나요 : {}", plNo);
		log.debug("delRes : {}", delRes);
		
		/** 자료 반환 */	
		return ResponseEntity.ok(param);
	}
	
	@GetMapping("/travelTheEndAjax.do")
	@ResponseBody
	public ServiceResult travelTheEndAjax(@RequestParam int plNo) {
		ServiceResult result = myTripService.travelTheEnd(plNo);
		return result;
	}
	
}

package kr.or.ddit.users.partner.vo;

import org.springframework.web.multipart.MultipartFile;

import lombok.Data;

@Data
public class PlanerVO {
 
	private int plNo;
	private String memId;
	private String plRdate;
	private String plTitle;
	private String plMsize;
	private String plPrivate;
	private String plTheme;
	private String plThumburl;
	
	/* 조인 용도 */
	// MemberVO
	private int memNo;
	private String memPw;
	private String memName;
	private String memGender;
	private String memEmail;
	private String memPhone;
	private String memPostcode;
	private String memAddress1;
	private String memAddress2;
	private String gradeCode;
	private String enabled;
	private int memCategory;
	private String memRegdate;
	private String memAgedate;
	
	private MultipartFile imgFile;
	private String memProfileimg;
	
	// mategroupVO
	private int mgNo;
	private String mategroupRecruiter;
	private int mategroupCurrentnum;
	private String mategroupStatus;
	private int mategroupPoint;
	
	// mategroupMemberVO
	private int mategroupNo;
	private String mategroupId;
	private int mategroupAgree;
	private String mategroupApply;
	
	// ChatroomVO
	private int roomNo;
	private String roomRegdate;
	
	// ChatVO
	private int chatNo;
	private String chatFile;
	private String chatContent;
	private String chatYmd;
	private String chatHms;
	private String chatCnt;
	
	// 내플랜 - 그룹장
	// 동행참가 - 참여자
	private String sType;
	
}

package kr.or.ddit.users.partner.vo;

import lombok.Data;

@Data
public class ChatroomVO {

	private int roomNo;
	private String roomRegdate;
	private int mgNo;
	
	/* 조인 용도 */
	// ChatVO
	private int chatNo;
	private String memId;
	private String chatFile;
	private String chatContent;
	private String chatYmd;
	private String chatHms;
	private String chatCnt;
	
}

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

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;


import kr.or.ddit.users.partner.vo.PlanerVO;
import kr.or.ddit.utils.ServiceResult;

public interface MyTripService {
 
	public void myTripList(Map<String, Object> param);
	public List<PlanerVO> searchPlanerList(PlanerVO planerVO);
	public void chgStatusPlan(Map<String, Object> param);
	public void deletePlan(Map<String, Object> param);
	public void meetsquareRoom(Map<String, Object> param);
	public PlanerVO excludeNonUser(PlanerVO planerVO);
	public void acceptMem(Map<String, Object> param);
	public void rejectMem(Map<String, Object> param);
	public void chgStatusJoiner(Map<String, Object> param);
	public void ajaxChatContSave(Map<String, Object> param);
	public void groupRecruitEnded(Map<String, Object> param);
	public void chatContTxtDown(Map<String, Object> param) ;
	public void chatContDelete(Map<String, Object> param);
	public Map<String, Object> planShare(HttpServletRequest request, Map<String, Object> param) throws IOException;
	public ServiceResult travelTheEnd(int plNo);

}

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

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import kr.or.ddit.mapper.MyTripMapper;
import kr.or.ddit.mapper.PdfUploadMapper;
import kr.or.ddit.users.partner.service.MyTripService;
import kr.or.ddit.users.partner.vo.ChatroomVO;
import kr.or.ddit.users.partner.vo.PlanerVO;
import kr.or.ddit.utils.ServiceResult;
import lombok.extern.slf4j.Slf4j;

import java.nio.file.Files;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class MyTripServiceImpl implements MyTripService {

	@Inject
	private MyTripMapper myTripMapper;
	
	@Inject
	private PdfUploadMapper pdfUploadMapper;
	
	@Override
	public void myTripList(Map<String, Object> param) {
		/** 파라미터 조회 */
		String memId = (String) param.get("memId");
		
		/** 파라미터 정의 */
		List<PlanerVO> planerList = new ArrayList<PlanerVO>();
		
		/** 메인로직 처리 */
		// 플래너 리스트 가져오기
		PlanerVO planerVO = new PlanerVO();
		planerVO.setMemId(memId);
		planerList = myTripMapper.myTripList(planerVO);
		
		/** 반환자료 저장 */
		param.put("planerList", planerList);
	}

	@Override
	public List<PlanerVO> searchPlanerList(PlanerVO planerVO) {
		return myTripMapper.searchPlanerList(planerVO);
	}

	@Override
	public void chgStatusPlan(Map<String, Object> param) {
		/** 파라미터 조회 */
		String memId = (String) param.get("memId");
		int plNo = (int) param.get("plNo");
		String plPrivate = (String) param.get("plPrivate");
		
		/** 파라미터 정의 */
		PlanerVO planerVO = new PlanerVO();
		int status = 0;
		ServiceResult result = null;
		String message = "";
		String goPage = "";
		
		/** 메인로직 처리 */
		// 해당 플래너를 공개/비공개 처리 하기
		planerVO.setMemId(memId);
		planerVO.setPlNo(plNo);
		
		if(plPrivate.equals("Y")) { // 비공개 처리
			planerVO.setPlPrivate("N");
		}else if(plPrivate.equals("N")) { // 공개 처리
			planerVO.setPlPrivate("Y");
		}
		
		status = myTripMapper.chgStatusPlan(planerVO);
		
		if(status > 0) { // 업데이트 성공
			result = ServiceResult.OK;
			if(plPrivate.equals("Y")) { // 비공개 처리
				message = "해당 플래너를 비공개 처리하였습니다.";
			}else if(plPrivate.equals("N")) { // 공개 처리
				message = "해당 플래너를 공개 처리하였습니다.";
			}
			goPage = "redirect:/partner/mygroup.do";
		}else { // 업데이트 실패
			result = ServiceResult.FAILED;
			message = "해당 플래너를 갱신하는데 실패했습니다.";
			goPage = "partner/mygroup";
		}
		
		/** 반환자료 저장 */
		param.put("result", result);
		param.put("message", message);
		param.put("goPage", goPage);
	}

	@Override
	public void deletePlan(Map<String, Object> param) {
		/** 파라미터 조회 */
		int plNo = (int) param.get("plNo");
		
		/** 파라미터 정의 */
		int status = 0;
		ServiceResult result = null;
		String message = "";
		String goPage = "";
		
		/** 메인로직 처리 */
		// 항공편 삭제
		myTripMapper.deleteCartAir(plNo);
		myTripMapper.deleteCart(plNo);
		
		// 플래너 삭제하기
		// 1. 세부플랜(s_planer) 삭제 - plNo 이용
		myTripMapper.deleteSPlaner(plNo);
		
		// 2. 좋아요 삭제(planer_like) - plNo 이용
		myTripMapper.deletePlanerLike(plNo);
		
		// 3. 동행 그룹 멤버(mategroup_member)삭제 후 동행그룹(mategroup)삭제
		// plNo에 해당하는 동행그룹을 하나 조회하여 그 그룹번호(mg_no)가 외래키로 들어간 동행그룹멤버 테이블의 레코드를 전부 삭제
		myTripMapper.deleteMategrpMem(plNo);
		// + 채팅방도 삭제
		myTripMapper.deleteChatAll(plNo);
		myTripMapper.deleteChatRoom(plNo);
		myTripMapper.deleteMategrp(plNo);
		
		
		
		// 4. 플랜(planer) 삭제 - plNo 이용
		status = myTripMapper.deletePlan(plNo);
		
		if(status > 0) { // 삭제 성공
			result = ServiceResult.OK;
			message = "해당 플래너를 삭제하였습니다.";
			goPage = "redirect:/partner/mygroup.do";
		}else { // 삭제 실패
			result = ServiceResult.FAILED;
			message = "해당 플래너 삭제에 실패했습니다.";
			goPage = "partner/mygroup";
		}
		
		/** 반환자료 저장 */
		param.put("result", result);
		param.put("message", message);
		param.put("goPage", goPage);
	}

	@Override
	public void meetsquareRoom(Map<String, Object> param) {
		/** 파라미터 조회 */
		int plNo = (int) param.get("plNo");
		
		/** 파라미터 정의 */
		PlanerVO recruiter = new PlanerVO();
		List<PlanerVO> mateList = new ArrayList<PlanerVO>();
		int mateCnt = 0;
		List<PlanerVO> chatRoomInfo = new ArrayList<PlanerVO>();
		List<PlanerVO> chatInfoList = new ArrayList<PlanerVO>();
		
		/** 메인로직 처리 */
		// 해당 플래너 참여자 목록 들고 오기
		// 1. 모집자 목록 들고오기
		recruiter = myTripMapper.meetsquareRoomOne(plNo);
		// 2. 참여자 목록 들고오기
		mateList = myTripMapper.meetsquareRoomList(plNo);
		// 3. 현재멤버 수 들고오기
		mateCnt = myTripMapper.mateCnt(plNo);
		// 4. 채팅방 정보 들고오기
		chatRoomInfo = myTripMapper.chatRoomInfo(plNo);
		// 5. 채팅내역 들고오기
		chatInfoList = myTripMapper.chatInfoList(plNo);
		
		/** 반환자료 저장 */
		param.put("recruiter", recruiter);
		param.put("mateList", mateList);
		param.put("mateCnt", mateCnt);
		param.put("chatRoomInfo", chatRoomInfo);
		param.put("chatInfoList", chatInfoList);
	}

	@Override
	public PlanerVO excludeNonUser(PlanerVO planerVO) {
		return myTripMapper.excludeNonUser(planerVO);
	}

	@Override
	public void acceptMem(Map<String, Object> param) {
		/** 파라미터 조회 */
		String memId = (String) param.get("memId");
		int plNo = (int) param.get("plNo");
		
		/** 파라미터 정의 */
		PlanerVO planerVO = new PlanerVO();
		int status = 0;
		int status2 = 0;
		PlanerVO recruiter = new PlanerVO();
		List<PlanerVO> mateList = new ArrayList<PlanerVO>();
		int mateCnt = 0;
		
		/** 메인로직 처리 */
		// 1. 멤버 상태를 승인으로 업데이트
		planerVO.setMemId(memId);
		planerVO.setPlNo(plNo);
		status = myTripMapper.acceptMemUpd(planerVO);
		
		// 2. 만들어진 채팅방에 승인된 멤버를 인서트해야 함
		// mategroup테이블의 mategroup_currentnum(현재원)를 가입 신청 상태가 'Y'인 승인된 회원들의 수로 업데이트 
		status2 = myTripMapper.updateCurMemCnt(plNo);	
		
		if(status > 0) { // 멤버 상태 승인
			if(status2 > 0) {
				// 2. 갱신된 리스트 들고 오기
				recruiter = myTripMapper.meetsquareRoomOne(plNo);
				mateList = myTripMapper.meetsquareRoomList(plNo);
			}
		}
		
		// 3. 갱신된 채팅방 참여자 수 가져오기
		mateCnt = myTripMapper.mateCnt(plNo);
		
		/** 반환자료 저장 */
		param.put("recruiter", recruiter);
		param.put("mateList", mateList);
		param.put("mateCnt", mateCnt);
	}

	@Override
	public void rejectMem(Map<String, Object> param) {
		/** 파라미터 조회 */
		String memId = (String) param.get("memId");
		int plNo = (int) param.get("plNo");
		
		/** 파라미터 정의 */
		PlanerVO planerVO = new PlanerVO();
		int status = 0;
		int status2 = 0;
		PlanerVO recruiter = new PlanerVO();
		List<PlanerVO> mateList = new ArrayList<PlanerVO>();
		int mateCnt = 0;
		
		/** 메인로직 처리 */
		// 1. 멤버 상태를 승인으로 업데이트
		planerVO.setMemId(memId);
		planerVO.setPlNo(plNo);
		status = myTripMapper.rejectMemUpd(planerVO);
		
		// 현재원을 업데이트
		status2 = myTripMapper.updateCurMemCnt(plNo);
		
		if(status > 0) { // 멤버 상태 승인
			// 2. 갱신된 리스트 들고 오기
			if (status2 > 0) {
				recruiter = myTripMapper.meetsquareRoomOne(plNo);
				mateList = myTripMapper.meetsquareRoomList(plNo);
			}
		}
		
		// 3. 갱신된 채팅방 참여자 수 가져오기
		mateCnt = myTripMapper.mateCnt(plNo);
		
		/** 반환자료 저장 */
		param.put("recruiter", recruiter);
		param.put("mateList", mateList);
		param.put("mateCnt", mateCnt);
	}

	@Override
	public void chgStatusJoiner(Map<String, Object> param) {
		/** 파라미터 조회 */
		String memId = (String) param.get("memId");
		int plNo = (int) param.get("plNo");
		
		/** 파라미터 정의 */
		PlanerVO planerVO = new PlanerVO();
		int status = 0;
		int status2 = 0;
		ServiceResult result = null;
		String message = "";
		String goPage = "";
		
		/** 메인로직 처리 */
		// 해당 플래너 취소 처리 하기
		planerVO.setMemId(memId);
		planerVO.setPlNo(plNo);
		
		status = myTripMapper.chgStatusJoiner(planerVO);
		
		// 현재 인원을 업데이트
		status2 = myTripMapper.updateCurMemCnt(plNo);
		
		if(status > 0) { // 업데이트 성공
			if(status2 > 0) {
				result = ServiceResult.OK;
				message = "해당 플래너를 취소하였습니다. 재참여는 불가합니다.";
				goPage = "redirect:/partner/mygroup.do";
			} else {
				result = ServiceResult.FAILED;
				message = "현재 인원을 업데이트 하는데 실패했습니다. 다시 시도해 주세요.";
				goPage = "partner/mygroup";
			}
		}else { // 업데이트 실패
			result = ServiceResult.FAILED;
			message = "해당 플래너를 취소하는데 실패했습니다. 다시 시도해 주세요.";
			goPage = "partner/mygroup";
		}
		
		/** 반환자료 저장 */
	    param.put("result", result);
	    param.put("message", message);
	    param.put("goPage", goPage);
	}

	@Override
	public void ajaxChatContSave(Map<String, Object> param) {
		/** 파라미터 조회 */
		ChatroomVO chatroomVO = (ChatroomVO) param.get("chatroomVO");
		
		/** 파라미터 정의 */
		String result = "";
		int status = 0;
		
		/** 메인로직 처리 */
		// 1. 채팅 내역 저장하기
		status = myTripMapper.ajaxChatContSave(chatroomVO);
		if(status > 0) { // 채팅 내역 저장 성공
			result = "OK";
		}else { // 채팅 내역 저장 실패
			result = "FAILED";
		}
		
		/** 반환자료 저장 */
		param.put("result", result);
	}

	@Override
	public void groupRecruitEnded(Map<String, Object> param) {
		/** 파라미터 조회 */
	    int plNo = (int) param.get("plNo");
	    
	    /** 파라미터 정의 */
	    int cnt1 = 0;
	    int cnt2 = 0;
	    int status = 0;
	    int status2 = 0;
	    ServiceResult result = null;
	    String message = "";
	    String goPage = "";
	    
	    /** 메인로직 처리 */
	    // 0. 혼자가는 여행일 경우, mategroup_apply = 'Y'이게 나 혼자니까 무조건 cnt2 = 1;
	    cnt1 = myTripMapper.soloTrip(plNo);
	    log.debug("cnt1 : {}", cnt1);
	    
//	    if(cnt1 == 1) { // 신청 멤버는 모르겠고 나혼자 무조건 ㄱ
//	    	// 1. 현재 플래너에 대기 중인 나 자신을 모집 마감 상태로 바꾸기
//    		status = myTripMapper.mategroupApplyCancel(plNo);
//    		if(status > 0) {
//    			// 2. 현재 플래너의 상태를 1단계에서 2단계로 바꾸기
//			    status2 = myTripMapper.mategroupStatusSecondStage(plNo);
//		    	if(status2 > 0) { // 2단계로 바꾸기 성공
//		    		result = ServiceResult.OK;
//			        message = "현재 플래너에 참여 모집을 마감하였습니다. 다음 단계를 진행해 주세요.";
//			        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
//		    	}else { // 2단계로 바꾸기 실패
//		    		result = ServiceResult.FAILED;
//			        message = "2단계로 바꾸기 실패했습니다.";
//			        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
//		    	}
//    		}
//	    }else if(cnt1 > 0) { // 신청 멤버는 모르겠는데 일단 동행 모집할 거임
//
//	    }
	    // 경우의수 
	    // 1. 나 자신은 당연히 'Y'겠지
	    // 나 혼자인 경우
	    // 1. 아무도 안 받고 나만 있는 상태에서 모집마감
	    // 2. 아무도 안 받고 신청한 사람('W')이 있는 상태에서 모집마감
	    // 3. 아무도 안 받고 신청한 사람('W')이 있는 상태에서 모집마감
	    // 동행 모집한경우
	    // 1. 나 외에 한명 이상을 승인한 상황에서 대기자('W')가 존재하는 경우
	    // 2. 나 외에 한명 이상을 승인한 상황에서 거절자나 취소자('C', 'N')가 존재하는 경우
	    // 3. 나 외에 한명 이상을 승인한 상황에서 대기자나 거절자, 취소자가 존재하지 않는 경우
	    
	    cnt1 = myTripMapper.soloTrip(plNo);
	    
	    // cnt1 == 1이면 혼자가는거여
	    if(cnt1 == 1) {
	    	// 신청멤버를 센다
	    	cnt2 = myTripMapper.waitMemCnt(plNo);
	    	log.debug("cnt2 : {}", cnt2);
	    	if(cnt2 == 0) {	// 신청멤버가 없어. 또는 취소자나 거절자만 있어
	    		// 모집마감 가능
	    		status2 = myTripMapper.mategroupStatusSecondStage(plNo);
	    		if(status2 > 0) {
	    			result = ServiceResult.OK;
			        message = "현재 플래너에 참여 모집을 마감하였습니다. 다음 단계를 진행해 주세요.";
			        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
	    		} else {
	    			result = ServiceResult.FAILED;
			        message = "2단계로 바꾸기 실패했습니다.";
			        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
	    		}
	    		
	    	} else if(cnt2 >= 1) {	// 신청멤버가 한명 이상이여
	    		// 일단 대기자들을 E(모집마감)상태로 바꾸고 모집마감해
	    		status = myTripMapper.mategroupApplyCancel(plNo);
	    		if(status > 0) {
	    			status2 = myTripMapper.mategroupStatusSecondStage(plNo);
	    			if(status2 > 0) {
	    				result = ServiceResult.OK;
				        message = "현재 플래너에 참여 모집을 마감하였습니다. 다음 단계를 진행해 주세요.";
				        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
	    			} else {
	    				result = ServiceResult.FAILED;
				        message = "2단계로 바꾸기 실패했습니다.";
				        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
	    			}
	    		} else {
	    			result = ServiceResult.FAILED;
			        message = "모집 마감 상태 변경 실패했습니다.";
			        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
	    		}
	    		
	    	}
	    	
	    } else if(cnt1 > 1) {	// cnt1 2이상이면 같이가는 거겠지
	    	// 신청멤버를 센다
	    	cnt2 = myTripMapper.waitMemCnt(plNo);
	    	log.debug("cnt2 : {}", cnt2);
	    	if(cnt2 == 0) {	// 신청멤버가 없어. 또는 취소자나 거절자만 있어
	    		// 모집마감 가능
	    		status2 = myTripMapper.mategroupStatusSecondStage(plNo);
	    		if(status2 > 0) {
	    			result = ServiceResult.OK;
			        message = "현재 플래너에 참여 모집을 마감하였습니다. 다음 단계를 진행해 주세요.";
			        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
	    		} else {
	    			result = ServiceResult.FAILED;
			        message = "2단계로 바꾸기 실패했습니다.";
			        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
	    		}
	    		
	    	} else if(cnt2 >= 1) {	// 신청멤버가 한명 이상이여
	    		// 일단 대기자들을 E(모집마감)상태로 바꾸고 모집마감해
	    		status = myTripMapper.mategroupApplyCancel(plNo);
	    		if(status > 0) {
	    			status2 = myTripMapper.mategroupStatusSecondStage(plNo);
	    			if(status2 > 0) {
	    				result = ServiceResult.OK;
				        message = "현재 플래너에 참여 모집을 마감하였습니다. 다음 단계를 진행해 주세요.";
				        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
	    			} else {
	    				result = ServiceResult.FAILED;
				        message = "2단계로 바꾸기 실패했습니다.";
				        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
	    			}
	    		} else {
	    			result = ServiceResult.FAILED;
			        message = "모집 마감 상태 변경 실패했습니다.";
			        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
	    		}
	    		
	    	}
	    	
	    }
	    
	    
    	// 0. 신청멤버 카운트를 센다
//    	cnt2 = myTripMapper.waitMemCnt(plNo);
//    	log.debug("cnt2 : {}", cnt2);
//    	if(cnt2 == 0) { // 신청 멤버가 없는 경우
//    		result = ServiceResult.FAILED;
//            message = "신청 멤버가 없습니다.";
//            goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
//    	}else if(cnt2 >= 1) { // 동행 참가인 경우
//    		// 1. 현재 플래너에 대기 중인 멤버를 모집 마감 상태로 바꾸기
//		    status = myTripMapper.mategroupApplyCancel(plNo);
//		    
//		    if(status > 0) { // 모집 마감 상태 변경 성공
//		    	// 2. 현재 플래너의 상태를 1단계에서 2단계로 바꾸기
//			    status2 = myTripMapper.mategroupStatusSecondStage(plNo);
//		    	if(status2 > 0) { // 2단계로 바꾸기 성공
//		    		result = ServiceResult.OK;
//			        message = "현재 플래너에 참여 모집을 마감하였습니다. 다음 단계를 진행해 주세요.";
//			        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
//		    	}else { // 2단계로 바꾸기 실패
//		    		result = ServiceResult.FAILED;
//			        message = "2단계로 바꾸기 실패했습니다.";
//			        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
//		    	}
//		    }else { // 모집 마감 상태 변경 실패
//		    	result = ServiceResult.FAILED;
//		        message = "모집 마감 상태 변경 실패했습니다.";
//		        goPage = "redirect:/partner/meetsquare.do?plNo=" + plNo;
//		    }
//    	}
	    
	    /** 반환자료 저장 */
	    param.put("result", result);
	    param.put("message", message);
	    param.put("goPage", goPage);
	}

	@Override
	public void chatContTxtDown(Map<String, Object> param) {
		
		/** 파라미터 조회 */
		int plNo = (int)param.get("plNo");
		
		/** 파라미터 정의*/
		List<PlanerVO> allChatList = new ArrayList<PlanerVO>();
		
		/** 메인로직 처리 */
		allChatList = myTripMapper.chatContTxtDown(plNo);
		
		// 로그 내용 만들기
		StringBuilder content = new StringBuilder();
        for (PlanerVO message : allChatList) {
        	String line = String.format("[%s][%s][%s]: %s", 
			message.getChatYmd(), message.getChatHms(), message.getMemName(), message.getChatContent());
            content.append(line).append("\n");
        }
        
        String allContent = content.toString();
        log.debug("allContent : {}", allContent);
        
        byte[] contentBytes = allContent.getBytes();
        
        /** 반환자료 저장 */
        param.put("contentBytes", contentBytes);
		
	}

	@Override
	public void chatContDelete(Map<String, Object> param) {
		/** 파라미터 조회 */
		int plNo = (int)param.get("plNo");
		
		/** 파라미터 정의*/
		int status =  0;
		String delRes = "";
		
		/** 메인로직 처리 */
		status = myTripMapper.chatContDelete(plNo);
		
		if(status > 0) {
			delRes = "success"; 
		} else {
			delRes = "failed"; 
		}
		
		/** 반환자료 저장 */
		param.put("delRes", delRes);
		
	}

	// 일정공유
	@Override
	public Map<String, Object> planShare(HttpServletRequest request, Map<String, Object> param) throws IOException {
	    // 파라미터 조회
	    int plNo = (int)param.get("plNo");
	    String pdfUrl = pdfUploadMapper.getPdfUrl(plNo);
	    
	    log.info("pdfUrl : " + pdfUrl);
	    log.info("plNo : " + plNo);

	    Map<String, Object> result = new HashMap<String, Object>();

	    // pdfUrl이 null이 아닌 경우에만 처리합니다.
	    if (pdfUrl != null) {
	        // PDF 파일이 저장된 경로를 찾습니다.
	        String realPath = request.getServletContext().getRealPath(pdfUrl);
	        File pdfFile = new File(realPath);

	        log.info("realPath : " + realPath);
	        log.info("pdfFile : " + pdfFile.getName());
	      

	        // PDF 파일이 존재하는 경우, 파일의 바이트 배열과 파일 이름을 반환합니다.
	        if(pdfFile.exists()) {
	            byte[] fileBytes = Files.readAllBytes(pdfFile.toPath());
	            String filename = pdfFile.getName();

	            result.put("fileBytes", fileBytes);
	            result.put("filename", filename);
	        } 
	    }

	    return result;
	}

	@Override
	public ServiceResult travelTheEnd(int plNo) {
		ServiceResult sres = null;
		int res = myTripMapper.travelTheEnd(plNo);
		
		if(res > 0) {
			sres = ServiceResult.OK;
		} else {
			sres = ServiceResult.FAILED;
		}
		
		return sres;
	}

}

package kr.or.ddit.mapper;

import java.util.List;

import kr.or.ddit.users.partner.vo.ChatroomVO;
import kr.or.ddit.users.partner.vo.PlanerVO;
import kr.or.ddit.utils.ServiceResult;

public interface MyTripMapper {
 
	public List<PlanerVO> myTripList(PlanerVO planerVO);
	public List<PlanerVO> searchPlanerList(PlanerVO planerVO);
	public int chgStatusPlan(PlanerVO planerVO);
	public void deleteSPlaner(int plNo);
	public void deletePlanerLike(int plNo);
	public void deleteMategrpMem(int plNo);
	public void deleteMategrp(int plNo);
	public int deletePlan(int plNo);
	public PlanerVO meetsquareRoomOne(int plNo);
	public List<PlanerVO> meetsquareRoomList(int plNo);
	public PlanerVO excludeNonUser(PlanerVO planerVO);
	public int mateCnt(int plNo);
	public int acceptMemUpd(PlanerVO planerVO);
	public int rejectMemUpd(PlanerVO planerVO);
	public int chgStatusJoiner(PlanerVO planerVO);
	public void deleteChatRoom(int plNo);
	public int updateCurMemCnt(int plNo);
	public List<PlanerVO> chatInfoList(int plNo);
	public int ajaxChatContSave(ChatroomVO chatroomVO);
	public List<PlanerVO> chatRoomInfo(int plNo);
	public int mategroupApplyCancel(int plNo);
	public int mategroupStatusSecondStage(int plNo);
	public List<PlanerVO> chatContTxtDown(int plNo);
	public void deleteChatAll(int plNo);
	public int chatContDelete(int plNo);
	public int waitMemCnt(int plNo);
	public int soloTrip(int plNo);
	public void deleteCartAir(int plNo);
	public void deleteCart(int plNo);
	public int travelTheEnd(int plNo);

}

<?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.MyTripMapper">
 
	<select id="myTripList" parameterType="planerVO" resultType="planerVO">
		SELECT *
		  FROM (
		    SELECT 
		        '내플랜' as sType, 
		        A.PL_NO, 
		        A.MEM_ID, 
		        M.MEM_NAME, 
		        B.MATEGROUP_STATUS,
		        A.PL_RDATE, 
		        A.PL_TITLE, 
		        A.PL_MSIZE, 
		        A.PL_PRIVATE, 
		        A.PL_THEME, 
		        A.PL_THUMBURL, 
		        C.MATEGROUP_ID,
		        C.MATEGROUP_APPLY,
		        B.MATEGROUP_CURRENTNUM
		    FROM 
		        PLANER A
		        JOIN MATEGROUP B ON A.PL_NO = B.PL_NO 
		        JOIN MATEGROUP_MEMBER C ON B.MG_NO = C.MG_NO 
		        JOIN members M ON A.MEM_ID = M.MEM_ID 
		    WHERE 
		        A.MEM_ID = #{memId}
		        AND B.MATEGROUP_RECRUITER = #{memId}
		    
		    UNION ALL
		
		    SELECT 
		        '동행참가' as sType, 
		        A.PL_NO, 
		        A.MEM_ID, 
		        M.MEM_NAME, 
		        B.MATEGROUP_STATUS,
		        A.PL_RDATE, 
		        A.PL_TITLE, 
		        A.PL_MSIZE, 
		        A.PL_PRIVATE, 
		        A.PL_THEME, 
		        A.PL_THUMBURL, 
		        C.MATEGROUP_ID,
		        C.MATEGROUP_APPLY,
		        B.MATEGROUP_CURRENTNUM
		    FROM 
		        PLANER A
		        JOIN MATEGROUP B ON A.PL_NO = B.PL_NO 
		        JOIN MATEGROUP_MEMBER C ON B.MG_NO = C.MG_NO 
		        JOIN members M ON A.MEM_ID = M.MEM_ID 
		    where 1=1 
		      AND A.PL_NO = B.PL_NO 
		      AND B.MG_NO = C.MG_NO
		      AND A.MEM_ID = M.MEM_ID
		      AND C.MATEGROUP_ID in (
		        SELECT DISTINCT C.MATEGROUP_ID
		        FROM 
		            PLANER A, MATEGROUP B, MATEGROUP_MEMBER C 
		        WHERE 
		            A.PL_NO = B.PL_NO AND B.MG_NO = C.MG_NO
		        )
		      AND C.MATEGROUP_ID = #{memId}
		    ORDER BY 
		        PL_NO DESC, 
		        sType
		  ) result
	</select>
	
	<select id="searchPlanerList" parameterType="planerVO" resultType="planerVO">
		SELECT *
		  FROM (
		    SELECT 
		        '내플랜' as sType, 
		        A.PL_NO, 
		        A.MEM_ID, 
		        M.MEM_NAME, 
		        B.MATEGROUP_STATUS,
		        A.PL_RDATE, 
		        A.PL_TITLE, 
		        A.PL_MSIZE, 
		        A.PL_PRIVATE, 
		        A.PL_THEME, 
		        A.PL_THUMBURL, 
		        C.MATEGROUP_ID,
		        C.MATEGROUP_APPLY
		    FROM 
		        PLANER A
		        JOIN MATEGROUP B ON A.PL_NO = B.PL_NO 
		        JOIN MATEGROUP_MEMBER C ON B.MG_NO = C.MG_NO 
		        JOIN members M ON A.MEM_ID = M.MEM_ID 
		    WHERE 
		        A.MEM_ID = #{memId}
		        AND B.MATEGROUP_RECRUITER = #{memId}
		    
		    UNION ALL
		
		    SELECT 
		        '동행참가' as sType, 
		        A.PL_NO, 
		        A.MEM_ID, 
		        M.MEM_NAME, 
		        B.MATEGROUP_STATUS,
		        A.PL_RDATE, 
		        A.PL_TITLE, 
		        A.PL_MSIZE, 
		        A.PL_PRIVATE, 
		        A.PL_THEME, 
		        A.PL_THUMBURL, 
		        C.MATEGROUP_ID,
		        C.MATEGROUP_APPLY
		    FROM 
		        PLANER A
		        JOIN MATEGROUP B ON A.PL_NO = B.PL_NO 
		        JOIN MATEGROUP_MEMBER C ON B.MG_NO = C.MG_NO 
		        JOIN members M ON A.MEM_ID = M.MEM_ID 
		    where 1=1 
		      AND A.PL_NO = B.PL_NO 
		      AND B.MG_NO = C.MG_NO
		      AND A.MEM_ID = M.MEM_ID
		      AND C.MATEGROUP_ID in (
		        SELECT DISTINCT C.MATEGROUP_ID
		        FROM 
		            PLANER A, MATEGROUP B, MATEGROUP_MEMBER C 
		        WHERE 
		            A.PL_NO = B.PL_NO AND B.MG_NO = C.MG_NO
		        )
		      AND C.MATEGROUP_ID = #{memId}
		    ORDER BY 
		        PL_NO DESC, 
		        sType
		  ) result
		where 1=1
		  and pl_title like '%' || #{plTitle} || '%'
		  and pl_msize like '%' || #{plMsize} || '%'
	</select>
	
	<update id="chgStatusPlan" parameterType="planerVO">
		MERGE INTO PLANER A
		USING (
		    SELECT A.PL_NO
		    FROM PLANER A
		    JOIN MATEGROUP B ON A.PL_NO = B.PL_NO
		    JOIN members M ON A.MEM_ID = M.MEM_ID
		    WHERE 
		        A.MEM_ID = #{memId}
		        AND B.MATEGROUP_RECRUITER = #{memId}
		        AND A.PL_NO = #{plNo}
		) B ON (A.PL_NO = B.PL_NO)
		WHEN MATCHED THEN
		    UPDATE SET A.PL_PRIVATE = #{plPrivate}
	</update>
	
	<delete id="deleteCartAir" parameterType="int">
		DELETE FROM cart_air
		WHERE cart_no = (SELECT cart_no FROM cart WHERE pl_no = #{plNo}) AND cartair_status = 'N'
	</delete>
	
	<delete id="deleteCart" parameterType="int">
		DELETE FROM cart
		WHERE pl_no = #{plNo}
	</delete>
	
	<delete id="deleteSPlaner" parameterType="int">
		DELETE FROM s_planer
		WHERE pl_no = #{plNo}
	</delete>
	
	<delete id="deletePlanerLike" parameterType="int">
		DELETE FROM planer_like
		WHERE pl_no = #{plNo}
	</delete>
	
	<delete id="deleteMategrpMem" parameterType="int">
		DELETE FROM mategroup_member
		where mg_no = (
		    select distinct a.mg_no
		      from mategroup a,
		           mategroup_member b
		     where 1=1 
		       and a.mg_no = b.mg_no
		       and a.pl_no = #{plNo}
		)
	</delete>
	
	<delete id="deleteMategrp" parameterType="int">
		DELETE FROM mategroup
		WHERE pl_no = #{plNo}
	</delete>
	
	<delete id="deletePlan" parameterType="int">
		DELETE FROM planer
		WHERE pl_no = #{plNo}
	</delete>
	
	<delete id="deleteChatAll" parameterType="int">
		DELETE 
		FROM 
		    chat
		WHERE 
		    room_no = (
		        SELECT 
		            room_no 
		        FROM 
		            chatroom 
		        WHERE mg_no = (
		            SELECT
		                mg_no
		            FROM
		                mategroup
		            WHERE 
		                pl_no = #{plNo}
		    )
		)
	</delete>
	
	<delete id="deleteChatRoom" parameterType="int">
		DELETE FROM chatroom
		WHERE mg_no = (
			select distinct a.mg_no
			from mategroup a,
				chatroom b
			where 1=1
				and a.mg_no = b.mg_no
				and a.pl_no = #{plNo}
		)
	</delete>
	
	<select id="meetsquareRoomOne" parameterType="int" resultType="planerVO">
		select d.*
		     , e.*
		  from (
		    select a.*
		         , b.mategroup_no
		         , b.mategroup_id
		         , b.mategroup_agree
		         , b.mategroup_apply
		         , c.pl_private
		         , c.pl_title
		         , c.pl_theme
		         , c.pl_thumburl
		         , c.pl_msize
		         , c.pl_rdate
		      from mategroup a
		         , mategroup_member b
		         , planer c
		     where 1=1
		       and a.mg_no = b.mg_no
		       and a.pl_no = c.pl_no
		       and a.pl_no = #{plNo}
		  ) d,
		  members e
		 where 1=1
		   and d.mategroup_id = e.mem_id
		   and d.mategroup_recruiter = d.mategroup_id
	</select>
	
	<select id="meetsquareRoomList" parameterType="int" resultType="planerVO">
		select d.*
		     , e.*
		  from (
		    select a.*
		         , b.mategroup_no
		         , b.mategroup_id
		         , b.mategroup_agree
		         , b.mategroup_apply
		         , c.pl_private
		         , c.pl_title
		         , c.pl_theme
		         , c.pl_thumburl
		         , c.pl_msize
		         , c.pl_rdate
		      from mategroup a
		         , mategroup_member b
		         , planer c
		     where 1=1
		       and a.mg_no = b.mg_no
		       and a.pl_no = c.pl_no
		       and a.pl_no = #{plNo}
		  ) d,
		  members e
		 where 1=1
		   and d.mategroup_id = e.mem_id
		   and d.mategroup_recruiter != d.mategroup_id
		 order by d.mategroup_no asc
	</select>
	
	<select id="excludeNonUser" parameterType="planerVO" resultType="planerVO">
		select d.*
		     , e.*
		  from (
		    select a.*
		         , b.mategroup_no
		         , b.mategroup_id
		         , b.mategroup_agree
		         , b.mategroup_apply
		         , c.pl_private
		         , c.pl_title
		         , c.pl_theme
		         , c.pl_thumburl
		         , c.pl_msize
		         , c.pl_rdate
		      from mategroup a
		         , mategroup_member b
		         , planer c
		     where 1=1
		       and a.mg_no = b.mg_no
		       and a.pl_no = c.pl_no
		       and a.pl_no = #{plNo}
		  ) d,
		  members e
		 where 1=1
		   and d.mategroup_id = e.mem_id
		   and d.mategroup_id = #{memId}
	</select>
	
	<select id="mateCnt" parameterType="int" resultType="int">
		select count(*) as cnt
		  from (
		    select a.*
		         , b.mategroup_no
		         , b.mategroup_id
		         , b.mategroup_agree
		         , b.mategroup_apply
		         , c.pl_private
		         , c.pl_title
		         , c.pl_theme
		         , c.pl_thumburl
		         , c.pl_msize
		         , c.pl_rdate
		      from mategroup a
		         , mategroup_member b
		         , planer c
		     where 1=1
		       and a.mg_no = b.mg_no
		       and a.pl_no = c.pl_no
		       and a.pl_no = #{plNo}
		  ) d,
		  members e
		 where 1=1
		   and d.mategroup_id = e.mem_id
		   and d.mategroup_apply = 'Y'
	</select>
	
	<update id="acceptMemUpd" parameterType="planerVO">
		UPDATE mategroup_member m
		   SET m.mategroup_apply = 'Y'
		 WHERE m.mg_no = (
		       SELECT a.mg_no
		         FROM mategroup a, planer c
		        WHERE a.mg_no = m.mg_no
		          AND a.pl_no = c.pl_no
		          AND a.pl_no = #{plNo}
		      )
		   AND m.mategroup_id = #{memId}
	</update>
	
	<update id="rejectMemUpd" parameterType="planerVO">
		UPDATE mategroup_member m
		   SET m.mategroup_apply = 'N'
		 WHERE m.mg_no = (
		       SELECT a.mg_no
		         FROM mategroup a, planer c
		        WHERE a.mg_no = m.mg_no
		          AND a.pl_no = c.pl_no
		          AND a.pl_no = #{plNo}
		      )
		   AND m.mategroup_id = #{memId}
	</update>
	
	<update id="chgStatusJoiner" parameterType="planerVO">
		UPDATE mategroup_member m
		   SET m.mategroup_apply = 'C'
		 WHERE m.mg_no = (
		       SELECT a.mg_no
		         FROM mategroup a, planer c
		        WHERE a.mg_no = m.mg_no
		          AND a.pl_no = c.pl_no
		          AND a.pl_no = #{plNo}
		      )
		   AND m.mategroup_id = #{memId}
	</update>
	
	<update id="updateCurMemCnt" parameterType="int">
    	UPDATE 
           mategroup
		SET 
            mategroup_currentnum = (
	            SELECT 
	                count(a.mategroup_id) 
	            FROM 
	            	mategroup_member a, mategroup b 
	            WHERE a.mg_no = b.mg_no and a.mategroup_apply = 'Y' and b.pl_no = #{plNo}
            )
        where 
            pl_no = #{plNo}
	</update>
	
	<select id="chatInfoList" parameterType="planerVO" resultType="planerVO">
		SELECT 
		      c.*
		    , m.mem_name
		    , m.mem_profileimg
		  FROM 
		      chat c, members m 
		  WHERE room_no = (
		      SELECT 
		          room_no 
		      FROM 
		          chatroom 
		      WHERE mg_no = (
		          SELECT
		              mg_no 
		          FROM
		              mategroup 
		          WHERE pl_no = #{plNo}
		          )
		      )
		      AND c.mem_id = m.mem_id
		  ORDER BY chat_no ASC
	</select>
	
	<insert id="ajaxChatContSave" parameterType="chatroomVO">
		INSERT INTO chat (
		    chat_no,
		    mem_id,
		    room_no,
		    chat_file,
		    chat_content,
		    chat_ymd,
		    chat_hms,
		    chat_cnt
		) VALUES (
		    seq_chat.nextval,
		    #{memId},
		    #{roomNo},
		    #{chatFile},
		    #{chatContent},
		    #{chatYmd},
		    #{chatHms},
		    #{chatCnt}
		)
	</insert>
	
	<select id="chatRoomInfo" parameterType="planerVO" resultType="planerVO">
		SELECT sub.*
		     , m.*
		     , cr.room_no
		     , cr.room_regdate
		FROM (
		    SELECT 
		        a.*, 
		        b.mategroup_no, 
		        b.mategroup_id, 
		        b.mategroup_agree, 
		        b.mategroup_apply, 
		        c.pl_private, 
		        c.pl_title, 
		        c.pl_theme, 
		        c.pl_thumburl, 
		        c.pl_msize, 
		        c.pl_rdate
		    FROM 
		        mategroup a, 
		        mategroup_member b, 
		        planer c
		    WHERE 
		        a.mg_no = b.mg_no
		        AND a.pl_no = c.pl_no
		        AND a.pl_no = #{plNo}
		) sub
		, chatroom cr
		, members m
		WHERE 
		    1 = 1
		    AND cr.mg_no = sub.mg_no
		    AND sub.mategroup_id = m.mem_id
		    AND sub.mategroup_apply = 'Y'
	</select>
	
	<update id="mategroupApplyCancel" parameterType="int">
		UPDATE mategroup_member m
		   SET m.mategroup_apply = 'E'
		 WHERE m.mg_no = (
		       SELECT a.mg_no
		         FROM mategroup a, planer c
		        WHERE a.mg_no = m.mg_no
		          AND a.pl_no = c.pl_no
		          AND a.pl_no = #{plNo}
		      )
		   AND m.mategroup_apply = 'W'
	</update>
	
	<select id="waitMemCnt" parameterType="int" resultType="int">
		SELECT
			count(*) cnt
		FROM
			mategroup_member
		WHERE
			mg_no = (SELECT mg_no FROM mategroup WHERE pl_no = #{plNo}) AND mategroup_apply = 'W'
	</select>
	
	<select id="soloTrip" parameterType="int" resultType="int">
		SELECT
			count(*) cnt
		FROM
			mategroup_member
		WHERE
			mg_no = (SELECT mg_no FROM mategroup WHERE pl_no = #{plNo})
	</select>
	
	<update id="mategroupStatusSecondStage" parameterType="int">
		UPDATE mategroup m
		   SET m.mategroup_status = '2단계'
		 WHERE m.mg_no = (
		    SELECT a.mg_no
		     FROM mategroup a, planer c
		    WHERE a.mg_no = m.mg_no
		      AND a.pl_no = c.pl_no
		      AND a.pl_no = #{plNo}
		)
	</update>
	
	<!-- 찬섭 추가 채팅 다운로드 밑작업 쿼리  -->
	<select id="chatContTxtDown" parameterType="planerVO" resultType="planerVO">
		SELECT 
		      c.*
		    , m.mem_name
		    , m.mem_profileimg
		  FROM 
		      chat c, members m 
		  WHERE room_no = (
		      SELECT 
		          room_no 
		      FROM 
		          chatroom 
		      WHERE mg_no = (
		          SELECT
		              mg_no 
		          FROM
		              mategroup 
		          WHERE pl_no = #{plNo}
		          )
		      )
		      AND c.mem_id = m.mem_id
		  ORDER BY chat_no ASC
	</select>
	
	<delete id="chatContDelete" parameterType="int">
		DELETE
		FROM
			chat
		WHERE room_no = (
		      SELECT 
		          room_no 
		      FROM 
		          chatroom 
		      WHERE mg_no = (
		          SELECT
		              mg_no 
		          FROM
		              mategroup 
		          WHERE pl_no = #{plNo}
		          )
		      )
      <![CDATA[  
		AND to_date(chat_ymd, 'YY/MM/DD') < TRUNC(sysdate)
		]]>
	</delete>
	
	<update id="travelTheEnd" parameterType="int">
		UPDATE
			mategroup
		SET
			mategroup_status = '4단계'
		WHERE
			pl_no = #{plNo}
	</update>

</mapper>