예약 기능 전체 흐름에 필요한 ReservationController, ReservationService, DTO, 모델, 리포지토리 구조를 포함한 전체 코드 입니다.
프론트엔드에서 JWT 토큰을 헤더로 넘기면 사용자의 이메일을 추출하여 예약을 등록합니다.
✅ ReservationController.java
package com.example.reservation.controller;
import com.example.reservation.dto.ReservationRequest;
import com.example.reservation.dto.ReservationResponse;
import com.example.reservation.service.ReservationService;
import com.example.reservation.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/auth")
@CrossOrigin(origins = "http://localhost:5173")
@RequiredArgsConstructor
public class ReservationController {
private final ReservationService reservationService;
private final JwtUtil jwtUtil;
@PostMapping("/reservations")
public ReservationResponse create(
@RequestBody ReservationRequest request,
@RequestHeader("Authorization") String authHeader
) {
String token = authHeader.replace("Bearer ", "");
String email = jwtUtil.extractUsername(token);
return reservationService.createReservation(email, request);
}
}
✅ ReservationService.java
package com.example.reservation.service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import com.example.reservation.dto.ReservationRequest;
import com.example.reservation.dto.ReservationResponse;
import com.example.reservation.model.Reservation;
import com.example.reservation.model.ReservationStatus;
import com.example.reservation.model.ReservationTimeSlot;
import com.example.reservation.model.User;
import com.example.reservation.repository.ReservationRepository;
import com.example.reservation.repository.UserRepository;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class ReservationService {
private final ReservationRepository reservationRepository;
private final UserRepository userRepository;
@Transactional
public ReservationResponse createReservation(String email, ReservationRequest request) {
User user = userRepository.findByEmail(email).orElseThrow();
Reservation reservation = new Reservation();
reservation.setDate(LocalDate.parse(request.getDate()));
reservation.setUser(user);
reservation.setMemo(request.getMemo());
reservation.setStatus(ReservationStatus.PENDING);
reservation.setCreatedAt(LocalDateTime.now());
List<ReservationTimeSlot> slotEntities = request.getTimeSlots().stream()
.map(ts -> {
ReservationTimeSlot slot = new ReservationTimeSlot();
slot.setTimeSlot(ts);
slot.setReservation(reservation); // 필수
return slot;
}).collect(Collectors.toList());
reservation.setTimeSlots(slotEntities);
Reservation saved = reservationRepository.save(reservation);
return new ReservationResponse(
saved.getId(),
saved.getDate().toString(),
saved.getTimeSlots().stream().map(ReservationTimeSlot::getTimeSlot).toList(),
saved.getMemo(),
saved.getStatus().name(),
saved.getCreatedAt().toString()
);
}
}
✅ ReservationRequest.java
package com.example.reservation.dto;
import lombok.Data;
import java.util.List;
@Data
public class ReservationRequest {
private String date; // "yyyy-MM-dd"
private List<String> timeSlots; // e.g., ["10:00~11:00", "11:00~12:00"]
private String memo;
}
✅ ReservationResponse.java
package com.example.reservation.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
@Data
@AllArgsConstructor
public class ReservationResponse {
private Long id;
private String date;
private List<String> timeSlots;
private String memo;
private String status;
private String createdAt;
}
✅ Reservation.java
package com.example.reservation.model;
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Reservation {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private LocalDate date;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
private String memo;
@Enumerated(EnumType.STRING)
private ReservationStatus status;
private LocalDateTime createdAt;
@OneToMany(mappedBy = "reservation", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ReservationTimeSlot> timeSlots = new ArrayList<>();
}
✅ ReservationTimeSlot.java
package com.example.reservation.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import lombok.*;
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ReservationTimeSlot {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String timeSlot;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "reservation_id")
@JsonIgnore
private Reservation reservation;
public ReservationTimeSlot(Reservation reservation, String timeSlot) {
this.reservation = reservation;
this.timeSlot = timeSlot;
}
}
✅ ReservationStatus.java
package com.example.reservation.model;
public enum ReservationStatus {
PENDING, APPROVED, REJECTED, CANCELLED
}
✅ Repository 인터페이스
ReservationRepository.java
package com.example.reservation.repository;
import com.example.reservation.model.Reservation;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ReservationRepository extends JpaRepository<Reservation, Long> {
// JpaRepository를 상속받으면 save() 등 기본 CRUD 메서드 사용 가능
}
ReservationTimeSlotRepository.java
package com.example.reservation.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.reservation.model.ReservationTimeSlot;
public interface ReservationTimeSlotRepository extends JpaRepository<ReservationTimeSlot, Long> {}
'예약 관리 시스템 - Spring + Vue' 카테고리의 다른 글
예약 관리 시스템 (Spring Boot 3 + Vue 3) - 예약 조회(사용자) (0) | 2025.05.29 |
---|---|
예약 관리 시스템 (Spring Boot 3 + Vue 3) - 예약 관리(관리자) (1) | 2025.05.27 |
예약 관리 시스템 (Spring Boot 3 + Vue 3) - 예약 하기 (프론트엔드) (0) | 2025.05.26 |
예약 관리 시스템 (Spring Boot 3 + Vue 3) - 사용자 인증 프론트엔드 (Vue 3 + Vuetify) (0) | 2025.05.26 |
예약 관리 시스템 (Spring Boot 3 + Vue 3) - 사용자 인증 백엔드 (Spring Security + JWT) (0) | 2025.05.26 |