[ 작업한 내용 ]
# Frontend
1. 대출 연장 api 연결
- 대출연장은 1회만 가능. 대출연장 유무를 체크하여 0회 또는 1회로 표시.
<div>대출연장: <span>{item.extended != true ? "0" : "1"}</span>회</div>
- 도서 대출 연장 버튼 클릭 시 해당 id를 대출 연장 api 함수로 전달하여 실행.
// 도서 대출 연장 api
const updateExtended = async (loanId) => {
try {
const response = await axios.patch(
`http://localhost:8080/api/v1/user/me/loans/${loanId}/extend`,
{},
{
withCredentials: true,
headers: {
Accept: "application/json",
}
}
);
console.log(response.data.data);
alert("도서 대출 연장 성공");
} catch (error) {
console.log("Error: ", error.response.data.message);
setError(error.response.data.message);
alert(error.response.data.message);
} finally {
}
}
// 버튼 클릭 시 id에 따라 api 호출
const handleClick = async () => {
await updateExtended(loanId);
await fetchBookLoans();
document.getElementById(id)?.close();
}
{/* 대출연장 */}
{ id === "dialogExtended" && (
<>
<div class="flex flex-col w-full mt-3 text-center sm:mt-0 sm:text-left">
<h3 id="dialog-title" class="text-base font-semibold text-gray-900">{title}</h3>
<div class="mt-2">
<p class="text-sm text-gray-500 mb-3">{content}</p>
</div>
</div>
</>
)}
{/* 대출연장버튼 */}
<button
type="button" command="close" commandfor={id}
class="
inline-flex w-full justify-center rounded-md
bg-teal-600 hover:bg-teal-700
text-sm font-semibold text-white shadow-xs
px-3 py-2 sm:ml-3 sm:w-auto
"
onClick={handleClick}
>연장</button>
2. 반납일, 반납 예정일 데이터 화면에 출력
- 반납일에 값이 있으면 반납일을 표기하고, 반납일에 값이 없으면 반납예정일로 표기
{item.returnDate
? (
<div className="font-bold">
반납일:
<span className="text-red-700 ml-[4px] font-normal">{item.returnDate.split('T', 1)}</span>
</div>
)
: (
<div className="font-bold">
반납예정일:
<span className="text-red-700 ml-[4px] font-normal">{item.dueDate.split('T', 1)}</span>
</div>
)
}
# Backend
1. 내 도서 대출 내역 조회 시 내림차순으로 코드 수정
- JPA 네이밍 규칙으로 DESC을 사용하여 내림차순으로 코드 수정
// Repository
Page<Loan> findByUser_IdOrderByLoanDateDesc(Long userId, Pageable pageable);
// Service
Page<Loan> result = loanRepository.findByUser_IdOrderByLoanDateDesc(user.getId(), pageable);
2. 도서 대출 목록에 리뷰 작성 확인 코드 추가
- 리뷰 작성 유무 체크를 위해 응답 DTO, Service, Repository 코드 수정
// 응답 DTO
// boolean reviewWritten 추가
public class UserLoanListResDTO {
private Long id;
private String bookTitle;
private String author;
private String publisher;
private LocalDate publishedDate;
private String location;
private LocalDateTime loanDate;
private LocalDateTime dueDate;
private LocalDateTime returnDate;
private String borrower;
private LoanStatus status;
private boolean extended;
private boolean reviewWritten;
public UserLoanListResDTO(Loan loan, boolean reviewWritten) {
this.id = loan.getId();
this.bookTitle = loan.getBook().getTitle();
this.author = loan.getBook().getAuthor();
this.publisher = loan.getBook().getPublisher();
this.publishedDate = loan.getBook().getPublishedDate();
this.location = loan.getBook().getLocation();
this.loanDate = loan.getLoanDate();
this.dueDate = loan.getDueDate();
this.returnDate = loan.getReturnDate();
this.borrower = loan.getUser().getUsername();
this.status = loan.getStatus();
this.extended = loan.isExtended();
this.reviewWritten = reviewWritten;
}
}
// Service
// 조회한 loans를 UserLoanListResDTO로 맵핑하면서 reviewWritten 유무를 체크한 후 결과를 반환.
Page<Loan> loans = loanRepository.findByUser_IdOrderByLoanDateDesc(user.getId(), pageable);
// 리뷰 작성 여부 체크 추가
Page<UserLoanListResDTO> pageDTO = loans.map(loan -> {
boolean reviewWritten = reviewRepository.existsByBook_IdAndUser_Id(loan.getBook().getId(), loan.getUser().getId());
return new UserLoanListResDTO(loan, reviewWritten);
});
// Repository
// 사용자: 특정 도서 리뷰 작성 체크
boolean existsByBook_IdAndUser_Id(Long bookId, Long userId);

'공부 기록 > Java with ChatGPT' 카테고리의 다른 글
| [Java/ChatGPT] Day 22: Stream API 고급 활용 & Optional (0) | 2025.07.27 |
|---|---|
| [Java/ChatGPT] Day 21: 파일 기반 데이터 저장 및 로딩 (실제 시스템처럼) (0) | 2025.07.25 |
| [Java/ChatGPT] Day 20: 날짜(LocalDate) 활용 & 조건 기반 검색 기능 (0) | 2025.07.24 |
| [Java/ChatGPT] Day 19: 예외 처리와 파일 연동 실전 연습 (0) | 2025.07.16 |
| [Java/ChatGPT] Day 18: 파일 입출력 (File I/O) (0) | 2025.07.14 |