Skip to content

Commit

Permalink
Merge pull request #15 from T1F5/feature/#14
Browse files Browse the repository at this point in the history
Feature/#14
  • Loading branch information
Beakjiyeon authored Apr 6, 2024
2 parents 2f8ca8c + 0b839bf commit 230586f
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 16 deletions.
2 changes: 2 additions & 0 deletions src/main/java/com/unit/daybook/DaybookApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
@EnableJpaAuditing
@SpringBootApplication
public class DaybookApplication {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,21 @@ public AddBoardResponseDto getBoard(@PathVariable("boardId") Long boardId) {
return boardService.getBoard(boardId);
}

/**
* 사용자가 작성한 일지 목록 조회
*/
@GetMapping("/boards")
public List<AddBoardResponseDto> getMyBoards() {
// 사용자가 작성한 일지 목록 조회
Long memberId = 1L; // TODO 인증
return boardService.getMyBoards(memberId);
}

// TODO 사용자가 보지 않은 글 중에서 랜덤 3개 골라 주기
/**
* 사용자가 보지 않은 글 중에서 랜덤 3개 골라 주기
* 밤 12시에 적재된 사용자가 읽지 않은 글을 조회
*/
@GetMapping("/random")
public List<AddBoardResponseDto> getRandomBoards() {
// 사용자가 작성한 일지 목록 조회
// TODO api 호출 시점마다 랜덤x. 12시에 사용자가 읽지 않은 글을 today_user_table에 저장한다. 전날 건 삭제
// todo api는 today_user_table 에 있는 정보를 read. 계산 x
Long memberId = 1L; // TODO 인증
return boardService.getRandomBoards(memberId);
}
Expand All @@ -41,7 +43,6 @@ public List<AddBoardResponseDto> getRandomBoards() {
public AddBoardResponseDto addBoard(@RequestBody AddBoardRequestDto addBoardRequestDto) {
Long memberId = 1L; // TODO 인증
return boardService.addBoard(addBoardRequestDto, memberId);

}

@PostMapping("/{boardId}")
Expand All @@ -53,4 +54,5 @@ public String modifyBoard(@PathVariable("boardId") Long boardId) {
public String deleteBoard(@PathVariable("boardId") Long boardId) {
return "삭제 성공";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public static Board createBoard(AddBoardRequestDto addBoardRequestDto, Member me
.respectBoardId(addBoardRequestDto.respectBoardId())
.member(member)
.category(addBoardRequestDto.category())
.hearts(0L) // todo
.hearts(0L)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package com.unit.daybook.domain.board.entity;

import com.unit.daybook.domain.board.dto.request.AddBoardRequestDto;
import com.unit.daybook.domain.common.model.BaseTimeEntity;
import com.unit.daybook.domain.member.domain.Member;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Entity
@Table(name = "read_board")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
class ReadBoard extends BaseTimeEntity {
public class ReadBoard extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -26,4 +28,17 @@ class ReadBoard extends BaseTimeEntity {
@JoinColumn(name = "board_id")
private Board board;

@Builder(access = AccessLevel.PRIVATE)
public ReadBoard(Member member, Board board) {
this.member = member;
this.board = board;
}

public static ReadBoard createReadBoard(Member member, Board board) {
return ReadBoard.builder()
.member(member)
.board(board)
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import com.querydsl.jpa.impl.JPAQueryFactory;
import com.unit.daybook.domain.board.entity.Board;
import com.unit.daybook.domain.board.entity.QBoard;
import com.unit.daybook.domain.member.domain.QMember;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

Expand All @@ -14,12 +12,12 @@

@Repository
@RequiredArgsConstructor
public class BoardRepositoryImpl implements BoardRepositoryCustom {
public class BoardRepositoryImpl implements BoardRepositoryCustom {
private final JPAQueryFactory queryFactory;

public List<Board> findBoardsByMemberId(Long memberId) {

List<Board> boards = queryFactory
return queryFactory
.select(board)
.from(board)
.join(board.memeber, member).fetchJoin()
Expand All @@ -28,6 +26,29 @@ public List<Board> findBoardsByMemberId(Long memberId) {
)
.fetch();

return boards;
}

public List<Board> findNotReadBoardsByMemberId(Long memberId, List<Long> aleadyReadBoardIds) {
return queryFactory
.select(board)
.from(board)
.join(board.memeber, member).fetchJoin()
.where(
member.id.eq(memberId)
.and(board.boardId.notIn(aleadyReadBoardIds))
)
.fetch();

}

public List<Board> findBoardInBoardIds(List<Long> todayBoards) {
return queryFactory
.select(board)
.from(board)
.where(
board.boardId.in(todayBoards)
)
.fetch();

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.unit.daybook.domain.board.repository;

import com.unit.daybook.domain.board.entity.ReadBoard;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ReadBoardRepository extends JpaRepository<ReadBoard, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.unit.daybook.domain.board.repository;

public interface ReadBoardRepositoryCustom {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.unit.daybook.domain.board.repository;

import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

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

import static com.unit.daybook.domain.board.entity.QBoard.board;
import static com.unit.daybook.domain.board.entity.QReadBoard.readBoard;
import static com.unit.daybook.domain.member.domain.QMember.member;

@Repository
@RequiredArgsConstructor
public class ReadBoardRepositoryImpl implements BoardRepositoryCustom {
private final JPAQueryFactory queryFactory;

public List<Long> findBoardsByMemberId(Long memberId) {

List<Long> boards = queryFactory
.select(readBoard.board.boardId)
.from(readBoard)
.innerJoin(readBoard.member, member)
.where(
member.id.eq(memberId)
)
.fetch();

return boards;
}

public List<Long> findTodayBoardsByMemberId(Long memberId) {
LocalDate currentDate = LocalDateTime.now().toLocalDate(); // 현재 날짜의 일자만 추출

return queryFactory
.select(readBoard.readBoardId)
.from(readBoard)
.innerJoin(readBoard.board, board)
.innerJoin(readBoard.member, member)
.where(
member.id.eq(memberId)
.and(readBoard.createdAt.between(currentDate.atStartOfDay(), currentDate.atStartOfDay().plusDays(1).minusNanos(1))
))
.fetch();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@
import com.unit.daybook.domain.board.dto.request.AddBoardRequestDto;
import com.unit.daybook.domain.board.dto.response.AddBoardResponseDto;
import com.unit.daybook.domain.board.entity.Board;
import com.unit.daybook.domain.board.entity.ReadBoard;
import com.unit.daybook.domain.board.repository.BoardRepository;

import com.unit.daybook.domain.board.repository.BoardRepositoryImpl;
import com.unit.daybook.domain.board.repository.ReadBoardRepository;
import com.unit.daybook.domain.board.repository.ReadBoardRepositoryImpl;
import com.unit.daybook.domain.member.domain.Member;
import com.unit.daybook.domain.member.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Random;

@Transactional
@Service
Expand All @@ -23,6 +27,8 @@ public class BoardService {
private final BoardRepository boardRepository;
private final BoardRepositoryImpl boardRepositoryImpl;
private final MemberRepository memberRepository;
private final ReadBoardRepositoryImpl readBoardRepositoryImpl;
private final ReadBoardRepository readBoardRepository;

public AddBoardResponseDto addBoard(AddBoardRequestDto addBoardRequestDto, Long memberId) {
Member member = memberRepository.findById(memberId).orElseThrow(() -> new RuntimeException(memberId + "not found"));
Expand All @@ -36,12 +42,13 @@ public AddBoardResponseDto addBoard(AddBoardRequestDto addBoardRequestDto, Long
return AddBoardResponseDto.from(boardRepository.save(Board.createBoard(addBoardRequestDto, member)));
}


@Transactional(readOnly = true)
public AddBoardResponseDto getBoard(Long boardId) {
return AddBoardResponseDto.from(
boardRepository.findById(boardId).orElseThrow(() -> new RuntimeException(boardId + "not found")));
}

@Transactional(readOnly = true)
public List<AddBoardResponseDto> getMyBoards(Long memberId) {
// TODO 페이지네이션 - 스와이프 방식?
return boardRepositoryImpl.findBoardsByMemberId(memberId)
Expand All @@ -50,7 +57,62 @@ public List<AddBoardResponseDto> getMyBoards(Long memberId) {
.toList();
}

@Transactional(readOnly = true)
public List<AddBoardResponseDto> getRandomBoards(Long memberId) {
return null;
return getTodayBoardByMemberId(memberId);
}


public void batchReadBoard() {

List<Long> memberIds = memberRepository.findAll().stream().map(Member::getId).toList();

for (int i = 0; i < memberIds.size(); i++) {
Long memberId = memberIds.get(i);
// 이미 읽은 일지
List<Long> aleadyReadBoardIds = readBoardRepositoryImpl.findBoardsByMemberId(memberId);

// 안 읽은 일지
List<Board> notReadBoards = boardRepositoryImpl.findNotReadBoardsByMemberId(memberId, aleadyReadBoardIds);

// 적재할 일지 고유 id
List<Long> randomIdxs = selectRandomNumbers(notReadBoards.size() - 1);

// 적재
Member member = memberRepository.findById(memberId).orElseThrow(() -> new RuntimeException(memberId + "not found"));
readBoardRepository.save(ReadBoard.createReadBoard(member, notReadBoards.get(Math.toIntExact(randomIdxs.get(0)))));
readBoardRepository.save(ReadBoard.createReadBoard(member, notReadBoards.get(Math.toIntExact(randomIdxs.get(1)))));
readBoardRepository.save(ReadBoard.createReadBoard(member, notReadBoards.get(Math.toIntExact(randomIdxs.get(2)))));

}
}

public List<AddBoardResponseDto> getTodayBoardByMemberId(Long memberId) {
List<Long> todayBoards = readBoardRepositoryImpl.findTodayBoardsByMemberId(memberId);
List<Board> result = boardRepositoryImpl.findBoardInBoardIds(todayBoards);
return result.stream()
.map(AddBoardResponseDto::from)
.toList();
}

public static List<Long> selectRandomNumbers(long n) {
// 1부터 n 까지의 수를 리스트에 추가
List<Long> numbers = new ArrayList<>();
for (long i = 1; i <= n; i++) {
numbers.add(i);
}

// 랜덤으로 3개를 선택하기 위해 새 리스트를 생성
List<Long> randomNumbers = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < 3; i++) {
// 리스트에서 랜덤하게 하나의 수를 선택하여 결과 리스트에 추가
int randomIndex = random.nextInt(numbers.size());
randomNumbers.add(numbers.get(randomIndex));
// 선택된 수는 다시 리스트에서 제거하여 중복 선택을 방지
numbers.remove(randomIndex);
}

return randomNumbers;
}
}
27 changes: 27 additions & 0 deletions src/main/java/com/unit/daybook/scheduler/todayBoardsScheduler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.unit.daybook.scheduler;

import com.unit.daybook.domain.board.service.BoardService;
import com.unit.daybook.domain.member.domain.Member;
import com.unit.daybook.domain.member.repository.MemberRepository;
import com.unit.daybook.domain.member.repository.MemberRepositoryImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

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

@RequiredArgsConstructor
@Component
public class todayBoardsScheduler {
private final BoardService boardService;
private final MemberRepository memberRepository;
@Scheduled(cron = "0 0 0 * * *", zone = "Asia/Seoul")
public void run() {
System.out.println(LocalDateTime.now().toString());
List<Long> memberIds = memberRepository.findAll().stream().map(Member::getId).toList();

boardService.batchReadBoard();

}
}

0 comments on commit 230586f

Please sign in to comment.