Skip to content
Open
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 @@ -26,9 +26,6 @@ public class Board extends BaseEntity {
@Comment("반려동물 아이디")
private Long dogId;

@Comment("반려인 아이디")
private Long ownerId;

@Comment("반려인 주소 아이디")
private Long ownerAddressId;

Expand Down Expand Up @@ -57,5 +54,18 @@ public class Board extends BaseEntity {
@Enumerated(EnumType.STRING)
private WalkingStatus walkingStatus;

@Builder
public Board (BoardRequestDto boardRequestDto, String content) {
this.dogId = boardRequestDto.getDogId();
this.ownerAddressId = boardRequestDto.getAddressId();
this.content = content;
this.matchingYn = "N";
this.startTime = boardRequestDto.getStartTime();
this.endTime = boardRequestDto.getEndTime();
this.locationNegotiationYn = boardRequestDto.getLocationNegotiationYn();
this.preMeetAvailableYn = boardRequestDto.getPreMeetAvailableYn();
this.walkingStatus = WalkingStatus.BEFORE;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.jullaene.walkmong_back.api.board.dto.req;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.time.LocalDateTime;
import lombok.NoArgsConstructor;

@Getter
@AllArgsConstructor
@NoArgsConstructor
public class BoardRequestDto {
private Long dogId;

private Long addressId;

@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime startTime;

@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime endTime;

private String locationNegotiationYn;

private String preMeetAvailableYn;
}

Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.jullaene.walkmong_back.api.board.dto.res;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.jullaene.walkmong_back.api.dog.domain.enums.DogSize;
import org.jullaene.walkmong_back.common.enums.Gender;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BoardDetailResponseDto {

private Long dogId;
private String dogName;
private String dogProfile;
private Gender dogGender;
private Integer dogAge;
private String breed;
private Double weight;
private DogSize dogSize;
private String dongAddress;
private Double distance;
private String date;
private String startTime;
private String endTime;
private String locationNegotiationYn;
private String preMeetAvailableYn;
private String walkNote;
private String walkRequest;
private String additionalRequest;
private String ownerName;
private Integer ownerAge;
private Gender ownerGender;
private String ownerProfile;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.jullaene.walkmong_back.api.board.dto.res;

import lombok.Builder;
import org.jullaene.walkmong_back.api.dog.domain.enums.DogSize;
import org.jullaene.walkmong_back.common.enums.Gender;

import java.time.LocalDateTime;

public record BoardResponseDto(Long boardId, String startTime, String endTime, String matchingYn,
String dogName, String dogProfile,
Gender dogGender, String breed, Double weight,
DogSize dogSize, String content,
String dongAddress, Double distance, LocalDateTime createdAt) {

@Builder
public BoardResponseDto {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
import org.springframework.stereotype.Repository;

@Repository
public interface BoardRepository extends JpaRepository<Board, Long> {
public interface BoardRepository extends JpaRepository<Board, Long>, BoardRepositoryCustom {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.jullaene.walkmong_back.api.board.repository;

import org.jullaene.walkmong_back.api.board.dto.res.BoardDetailResponseDto;
import org.jullaene.walkmong_back.api.board.dto.res.BoardResponseDto;
import org.jullaene.walkmong_back.api.dog.domain.enums.DogSize;
import org.jullaene.walkmong_back.api.member.domain.Address;
import org.jullaene.walkmong_back.api.member.domain.enums.DistanceRange;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;

public interface BoardRepositoryCustom {
List<BoardResponseDto> getBoardsWithFilters(LocalDate date, Address walkerAddress, DistanceRange distance, DogSize dogSize, String matchingYn);
boolean existsByBoardIdAndMemberIdAndDelYn(Long boardId, Long memberId, String delYn);
Optional<BoardDetailResponseDto> getBoardDetailResponse(Long boardId, Long memberId, String delYn);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
package org.jullaene.walkmong_back.api.board.repository.impl;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Ops;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.NumberTemplate;
import com.querydsl.core.types.dsl.StringTemplate;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.jullaene.walkmong_back.api.board.domain.QBoard;
import org.jullaene.walkmong_back.api.board.dto.res.BoardDetailResponseDto;
import org.jullaene.walkmong_back.api.board.dto.res.BoardResponseDto;
import org.jullaene.walkmong_back.api.board.repository.BoardRepositoryCustom;
import org.jullaene.walkmong_back.api.dog.domain.QDog;
import org.jullaene.walkmong_back.api.dog.domain.enums.DogSize;
import org.jullaene.walkmong_back.api.member.domain.Address;
import org.jullaene.walkmong_back.api.member.domain.QAddress;
import org.jullaene.walkmong_back.api.member.domain.QMember;
import org.jullaene.walkmong_back.api.member.domain.enums.DistanceRange;

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

import static com.querydsl.core.types.dsl.Expressions.numberTemplate;

@Slf4j
public class BoardRepositoryImpl implements BoardRepositoryCustom {

private final JPAQueryFactory queryFactory;

public BoardRepositoryImpl(JPAQueryFactory queryFactory) {
this.queryFactory = queryFactory;
}

@Override
public List<BoardResponseDto> getBoardsWithFilters(LocalDate date, Address walkerAddress, DistanceRange distance, DogSize dogSize, String matchingYn) {
QBoard board = QBoard.board;
QDog dog = QDog.dog;
QAddress ownerAddress = QAddress.address;

BooleanBuilder builder = new BooleanBuilder();

// date가 null이면 당일을 조건에 삽입
if (date == null) {
date = LocalDate.now();
}
LocalDateTime startOfDay = date.atStartOfDay();
LocalDateTime endOfDay = date.atTime(23, 59, 59, 999_999_999);

builder.and(board.startTime.between(startOfDay, endOfDay));

if (dogSize != null) {
builder.and(board.dogId.in(
JPAExpressions.select(dog.dogId)
.from(dog)
.where(dog.dogSize.eq(dogSize))));
}

if (matchingYn != null) {
builder.and(board.matchingYn.eq(matchingYn));
}

if (distance == null) {
distance = walkerAddress.getDistanceRange();
}

// 거리 계산
NumberTemplate<Double> distanceExpression = numberTemplate(
Double.class,
"ST_Distance_Sphere(point({0}, {1}), point({2}, {3}))",
JPAExpressions.select(ownerAddress.longitude)
.from(ownerAddress)
.where(ownerAddress.addressId.eq(board.ownerAddressId)),
JPAExpressions.select(ownerAddress.latitude)
.from(ownerAddress)
.where(ownerAddress.addressId.eq(board.ownerAddressId)),
walkerAddress.getLongitude(),
walkerAddress.getLatitude()
);

BooleanExpression isWithinRange = distanceExpression.lt(distance.getRange());

StringTemplate startTimeExpression = Expressions.stringTemplate(
"DATE_FORMAT({0}, '%H:%i')",
board.startTime
);
StringTemplate endTimeExpression = Expressions.stringTemplate(
"DATE_FORMAT({0}, '%H:%i')",
board.endTime
);


// 필터링된 board들을 바로 결과로 조회
return queryFactory.select(
Projections.constructor(BoardResponseDto.class,
board.boardId.as("boardId"),
startTimeExpression.as("startTime"),
endTimeExpression.as("endTime"),
board.matchingYn.as("matchingYn"),
dog.name.as("dogName"),
dog.profile.as("dogProfile"),
dog.gender.as("dogGender"),
dog.breed.as("breed"),
dog.weight.as("weight"),
dog.dogSize.as("dogSize"),
board.content.as("content"),
ownerAddress.dongAddress.as("dongAddress"),
distanceExpression.as("distance"),
board.createdAt.as("createdAt")
)
)
.from(board)
.leftJoin(dog).on(dog.dogId.eq(board.dogId))
.leftJoin(ownerAddress).on(ownerAddress.addressId.eq(board.ownerAddressId))
.where(builder)
.where(isWithinRange)
.orderBy(board.startTime.asc())
.fetch();
}

/**
* boardId와 memberId를 기준으로 해당 게시글의 작성자인지 확인
* */
@Override
public boolean existsByBoardIdAndMemberIdAndDelYn(Long boardId, Long memberId, String delYn) {
QBoard board = QBoard.board;
QDog dog = QDog.dog;

BooleanBuilder builder = new BooleanBuilder();
builder.and(board.boardId.eq(boardId));
builder.and(board.delYn.eq(delYn));
builder.and(dog.memberId.eq(memberId));

long count = queryFactory
.selectFrom(board)
.join(dog).on(board.dogId.eq(dog.dogId).and(dog.delYn.eq(delYn)))
.where(builder)
.fetch()
.size();

return count > 0;
}


@Override
public Optional<BoardDetailResponseDto> getBoardDetailResponse(Long boardId, Long memberId, String delYn) {
QDog dog= QDog.dog;
QAddress address=QAddress.address;
QBoard board= QBoard.board;
QMember member=QMember.member;
int currentYear = LocalDate.now().getYear() + 1;


StringTemplate startTimeExpression = Expressions.stringTemplate(
"DATE_FORMAT({0}, '%H:%i')",
board.startTime
);
StringTemplate endTimeExpression = Expressions.stringTemplate(
"DATE_FORMAT({0}, '%H:%i')",
board.endTime
);

StringTemplate dateExpression = Expressions.stringTemplate(
"DATE_FORMAT({0}, '%Y-%m-%d')",
board.startTime
);

// 숫자 형식의 생년월일에서 연도 추출 (YYYYMMDD / 10000 = YYYY)
NumberTemplate<Integer> birthYearExpression = Expressions.numberTemplate(Integer.class,
"FLOOR({0} / 10000)",
member.birthDate
);

// // 거리 계산
// NumberTemplate<Double> distanceExpression = numberTemplate(
// Double.class,
// "ST_Distance_Sphere(point({0}, {1}), point({2}, {3}))",
// JPAExpressions.select(ownerAddress.longitude)
// .from(ownerAddress)
// .where(ownerAddress.addressId.eq(board.ownerAddressId)),
// JPAExpressions.select(ownerAddress.latitude)
// .from(ownerAddress)
// .where(ownerAddress.addressId.eq(board.ownerAddressId)),
// walkerAddress.getLongitude(),
// walkerAddress.getLatitude()
// );
double distance = 500;

System.out.println(currentYear);
return
Optional.ofNullable(queryFactory.select(
Projections.constructor(BoardDetailResponseDto.class,
dog.dogId.as("dogId"),
dog.name.as("dogName"),
dog.profile.as("dogProfile"),
dog.gender.as("dogGender"),
Expressions.numberOperation(Integer.class, Ops.SUB,
Expressions.constant(currentYear), dog.birthYear).as("dogAge"),
dog.breed.as("breed"),
dog.weight.as("weight"),
dog.dogSize.as("dogSize"),
address.dongAddress.as("dongAddress"),
Expressions.constant(distance),
dateExpression.as("date"),
startTimeExpression.as("startTime"),
endTimeExpression.as("endTime"),
board.locationNegotiationYn.as("locationNegotiationYn"),
board.preMeetAvailableYn.as("preMeetAvailableYn"),
dog.walkNote.as("walkNote"),
dog.walkRequest.as("walkRequest"),
dog.additionalRequest.as("additionalRequest"),
member.name.as("ownerName"),
Expressions.numberOperation(Integer.class, Ops.SUB,
Expressions.constant(currentYear),
birthYearExpression).as("ownerAge"),
member.gender.as("ownerGender"),
member.profile.as("ownerProfile")

))
.from(board)
.leftJoin(dog).on(dog.dogId.eq(board.dogId))
.leftJoin(member).on(dog.memberId.eq(member.memberId))
.leftJoin(address).on(address.addressId.eq(board.ownerAddressId))
.where(board.boardId.eq(boardId)
.and(board.delYn.eq(delYn)))
.fetchOne());
}
}
Loading