예약을 위해 시작/종료 일자, 예약자, 지점명/사이즈는 3가지 옵션 중에서 선택하면 기간과 사이즈 별 이용요금이 계산되어 예약이 가능하다.
성공적으로 예약되면 성공 메시지와 함께 예약 내역이 뜨고 마이페이지에서도 조회와 취소를 할 수 있다.
✂️예약 전
✂️예약 후
db에 저장이 된 것을 볼 수 있다.
예약 내역 조회와 취소는 마이페이지에서 다룰 예정❗
private int bookingId;
private String userId;
private String bookDateS;
private String bookDateE;
private String name;
private String city;
private String size;
private String price;
📕sql
create sequence box_booking_seq;
예약아이디 시퀀스를 만들어 주었다.
게시판의 글 번호처럼 예약 아이디는 int형, 사용자 아이디, 시작/종료 날짜, 이름, 지점, 사이즈, 가격 dto와 sql을 작성한다.
<form action="${contextPath }/booking/bookingDo" method="post" class="cf" name="select">
<input type="hidden" name="userId" id="userId" value="${successLoginUser }">
<label for="start-day">시작일자</label>
<input type="date" name="bookDateS" id="start-day" class="start-date" onchange="checkPrice()">
<label for="end-day">종료일자</label>
<input type="date" name="bookDateE" id="end-day" class="end-date"
onchange="checkPrice()">
<label for="bookingName">예약자</label>
<input type="text" name="name" id="book-name" required="required">
<label for="stringcity">지점명</label>
<select name="city" id="stringcity">
<option value="">선택하세요</option>
<option value="서울">서울 광화문점</option>
<option value="분당">분당 판교점</option>
<option value="부천">부천 소사점</option>
</select>
<label for="stringsize">사이즈</label>
<select name="size" id="stringsize" onchange="checkPrice()">
<option value="0">선택하세요</option>
<option value="5000">소 ( 20 x 20 x 45(cm) 이내 )</option>
<option value="6000">중 (30 x 30 x 60(cm) 이내)</option>
<option value="7000">대 (50 x 50 x 80(cm) 이내)</option>
</select>
<label for="intmoney">이용요금</label>
<input type="text" name="price" id="intmoney" readonly>
<button type="submit" id="next-btn" onclick="insertOpt()">예약하기</button>
</form>
해당 아이디로 예약을 해야하기 때문에 세션아이디를 input type="hidden"
으로 숨겨서 넘긴다.
지점과 사이즈는 select와 option
을 사용해 선택할 수 있도록 했고 모든 항목을 선택하면 checkPrice()
함수가 실행되 계산이 된다.
예약하기 버튼을 클릭하면 폼은 post방식으로 해당 컨트롤러로 연결한다.
//일자
let nowUtc = Date.now();
let timeOff = new Date().getTimezoneOffset() * 60000;
let today = new Date(nowUtc - timeOff).toISOString().split("T")[0];
document.getElementById("start-day").setAttribute("min", today);
document.getElementById("end-day").setAttribute("min", today);
// 사이즈, 날짜별 요금 계산
const intMoney = document.getElementById("intmoney");
const stringSize = document.getElementById("stringsize");
function checkPrice() {
const startDay = document.getElementById("start-day").value;
const endDay = document.getElementById("end-day").value;
const ar1 = startDay.split("-");
const ar2 = endDay.split("-");
const da1 = new Date(ar1[0], ar1[1], ar1[2]);
const da2 = new Date(ar2[0], ar2[1], ar2[2]);
const dateDiff = Math.abs((da2 - da1) / (24 * 60 * 60 * 1000));
if(startDay && endDay) {
intMoney.value = ((dateDiff * 2) * stringSize.value).toLocaleString() +'원';
}
if(startDay && endDay && dateDiff == 0) {
intMoney.value = (stringSize.value).toLocaleString() +'원';
}
}
시작/종료 일자는 캘린더를 클릭했을 때 시작일자에서 오늘 이전으로 선택되지 않도록 했다.
요금은 사이즈, 날짜별로 계산이 되도록 했다.
@PostMapping("bookingDo")
public String bookingDo( HttpSession session, bookingDTO bookingDto) {
bs.bookingDo(bookingDto);
return "redirect:bookingInfo";
}
예약하기 폼은 해당 컨트롤러로 연결되고 세션과 dto를 받는다.
사용자가 선택한 값들을 service로 연결하고 예약 정보 페이지를 보여준다.
public void bookingDo(bookingDTO bookingDto );
public void bookingDo(bookingDTO bookingDto ) {
try {
bMapper.bookingDo(bookingDto);
} catch (Exception e) {
e.printStackTrace();
}
}
오류 예외 처리를 하고 mapper로 보낸다.
public void bookingDo(bookingDTO bookingDto );
<insert id="bookingDo">
insert into box_booking(
booking_id,buser_id,booking_date_start, booking_date_end,
booking_name,
booking_city,booking_size,booking_price)
values(box_booking_seq.nextval,#{userId},#{bookDateS}, #{bookDateE},
#{name},#{city},#{size},#{price})
</insert>