-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[FEAT] 일정 리스트 조회 기능
- Loading branch information
Showing
9 changed files
with
260 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
src/main/java/org/sopt/makers/operation/controller/app/AppScheduleController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package org.sopt.makers.operation.controller.app; | ||
|
||
import io.swagger.annotations.ApiOperation; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.val; | ||
import org.sopt.makers.operation.common.ApiResponse; | ||
import org.sopt.makers.operation.service.ScheduleService; | ||
import org.springframework.format.annotation.DateTimeFormat; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
import static org.sopt.makers.operation.common.ApiResponse.success; | ||
import static org.sopt.makers.operation.common.ResponseMessage.*; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("/api/v1/app/schedules") | ||
public class AppScheduleController { | ||
private final ScheduleService scheduleService; | ||
|
||
@ApiOperation("일정 리스트 조회") | ||
@GetMapping | ||
public ResponseEntity<ApiResponse> getAlarms( | ||
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime start, | ||
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime end | ||
) { | ||
val response = scheduleService.getSchedules(start, end); | ||
return ResponseEntity.ok(success(SUCCESS_GET_SCHEDULES.getMessage(), response)); | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
src/main/java/org/sopt/makers/operation/dto/schedule/SchedulesResponseDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package org.sopt.makers.operation.dto.schedule; | ||
|
||
import lombok.*; | ||
import org.sopt.makers.operation.entity.lecture.Attribute; | ||
import org.sopt.makers.operation.entity.schedule.Schedule; | ||
|
||
import java.time.LocalDate; | ||
import java.time.format.TextStyle; | ||
import java.util.List; | ||
import java.util.Locale; | ||
import java.util.Map; | ||
|
||
public record SchedulesResponseDTO( | ||
List<DateVO> dates | ||
) { | ||
public static SchedulesResponseDTO of(Map<LocalDate, List<Schedule>> scheduleMap) { | ||
return new SchedulesResponseDTO( | ||
scheduleMap.keySet().stream().sorted() | ||
.map(key -> DateVO.of(key, scheduleMap.get(key))) | ||
.toList() | ||
); | ||
} | ||
|
||
@Builder | ||
record DateVO( | ||
String date, | ||
String dayOfWeek, | ||
List<ScheduleVO> schedules | ||
) { | ||
static DateVO of(LocalDate date, List<Schedule> schedules) { | ||
return DateVO.builder() | ||
.date(date.toString()) | ||
.dayOfWeek(date.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.KOREAN)) | ||
.schedules(schedules.stream().map(ScheduleVO::of).toList()) | ||
.build(); | ||
} | ||
} | ||
|
||
@Builder | ||
record ScheduleVO( | ||
Long scheduleId, | ||
String startDate, | ||
String endDate, | ||
Attribute attribute, | ||
String title | ||
) { | ||
static ScheduleVO of(Schedule schedule) { | ||
return ScheduleVO.builder() | ||
.scheduleId(schedule.getId()) | ||
.startDate(schedule.getStartDate().toString()) | ||
.endDate(schedule.getEndDate().toString()) | ||
.attribute(schedule.getAttribute()) | ||
.title(schedule.getTitle()) | ||
.build(); | ||
} | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
src/main/java/org/sopt/makers/operation/entity/schedule/Schedule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package org.sopt.makers.operation.entity.schedule; | ||
|
||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import org.sopt.makers.operation.entity.BaseEntity; | ||
import org.sopt.makers.operation.entity.lecture.Attribute; | ||
|
||
import javax.persistence.*; | ||
import java.time.LocalDateTime; | ||
|
||
import static javax.persistence.EnumType.STRING; | ||
import static javax.persistence.GenerationType.IDENTITY; | ||
|
||
@Entity | ||
@NoArgsConstructor | ||
@Getter | ||
public class Schedule extends BaseEntity { | ||
@Id | ||
@GeneratedValue(strategy = IDENTITY) | ||
@Column(name = "schedule_id") | ||
private Long id; | ||
|
||
private LocalDateTime startDate; | ||
|
||
private LocalDateTime endDate; | ||
|
||
@Column(nullable = false) | ||
@Enumerated(value = STRING) | ||
private Attribute attribute; | ||
|
||
private String title; | ||
|
||
private String location; | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/org/sopt/makers/operation/repository/schedule/ScheduleCustomRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package org.sopt.makers.operation.repository.schedule; | ||
|
||
import org.sopt.makers.operation.entity.schedule.Schedule; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
|
||
public interface ScheduleCustomRepository { | ||
List<Schedule> findBetweenStartAndEnd(LocalDateTime start, LocalDateTime end); | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/java/org/sopt/makers/operation/repository/schedule/ScheduleRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package org.sopt.makers.operation.repository.schedule; | ||
|
||
import org.sopt.makers.operation.entity.Member; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface ScheduleRepository extends JpaRepository<Member, Long>, ScheduleCustomRepository { | ||
} |
34 changes: 34 additions & 0 deletions
34
src/main/java/org/sopt/makers/operation/repository/schedule/ScheduleRepositoryImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package org.sopt.makers.operation.repository.schedule; | ||
|
||
import com.querydsl.core.types.dsl.BooleanExpression; | ||
import com.querydsl.jpa.impl.JPAQueryFactory; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
import org.sopt.makers.operation.entity.schedule.Schedule; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
|
||
import static org.sopt.makers.operation.entity.schedule.QSchedule.schedule; | ||
|
||
@Repository | ||
@RequiredArgsConstructor | ||
public class ScheduleRepositoryImpl implements ScheduleCustomRepository { | ||
|
||
private final JPAQueryFactory queryFactory; | ||
|
||
@Override | ||
public List<Schedule> findBetweenStartAndEnd(LocalDateTime start, LocalDateTime end) { | ||
return queryFactory | ||
.select(schedule) | ||
.from(schedule) | ||
.where( | ||
schedule.startDate.between(start, end) | ||
.or(schedule.endDate.between(start, end)) | ||
) | ||
.orderBy(schedule.startDate.asc()) | ||
.fetch(); | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/org/sopt/makers/operation/service/ScheduleService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package org.sopt.makers.operation.service; | ||
|
||
import org.sopt.makers.operation.dto.schedule.SchedulesResponseDTO; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
public interface ScheduleService { | ||
SchedulesResponseDTO getSchedules(LocalDateTime start, LocalDateTime end); | ||
} |
73 changes: 73 additions & 0 deletions
73
src/main/java/org/sopt/makers/operation/service/ScheduleServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package org.sopt.makers.operation.service; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.val; | ||
import org.sopt.makers.operation.dto.schedule.SchedulesResponseDTO; | ||
import org.sopt.makers.operation.entity.schedule.Schedule; | ||
import org.sopt.makers.operation.repository.schedule.ScheduleRepository; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.time.Duration; | ||
import java.time.LocalDate; | ||
import java.time.LocalDateTime; | ||
import java.time.temporal.ChronoUnit; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.LongStream; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class ScheduleServiceImpl implements ScheduleService { | ||
private final ScheduleRepository scheduleRepository; | ||
|
||
@Override | ||
public SchedulesResponseDTO getSchedules(LocalDateTime start, LocalDateTime end) { | ||
val schedules = scheduleRepository.findBetweenStartAndEnd(start, end); | ||
val scheduleMap = classifiedByDate(schedules, start, end); | ||
return SchedulesResponseDTO.of(scheduleMap); | ||
} | ||
|
||
private Map<LocalDate, List<Schedule>> classifiedByDate(List<Schedule> schedules, LocalDateTime startAt, LocalDateTime endAt) { | ||
val scheduleMap = initScheduleMap(startAt, endAt); | ||
schedules.forEach(schedule -> putScheduleMap(scheduleMap, schedule)); | ||
return scheduleMap; | ||
} | ||
|
||
private Map<LocalDate, List<Schedule>> initScheduleMap(LocalDateTime startAt, LocalDateTime endAt) { | ||
//TODO: 클라이언트 개발 시간 리소스 절약을 위해 해당 메소드 활용, 가능한 일정이 존재하는 날짜만 key로 가지는 HashMap로 변경 요망 | ||
val duration = Duration.between(startAt, endAt).toDays() + 1; | ||
validDuration(duration); | ||
return LongStream.range(0, duration) | ||
.mapToObj(startAt::plusDays) | ||
.collect(Collectors.toMap( | ||
LocalDateTime::toLocalDate, | ||
date -> new ArrayList<>())); | ||
} | ||
|
||
private void validDuration(long duration) { | ||
//TODO: 추후 응답 값 형식 변경 후 삭제될 수 있는 메소드 | ||
if (duration > 50) { | ||
throw new IllegalStateException("조회할 날짜 기간은 50일을 넘길 수 없습니다."); | ||
} | ||
} | ||
|
||
private void putScheduleMap(Map<LocalDate, List<Schedule>> scheduleMap, Schedule schedule) { | ||
val duration = ChronoUnit.DAYS.between(schedule.getStartDate(), schedule.getEndDate()); | ||
scheduleMap.computeIfAbsent(schedule.getStartDate().toLocalDate(), k -> new ArrayList<>()).add(schedule); | ||
if (duration >= 1) { | ||
scheduleMap.computeIfAbsent(schedule.getEndDate().toLocalDate(), k -> new ArrayList<>()).add(schedule); | ||
if (duration >= 2) { | ||
putScheduleMapBetween(scheduleMap, schedule, (int)duration); | ||
} | ||
} | ||
} | ||
|
||
private void putScheduleMapBetween(Map<LocalDate, List<Schedule>> scheduleMap, Schedule schedule, int duration) { | ||
for (int i = 1; i < duration; i++) { | ||
val date = schedule.getStartDate().plusDays(i).toLocalDate(); | ||
scheduleMap.computeIfAbsent(date, k -> new ArrayList<>()).add(schedule); | ||
} | ||
} | ||
} |