예약내역과 쿠폰을 불러오는 섹션은 같이 작성을 해보도록 하겠다. 모두 말그대로 사용자가 예약한 내역, 사용자가 내려받은 쿠폰을 조회하는 섹션이다.
예약 내역 조회

아래와 같이 javaScript로 서버에 요청을 하고
/*-------------예약내역 조회-----------------*/
function loadReservations() {
$.ajax({
type: 'POST',
url: '/reservation',
success: function(response) {
if (response.success) {
const reservation = response.reservation || []; // 예약 내역 배열
renderReservation(reservation); // 조회된 예약 데이터를 렌더링하는 함수 호출
} else {
console.error('예약 정보를 가져오는 데 실패했습니다.', response.error);
alert('예약 정보를 가져오는 데 실패했습니다.');
}
},
error: function(xhr, status, error) {
console.error('예약 정보를 가져오는 데 실패했습니다.', status, error);
alert('예약 정보를 가져오는 데 실패했습니다.');
}
});
}
- /reservation URL로 POST 요청 -> 사용자의 예약 내역(response)을 서버에서 가져온다. 서버에서 예약 정보를 성공적으로 받아오면 renderReservation 함수를 호출 한다.
*** renderReservation 함수
서버로 부터 받은 예약 데이터를 반복하여 렌더링하는 함수 ( 예약 내역에는 숙소 이미지, 객실 정보, 체크인/체크아웃 정보 및 예약 금액이 포함 ), 예약데이터가 없으면 예약 없음 메세지 표시
javaScript에서 요청해온 url로 매핑하여 controller를 작성했다.
// 마이페이지 예약 내역 조회
@PostMapping("/reservation")
@ResponseBody
public Map<String, Object> getReservation(@CookieValue(value = "Authorization", required = false) String token) {
Map<String, Object> response = new HashMap<>();
try {
Long userNo = jwtUtil.getUserNoFromToken(token);
// 예약 조회
List<SellerDto> reservation = memberServiceImpl.getUserReservation(userNo);
response.put("reservation", reservation);
response.put("success", true);
} catch (Exception e) {
response.put("success", false);
response.put("error", "예약 정보를 불러오는 중 오류가 발생했습니다.");
}
return response;
}
- /reservation URL로 POST 요청을 처리하는 컨트롤러
- memberServiceImpl.getUserReservation(userNo) : 토큰에서 꺼낸 userNo로 해당 사용자의 예약내역을 조회하는 메서드
- response.put -> 조회된 예약 내역은 reservation이라는 키로 프론트엔드로 전달되며, 성공 여부를 success 값으로 반환한다.
아래의 코드는 memberService, mapper 에서 처리하는 로직이다.
// 예약 내역 조회
@Override
public List<SellerDto> getUserReservation(Long userNo) {
// 사용자의 예약 내역을 숙소 이미지와 함께 가져옴
return memberMapper.getUserReservation(userNo);
}
==============================================================================
// MypageReservationMapper 코드
<resultMap id="UserReservation" type="kr.co.swm.model.dto.SellerDto">
<!-- 예약 정보 - 숙소 -->
...생략
<!-- 예약 정보 - 객실 -->
...생략
<!-- 예약 정보 - 예약 -->
...생략
<!-- 숙소 이미지 정보 매핑 -->
<association property="accommodationImageDto" javaType="kr.co.swm.adminPage.accommodation.model.dto.AccommodationImageDto">
<result column="IMAGE_FILE" property="uploadUniqueName"/>
<result column="UPLOAD_NAME" property="uploadImagePath"/>
</association>
</resultMap>
예약 내역을 불러오기 위해 나는 다른 팀원이 만들어서 사용하고 있던 SellerDto를 사용했다.
기존 SellerDto에는 예약 정보와 숙소 정보만 포함되어 있어 AccommodationImageDto라는 별도의 객체를 SellerDto에 포
함시켜 숙소 이미지 정보도 함께 전달할 수 있도록 했다.
**association 사용 -> 하나의 DTO안에 다른 DTO를 포함시켜 데이터를 매핑할 수 있게 해주는 기능이다.
// 숙소 이미지 DTO
private AccommodationImageDto accommodationImageDto;
- property="accommodationImageDto" : SellerDto 안에 있는 AccommodationImageDto 객체와 연결되도록 설정 하는 부분이다. 위 코드를 보면 내가 SellerDto안에 설정해 놓은 변수를 보면 된다.
- javaType="kr.co.swm.adminPage.accommodation.model.dto.AccommodationImageDto" : AccommodationImageDto의 클래스 경로를 지정하여 MyBatis가 어떤 타입의 객체와 매핑할지 알려주는 부분을 설정
이 작업을 통해 SellerDto 하나에 예약 정보 + 숙소 이미지 정보가 모두 담기게 되고, 클라이언트(사용자)는 예약 내역을 조회할 때 이미지까지 한 번에 받아볼 수 있게 된다.

