1+ package hackathon .soa .domain .segment ;
2+
3+ import hackathon .soa .common .apiPayload .code .status .ErrorStatus ;
4+ import hackathon .soa .common .apiPayload .exception .CourseHandler ;
5+ import hackathon .soa .common .apiPayload .exception .SegmentHandler ;
6+ import hackathon .soa .domain .course .CourseRepository ;
7+ import hackathon .soa .domain .segment .dto .SegmentResponseDTO ;
8+ import hackathon .soa .domain .segment .repository .CourseSegmentRepository ;
9+ import hackathon .soa .domain .segment .repository .MoveSegmentRepository ;
10+ import hackathon .soa .domain .segment .repository .StaySegmentRepository ;
11+ import hackathon .soa .entity .Course ;
12+ import hackathon .soa .entity .CourseSegment ;
13+ import hackathon .soa .entity .MoveSegment ;
14+ import hackathon .soa .entity .StaySegment ;
15+ import lombok .RequiredArgsConstructor ;
16+ import lombok .extern .slf4j .Slf4j ;
17+ import org .springframework .stereotype .Service ;
18+ import org .springframework .transaction .annotation .Transactional ;
19+
20+ import java .time .format .DateTimeFormatter ;
21+ import java .util .List ;
22+ import java .util .Locale ;
23+ import java .util .Optional ;
24+ import java .util .stream .Collectors ;
25+
26+ @ Service
27+ @ RequiredArgsConstructor
28+ @ Transactional (readOnly = true )
29+ @ Slf4j
30+ public class SegmentService {
31+
32+ private final CourseSegmentRepository courseSegmentRepository ;
33+ private final StaySegmentRepository staySegmentRepository ;
34+ private final MoveSegmentRepository moveSegmentRepository ;
35+ private final CourseRepository courseRepository ;
36+
37+ public SegmentResponseDTO .CourseDetailResponseDTO getCourseDetail (Long courseId , Long memberId ) {
38+ // 1. 코스 조회 및 작성자 확인
39+ Course course = courseRepository .findById (courseId )
40+ .orElseThrow (() -> new CourseHandler (ErrorStatus .NOT_FOUND_COURSE ));
41+
42+ boolean isOwner = course .getMember ().getId ().equals (memberId );
43+
44+ // 2. 코스 세그먼트들을 순서대로 조회
45+ List <CourseSegment > courseSegments = courseSegmentRepository .findByCourse_IdOrderBySegmentOrder (courseId );
46+
47+ if (courseSegments .isEmpty ()) {
48+ throw new CourseHandler (ErrorStatus .NOT_FOUND_COURSE );
49+ }
50+
51+ // 3. 각 세그먼트 정보를 조회하여 DTO 생성
52+ List <SegmentResponseDTO .SegmentDetailDTO > segmentDetails = courseSegments .stream ()
53+ .map (this ::buildSegmentDetail )
54+ .collect (Collectors .toList ());
55+
56+ return SegmentResponseDTO .CourseDetailResponseDTO .builder ()
57+ .courseId (courseId )
58+ .isOwner (isOwner )
59+ .segments (segmentDetails )
60+ .build ();
61+ }
62+
63+ private SegmentResponseDTO .SegmentDetailDTO buildSegmentDetail (CourseSegment courseSegment ) {
64+ Long segmentId = courseSegment .getId ();
65+
66+ // 시간 포맷터 정의
67+ DateTimeFormatter dateFormatter = DateTimeFormatter .ofPattern ("MM/dd(E)" , Locale .KOREAN );
68+ DateTimeFormatter timeFormatter = DateTimeFormatter .ofPattern ("HH:mm" );
69+
70+ try {
71+ // 장소 세그먼트 먼저 확인 (@MapsId로 PK가 동일함)
72+ Optional <StaySegment > staySegment = staySegmentRepository .findById (segmentId );
73+ if (staySegment .isPresent ()) {
74+ return SegmentResponseDTO .SegmentDetailDTO .builder ()
75+ .segmentOrder (courseSegment .getSegmentOrder ())
76+ .segmentType ("장소" )
77+ .date (courseSegment .getStartTime ().format (dateFormatter ))
78+ .startTime (courseSegment .getStartTime ().format (timeFormatter ))
79+ .endTime (courseSegment .getEndTime ().format (timeFormatter ))
80+ .staySegment (SegmentResponseDTO .StaySegmentDTO .from (staySegment .get ()))
81+ .moveSegment (null )
82+ .build ();
83+ }
84+
85+ // 이동 세그먼트 확인 (@MapsId로 PK가 동일함)
86+ Optional <MoveSegment > moveSegment = moveSegmentRepository .findById (segmentId );
87+ if (moveSegment .isPresent ()) {
88+ return SegmentResponseDTO .SegmentDetailDTO .builder ()
89+ .segmentOrder (courseSegment .getSegmentOrder ())
90+ .segmentType ("이동" )
91+ .date (courseSegment .getStartTime ().format (dateFormatter ))
92+ .startTime (courseSegment .getStartTime ().format (timeFormatter ))
93+ .endTime (courseSegment .getEndTime ().format (timeFormatter ))
94+ .staySegment (null )
95+ .moveSegment (SegmentResponseDTO .MoveSegmentDTO .from (moveSegment .get ()))
96+ .build ();
97+ }
98+
99+ throw new SegmentHandler (ErrorStatus .SEGMENT_NOT_FOUND );
100+
101+ } catch (Exception e ) {
102+ log .error ("Error while building segment detail for segmentId: {}" , segmentId , e );
103+ throw new SegmentHandler (ErrorStatus .SEGMENT_DESERIALIZATION_ERROR );
104+ }
105+ }
106+ }
0 commit comments