Skip to content

Commit

Permalink
Merge pull request #11 from ktb-hackerthon/gib/#8
Browse files Browse the repository at this point in the history
✨ 세부 일정 조회를 동적검색 구현
  • Loading branch information
ddangme authored Sep 6, 2024
2 parents db5cc18 + a2c0299 commit 141bb84
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 48 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,6 @@ gradle-app.setting
# Java heap dump
*.hprof

# End of https://www.toptal.com/developers/gitignore/api/intellij+all,java,gradle
# End of https://www.toptal.com/developers/gitignore/api/intellij+all,java,gradle

**/main/generated
20 changes: 20 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,28 @@ dependencies {
// Database
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'

// Querydsl
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta'
annotationProcessor 'jakarta.annotation:jakarta.annotation-api'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api'
}

tasks.named('test') {
useJUnitPlatform()
}

def querydslDir = "src/main/generated"

sourceSets {
main.java.srcDirs += [ querydslDir ]
}

tasks.withType(JavaCompile).configureEach {
options.getGeneratedSourceOutputDirectory().set(file(querydslDir))
}

clean {
delete file(querydslDir)
}
20 changes: 20 additions & 0 deletions src/main/java/com/demo/chattodo/configure/QuerydslConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.demo.chattodo.configure;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.querydsl.jpa.impl.JPAQueryFactory;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;