위 와 같이 내역을 불러오며, 조회할 때 숙소키와 예약키를 받아와서 예약 취소와 예약 상세 처리도 같이 처리할 예정이다.
예약취소는 예약을 담당하는 팀원이 구현할 예정이며, 예약 상세 버튼을 눌렀을 때 처리하는 로직은 아래와 같다.
<div class="button-group" style="float: right;">
<button class="btn-danger" onclick="cancelReservation(${reservation.reserveRoomNo})">예약 취소</button>
<button class="btn-primary" onclick="viewReservationDetails(${reservation.accommodationNo})">예약 상세</button>
</div>
===================================================================================
// 예약 상세 페이지로 이동
function viewReservationDetails(accommodationNo) {
// 상세 페이지 URL 생성
const url = `/hotel-single?boardNo=${accommodationNo}`;
// 해당 URL로 이동
window.location.href = url;
}
- 예약 상세는 버튼을 누를때 viewReservationDetails(accommodationNo) 함수를 호출
- 상세 페이지로 이동하는 URL은 /hotel-single?boardNo=... 형식으로, 숙소의 고유 번호인 accommodationNo를 쿼리스트링으로 전달하여 예약한 숙소의 상세페이지로 이동
- window.location.href 는 브라우저의 현재 페이지를 해당 URL로 변경하는 기능이며, 이로써 사용자는 숙소 상세 페이지로 이동을 하게 된다!

쿠폰 조회
쿠폰을 조회하는 기능도 위와 같은 흐름으로 진행하였다.

javaScript에서 서버로 요청을 하였고
/*------------ 쿠폰 조회 -------------*/
function loadCoupons() {
$.ajax({
type: 'POST',
url: '/coupons',
success: function(response) {
if (response.success) {
const coupons = response.coupons || []; // 쿠폰 데이터 배열
renderCoupons(coupons); // 조회된 쿠폰 데이터를 렌더링하는 함수 호출
} else {
console.error('쿠폰 정보를 가져오는 데 실패했습니다.', response.error);
alert('쿠폰 정보를 가져오는 데 실패했습니다.');
}
},
error: function(xhr, status, error) {
console.error('쿠폰 정보를 가져오는 데 실패했습니다.', status, error);
alert('쿠폰 정보를 가져오는 데 실패했습니다.');
}
});
}
- /coupon URL로 POST 요청 -> 사용자의 쿠폰 내역(response)을 서버에서 가져온다. 서버에서 쿠폰 정보를 성공적으로 받아오면 renderCoupon 함수를 호출 한다.
*** renderCoupon 함수
서버로 부터 받은 쿠폰 데이터를 반복하여 렌더링하는 함수 (쿠폰이 있을 경우 : 쿠폰데이터 렌더링, 쿠폰이 없을 경우 : 메세지 표시)
// 마이페이지 쿠폰 조회
@PostMapping("/coupons")
@ResponseBody
public Map<String, Object> getCoupons(@CookieValue(value = "Authorization", required = false) String token) {
Map<String, Object> response = new HashMap<>();
try {
Long userNo = jwtUtil.getUserNoFromToken(token);
// 쿠폰 조회
List<WebDto> coupons = memberServiceImpl.getUserCoupons(userNo);
response.put("coupons", coupons);
response.put("success", true);
} catch (Exception e) {
response.put("success", false);
response.put("error", "쿠폰 정보를 불러오는 중 오류가 발생했습니다.");
}
return response;
}
- /coupon URL로 POST 요청을 처리하는 컨트롤러
- memberServiceImpl.getUserCoupons(userNo) : 토큰에서 꺼낸 userNo로 해당 사용자의 쿠폰을 조회하는 메서드
- response.put -> 조회된 쿠폰은 coupons이라는 키로 프론트엔드로 전달되며, 성공 여부를 success 값으로 반환한다.
위 로직이 정상적으로 성공을 반환한다면 아래와 같이 쿠폰을 다운 받았을때 mypage의 쿠폰 섹션에 조회가 될 것이다!!

여기까지 mypage의 5가지 섹션을 구현 완료 하였다.