Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor:경기리스트 조회 로직 수정 #111

Merged
merged 1 commit into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public class GameController {
*/
@GetMapping("/list")
public CommonResponse<GameSearchResponse> list(@RequestBody GameSearchRequest gameSearchRequest,
@RequestParam(value = "cursor", required = false) String cursor,
@RequestParam(value = "cursor", required = false) String cursorId,
@RequestParam(value = "limit", defaultValue = "10") int limit) {
GameSearchResponse gameList = gameService.getGameList(gameSearchRequest, cursor, limit);
GameSearchResponse gameList = gameService.getGameList(gameSearchRequest, cursorId, limit);

return new CommonResponse<>(gameList);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.kboticket.controller.game.dto;

import com.kboticket.service.game.dto.GameDetailDto;
import java.time.LocalDate;
import lombok.*;

@Builder
Expand All @@ -12,21 +13,24 @@ public class GameDetailResponse {
private Long id;
private String homeTeam;
private String awayTeam;
private String stadium;
private String gameDate;
private String startTime;
private String stadium;
// 약관, 요일, 팀을 클래스로, boolean 예매 오픈되었는지notnull, false인경우 시간 추가nullable, 딱지 boolean,
private String gameDay;
private String gameStatus; // 경기 상태 (SCHEDULED/OPEN/CLOSE)
private LocalDate openDate; // 티켓 오픈 일자 (경기일 - 7)
private String openTime; // 티켓 오픈 시간 (11:00)

public static GameDetailResponse from (GameDetailDto detailDto) {
public static GameDetailResponse from (GameDetailDto dto) {
return GameDetailResponse.builder()
.homeTeam(detailDto.getHomeTeam())
.awayTeam(detailDto.getAwayTeam())
.gameDate(detailDto.getGameDate())
.startTime(detailDto.getStartTime())
.stadium(detailDto.getStadium())
.homeTeam(dto.getHomeTeam())
.awayTeam(dto.getAwayTeam())
.stadium(dto.getStadium())
.gameDate(dto.getGameDate())
.startTime(dto.getStartTime())
.gameDate(dto.getGameDate())
.gameStatus(dto.getGameStatus())
.openDate(dto.getOpenDate())
.build();
}
}

// 홈팀에 정보가 더 있으면 클래스로 , 홈팀, 이미지 url
// enum 으로 lg
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@
@AllArgsConstructor
public class GameSearchRequest {

private String[] teams;
private String homeTeam;
private String awayTeam;
private String startDate;
private String endDate;
private String team;
private String stadium;
private String month;
private String dayOfMonth;

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@

public interface GameCustomRepository {

List<GameDetailResponse> getByCursor(GameSearchRequest gameSearchRequest, String cursor, int limit);
List<GameDetailResponse> getByCursor(GameSearchRequest gameSearchRequest, String cursorId, int limit);
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
package com.kboticket.repository.game;

import com.kboticket.controller.game.dto.GameDetailResponse;
import com.kboticket.controller.game.dto.GameSearchRequest;
import com.kboticket.domain.Game;
import com.kboticket.domain.QGame;
import com.kboticket.domain.QStadium;
import com.kboticket.domain.QTeam;
import com.kboticket.controller.game.dto.GameSearchRequest;
import com.kboticket.controller.game.dto.GameDetailResponse;
import com.kboticket.enums.ErrorCode;
import com.kboticket.exception.KboTicketException;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.DateTimeTemplate;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

@Slf4j
@Repository
@AllArgsConstructor
public class GameCustomRepositoryImpl implements GameCustomRepository{
Expand All @@ -41,12 +36,11 @@ public class GameCustomRepositoryImpl implements GameCustomRepository{
private static final QStadium stadium = QStadium.stadium;

@Override
public List<GameDetailResponse> getByCursor(GameSearchRequest gameSearchRequest, String cursor, int limit) {

public List<GameDetailResponse> getByCursor(GameSearchRequest gameSearchRequest, String cursorId, int limit) {
BooleanBuilder builder = createSearchBuilder(gameSearchRequest);

if (cursor!= null) {
builder.and(game.id.gt(Long.parseLong(cursor)));
if (cursorId != null) {
builder.and(game.id.gt(Long.parseLong(cursorId)));
}

List<Game> gameList = queryFactory
Expand All @@ -57,98 +51,65 @@ public List<GameDetailResponse> getByCursor(GameSearchRequest gameSearchRequest,
.leftJoin(game.stadium, stadium)
.where(builder)
.orderBy(game.gameDate.asc(), game.id.asc(), homeTeam.name.asc())
.limit(limit + 1)
.limit(limit)
.fetch();

return createResponse(gameList);
}

private List<GameDetailResponse> createResponse(List<Game> gameList) {
List<GameDetailResponse> responseList = gameList.stream()
.map(data -> GameDetailResponse.builder()
.id(data.getId())
.homeTeam(data.getHomeTeam().getId())
.awayTeam(data.getAwayTeam().getId())
.stadium(data.getStadium().getId())
.gameDate(data.getGameDate())
.build())
.map(data -> {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse(data.getGameDate(), formatter);

LocalDate openDate = date.minusDays(7);
LocalDateTime openDateTime = openDate.atTime(11, 00, 00);

String format = openDateTime.getHour() + ":" + String.format("%02d", openDateTime.getMinute());

String dayOfWeek = openDate.getDayOfWeek().toString();

return GameDetailResponse.builder()
.id(data.getId())
.homeTeam(data.getHomeTeam().getId())
.awayTeam(data.getAwayTeam().getId())
.stadium(data.getStadium().getId())
.gameDate(data.getGameDate())
.startTime(data.getStartTime())
.openDate(openDate)
.openTime(format)
.gameStatus("SCHEDULED")
.gameDay(dayOfWeek)
.build();

}
)
.collect(Collectors.toList());

return responseList;
}

private BooleanBuilder createSearchBuilder(GameSearchRequest gameSearchRequest) {
BooleanBuilder builder = new BooleanBuilder();

builder.and(teamsIn(gameSearchRequest.getTeams()))
.and(stadiumEq(gameSearchRequest.getStadium()))
.and(gameDateBetween(gameSearchRequest.getStartDate(), gameSearchRequest.getEndDate())
.and(gameDateInFuture()));
return builder;
}

private Predicate gameDateInFuture() {
LocalDateTime now = LocalDateTime.now();
DateTimeTemplate<LocalDateTime> gameDateAsLocalDateTime = Expressions.dateTimeTemplate(LocalDateTime.class,
"STR_TO_DATE({0}, '%Y.%m.%d')", game.gameDate);
return gameDateAsLocalDateTime.goe(now);
private BooleanBuilder createSearchBuilder(GameSearchRequest request) {
return new BooleanBuilder()
.and(teamsEq(request.getTeam()))
.and(stadiumEq(request.getStadium()))
.and(gameDateFilter(request.getMonth()));
}

private BooleanExpression teamsIn(String[] teams) {
if (teams == null) {
return null;
}
return homeTeam.id.in(teams).or(awayTeam.id.in(teams));
private BooleanExpression teamsEq(String team) {
return team == null ? null : homeTeam.id.eq(team).or(awayTeam.id.eq(team));
}


private BooleanExpression stadiumEq(String stadiumStr) {
return StringUtils.hasText(stadiumStr) ? stadium.id.eq(stadiumStr) : null;
}

private BooleanExpression gameDateBetween(String srchStartDt, String srchEndDt) {
LocalDateTime startDate = null;
LocalDateTime endDate = null;
private BooleanExpression gameDateFilter(String searchMonth) {
LocalDateTime now = LocalDateTime.now();

if (srchStartDt == null) {
// startDate가 null인 경우, 현재 날짜를 시작 날짜로 설정
startDate = now;
} else {
startDate = parseToLocalDateTime(srchStartDt);
if (startDate.isBefore(now)) {
throw new KboTicketException(ErrorCode.INVALID_START_DATE);
}
}
String month = (searchMonth != null) ? searchMonth : String.valueOf(now.getMonthValue());

if (srchEndDt != null) {
endDate = parseToLocalDateTime(srchEndDt);
}

DateTimeTemplate<LocalDateTime> gameDateAsLocalDateTime = Expressions.dateTimeTemplate(LocalDateTime.class,
"STR_TO_DATE({0}, '%Y.%m.%d')", game.gameDate);

if (startDate != null && endDate != null) {
return gameDateAsLocalDateTime.between(startDate, endDate);
} else if (startDate != null) {
return gameDateAsLocalDateTime.goe(startDate);
} else if (endDate != null) {
return gameDateAsLocalDateTime.loe(endDate);
} else {
return null;
}
}

public static LocalDateTime parseToLocalDateTime(String gameDateString) {
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy.MM.dd");
String DateString = gameDateString.split("\\(")[0];

try {
LocalDate localDate = LocalDate.parse(DateString, dateFormatter);
return localDate.atStartOfDay();
} catch (DateTimeParseException e) {
e.printStackTrace();
return null;
}
return game.gameDate.substring(5,7).eq(month);
}
}
26 changes: 6 additions & 20 deletions src/main/java/com/kboticket/service/game/GameService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,39 @@
import com.kboticket.controller.game.dto.GameSearchRequest;
import com.kboticket.controller.game.dto.GameSearchResponse;
import com.kboticket.domain.Game;
import com.kboticket.enums.ErrorCode;
import com.kboticket.exception.KboTicketException;
import com.kboticket.repository.SeatRepository;
import com.kboticket.repository.game.GameRepository;
import com.kboticket.service.game.dto.GameDetailDto;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class GameService {

private final GameRepository gameRepository;
private final SeatRepository seatRepository;

public GameSearchResponse getGameList(GameSearchRequest gameSearchRequest, String cursor, int limit) {
List<GameDetailResponse> games = gameRepository.getByCursor(gameSearchRequest, cursor, limit);
public GameSearchResponse getGameList(GameSearchRequest gameSearchRequest, String cursorId, int limit) {
List<GameDetailResponse> games = gameRepository.getByCursor(gameSearchRequest, cursorId, limit);

boolean hasNext = false;

if (games.size() > limit) {
hasNext = true;
}

GameSearchResponse result = GameSearchResponse.builder()
return GameSearchResponse.builder()
.games(games)
.hasNext(hasNext)
.build();

return result;
}

public GameDetailDto findById(Long gameId) {
Optional<Game> optionalGame = gameRepository.findById(gameId);
Game game = optionalGame.get();

Game game = optionalGame.get();
GameDetailDto gameDetailDto = GameDetailDto.builder()
.id(game.getId())
.homeTeam(game.getHomeTeam().getName())
Expand All @@ -55,10 +47,4 @@ public GameDetailDto findById(Long gameId) {

return gameDetailDto;
}

public Game getGame(Long gameId) {
return gameRepository.findById(gameId).orElseThrow(() -> {
throw new KboTicketException(ErrorCode.NOT_FOUND_GAME);
});
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.kboticket.service.game.dto;

import java.time.LocalDate;
import lombok.Builder;
import lombok.Getter;

Expand All @@ -9,9 +10,10 @@ public class GameDetailDto {
private Long id;
private String homeTeam;
private String awayTeam;
private String stadium;
private String gameDate;
private String startTime;
private String stadium;
private String gameInfo;

private String gameDay;
private String gameStatus; // 경기 상태(SCHEDULED/OPEN/CLOSE)
private LocalDate openDate; // 티켓 오픈 일자 (경기일 - 7)
}
Loading