@Configuration
public class QuerydslConfig {
@PersistenceContext
private EntityManager entityManager;

@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
package com.demo.chattodo.domain.controller;


import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;

import com.demo.chattodo.domain.dto.request.ScheduleUpdateDTO;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.demo.chattodo.domain.dto.request.ScheduleCreateDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


import com.demo.chattodo.domain.dto.request.ScheduleUpdateDTO;
import com.demo.chattodo.domain.dto.response.ScheduleCountResponseDTO;
import com.demo.chattodo.domain.dto.response.ScheduleInfoResponseDTO;
import com.demo.chattodo.domain.service.ScheduleService;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
Expand All @@ -29,28 +33,19 @@
public class ScheduleController {
private final ScheduleService scheduleService;


@GetMapping
public List<ScheduleCountResponseDTO> countScheduleOfEachDay(
@RequestHeader("member_id")String memberId,
@RequestParam("start_date") LocalDate startDate,
@RequestParam("end_date")LocalDate endDate) {
@RequestHeader("member_id") String memberId,
@RequestParam("start_date") LocalDate startDate,
@RequestParam("end_date") LocalDate endDate) {

return scheduleService.countScheduleOfEachDay(memberId, startDate, endDate);
}

@PostMapping
public ResponseEntity<?> createSchedule(
@RequestHeader("member_id") String memberId,
@RequestBody ScheduleCreateDTO dto) {

return ResponseEntity.ok().body(scheduleService.saveSchedule(memberId, dto));
}

@DeleteMapping("/{scheduleId}")
public ResponseEntity<?> deleteSchedule(
@RequestHeader("member_id") String memberId,
@PathVariable Long scheduleId) {
@RequestHeader("member_id") String memberId,
@PathVariable Long scheduleId) {

if (scheduleService.deleteSchedule(memberId, scheduleId)) {
return ResponseEntity.ok().build();
Expand All @@ -61,11 +56,49 @@ public ResponseEntity<?> deleteSchedule(

@PutMapping("/{scheduleId}")
public ResponseEntity<?> updateSchedule(
@RequestHeader("member_id") String memberId,
@PathVariable Long scheduleId,
@RequestBody ScheduleUpdateDTO dto) {
@RequestHeader("member_id") String memberId,
@PathVariable Long scheduleId,
@RequestBody ScheduleUpdateDTO dto) {

scheduleService.updateSchedule(memberId, scheduleId, dto);
return ResponseEntity.ok().build();
}

@PostMapping
public ResponseEntity<?> createSchedule(
@RequestHeader("member_id") String memberId,
@RequestBody ScheduleCreateDTO dto) {

return ResponseEntity.ok().body(scheduleService.saveSchedule(memberId, dto));
}

@GetMapping("/search")
public List<ScheduleInfoResponseDTO> searchAllByConditions(
@RequestHeader("member_id") String memberId,
@RequestParam(value = "start_date", required = false) LocalDate startDate,
@RequestParam(value = "start_time", required = false) LocalTime startTime,
@RequestParam(value = "end_date", required = false) LocalDate endDate,
@RequestParam(value = "end_time", required = false) LocalTime endTime,
@RequestParam(value = "title", required = false) String title,
@RequestParam(value = "place", required = false) String place) {

LocalDateTime startDateTime = null;

if (startDate != null) {
startDateTime = LocalDateTime.of(startDate, LocalTime.MIN);
if (startTime != null) {
startDateTime = LocalDateTime.of(startDate, startTime);
}
}

LocalDateTime endDateTime = null;
if (endDate != null) {
endDateTime = LocalDateTime.of(endDate, LocalTime.MAX);
if (endTime != null) {
endDateTime = LocalDateTime.of(endDate, endTime);
}
}

return scheduleService.searchAllByConditions(memberId, startDateTime, endDateTime, title, place);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.demo.chattodo.domain.dto.response;

import java.time.LocalDateTime;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class ScheduleInfoResponseDTO {
private Long id;
private String title;
private LocalDateTime startDateTime;
private LocalDateTime endDateTime;
private String place;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import com.demo.chattodo.domain.entity.Schedule;

public interface ScheduleRepository extends JpaRepository<Schedule, Long> {
public interface ScheduleRepository extends JpaRepository<Schedule, Long>, ScheduleRepositoryCustom {
// 유저의 일정기간내 모든 일정 가져오기
@Query("SELECT s FROM Schedule s WHERE s.memberId = :memberId AND s.startDateTime >= :startDate AND s.endDateTime < :endDate")
List<Schedule> findAllByDateRangeAndMemberId(@Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate, @Param("memberId") String memberId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.demo.chattodo.domain.repository;

import java.time.LocalDateTime;
import java.util.List;

import com.demo.chattodo.domain.entity.Schedule;

public interface ScheduleRepositoryCustom {
// 여러 조건들을 통해 일정 가져오기
List<Schedule> searchAllByConditions(String memberId, LocalDateTime startDateTime, LocalDateTime endDateTime,
String title, String place);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.demo.chattodo.domain.repository;

import java.time.LocalDateTime;
import java.util.List;

import org.springframework.stereotype.Repository;

import com.demo.chattodo.domain.entity.QSchedule;
import com.demo.chattodo.domain.entity.Schedule;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;

import lombok.RequiredArgsConstructor;

@Repository
@RequiredArgsConstructor
public class ScheduleRepositoryImpl implements ScheduleRepositoryCustom {
private final JPAQueryFactory queryFactory;

// 여러 조건들을 통해 일정 가져오기
@Override
public List<Schedule> searchAllByConditions(String memberId, LocalDateTime startDateTime, LocalDateTime endDateTime,
String title,
String place) {
QSchedule schedule = QSchedule.schedule;

BooleanBuilder builder = new BooleanBuilder();

// 멤버 ID는 필수 조건
builder.and(schedule.memberId.eq(memberId));

// 시작일시 조건
if (startDateTime != null) {
builder.and(schedule.startDateTime.goe(startDateTime));
}

// 종료일시 조건
if (endDateTime != null) {
builder.and(schedule.endDateTime.loe(endDateTime));
}

// 제목 조건 (부분 일치)
if (title != null && !title.isEmpty()) {
builder.and(schedule.title.containsIgnoreCase(title));
}

// 장소 조건 (부분 일치)
if (place != null && !place.isEmpty()) {
builder.and(schedule.place.containsIgnoreCase(place));
}

return queryFactory
.selectFrom(schedule)
.where(builder)
.orderBy(schedule.startDateTime.asc())
.fetch();
}
}
61 changes: 41 additions & 20 deletions src/main/java/com/demo/chattodo/domain/service/ScheduleService.java
Original file line number Diff line number Diff line change
@@ -1,37 +1,33 @@
package com.demo.chattodo.domain.service;


import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;


import com.demo.chattodo.domain.dto.request.ScheduleCreateDTO;
import com.demo.chattodo.domain.dto.request.ScheduleUpdateDTO;
import com.demo.chattodo.domain.entity.Schedule;
import com.demo.chattodo.domain.utils.DateTimeUtil;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.demo.chattodo.domain.dto.request.ScheduleCreateDTO;
import com.demo.chattodo.domain.dto.request.ScheduleUpdateDTO;
import com.demo.chattodo.domain.dto.response.ScheduleCountResponseDTO;
import com.demo.chattodo.domain.dto.response.ScheduleInfoResponseDTO;
import com.demo.chattodo.domain.entity.Schedule;
import com.demo.chattodo.domain.repository.ScheduleRepository;
import com.demo.chattodo.domain.utils.DateTimeUtil;

import lombok.RequiredArgsConstructor;



@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class ScheduleService {
private final ScheduleRepository scheduleRepository;


public List<ScheduleCountResponseDTO> countScheduleOfEachDay(String memberId, LocalDate startDate, LocalDate endDate) {
public List<ScheduleCountResponseDTO> countScheduleOfEachDay(String memberId, LocalDate startDate,
LocalDate endDate) {
List<Schedule> schedules = scheduleRepository.findAllByDateRangeAndMemberId(
LocalDateTime.of(startDate, LocalTime.MIN),
LocalDateTime.of(endDate, LocalTime.MIN).plusDays(1),
Expand Down Expand Up @@ -63,11 +59,11 @@ public List<ScheduleCountResponseDTO> countScheduleOfEachDay(String memberId, Lo
public Long saveSchedule(String memberId, ScheduleCreateDTO dto) {

Schedule schedule = new Schedule(
memberId,
dto.getTitle(),
DateTimeUtil.getStartLocalDateTime(dto.getStartDate(), dto.getStartTime()),
DateTimeUtil.getEndLocalDateTime(dto.getEndDate(), dto.getEndTime()),
dto.getPlace()
memberId,
dto.getTitle(),
DateTimeUtil.getStartLocalDateTime(dto.getStartDate(), dto.getStartTime()),
DateTimeUtil.getEndLocalDateTime(dto.getEndDate(), dto.getEndTime()),
dto.getPlace()
);

scheduleRepository.save(schedule);
Expand All @@ -90,9 +86,34 @@ public boolean deleteSchedule(String memberId, Long scheduleId) {
@Transactional
public void updateSchedule(String memberId, Long scheduleId, ScheduleUpdateDTO dto) {
scheduleRepository.findByIdAndMemberId(scheduleId, memberId)
.ifPresent(schedule -> schedule.update(dto.getTitle(),
DateTimeUtil.getStartLocalDateTime(dto.getStartDate(), dto.getStartTime()),
DateTimeUtil.getEndLocalDateTime(dto.getEndDate(), dto.getEndTime()),
dto.getPlace()));
.ifPresent(schedule -> schedule.update(dto.getTitle(),
DateTimeUtil.getStartLocalDateTime(dto.getStartDate(), dto.getStartTime()),
DateTimeUtil.getEndLocalDateTime(dto.getEndDate(), dto.getEndTime()),
dto.getPlace()));
}

public List<ScheduleInfoResponseDTO> searchAllByConditions(String memberId, LocalDateTime startDateTime,
LocalDateTime endDateTime, String title, String place) {
List<Schedule> schedules = scheduleRepository.searchAllByConditions(
memberId,
startDateTime,
endDateTime,
title,
place
);

List<ScheduleInfoResponseDTO> response = new ArrayList<>();
for (Schedule schedule : schedules) {
response.add(ScheduleInfoResponseDTO.builder()
.id(schedule.getId())
.title(schedule.getTitle())
.startDateTime(schedule.getStartDateTime())
.endDateTime(schedule.getEndDateTime())
.place(schedule.getPlace())
.build());
}

return response;
}

}
Loading

0 comments on commit 141bb84

Please sign in to comment.