Skip to content

Commit

Permalink
[Feature/#78] 일기 수정, 삭제기능 구현 (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
Walkers15 authored Aug 23, 2023
1 parent d6826fa commit 1854f13
Show file tree
Hide file tree
Showing 24 changed files with 629 additions and 187 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.dnd.bbok.diary.adapter.in.web;


import com.dnd.bbok.diary.application.port.in.usecase.DeleteDiaryUseCase;
import com.dnd.bbok.global.response.MessageResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("api/v1/friend")
@Api(tags = "일기 관련 컨트롤러")
public class DeleteDiaryController {
private final DeleteDiaryUseCase deleteDiaryUseCase;

@ApiOperation("일기 삭제")
@PreAuthorize("isAuthenticated()")
@DeleteMapping("diary/{id}")
public ResponseEntity<MessageResponse> deleteDiary(@Parameter(name = "id", in = ParameterIn.PATH, description = "일기 id") @PathVariable("id") Long id) {
deleteDiaryUseCase.deleteDiary(id);
return new ResponseEntity<>(MessageResponse.of(HttpStatus.OK, "일기 삭제 성공"), HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.dnd.bbok.diary.adapter.in.web;

import com.dnd.bbok.diary.application.port.in.request.UpdateDiaryRequest;
import com.dnd.bbok.diary.application.port.in.response.CreateDiaryResponse;
import com.dnd.bbok.diary.application.port.in.usecase.UpdateDiaryUseCase;
import com.dnd.bbok.global.response.MessageResponse;
import com.dnd.bbok.member.application.port.in.response.SessionUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("api/v1/friend")
@Api(tags = "일기 관련 컨트롤러")
public class UpdateDiaryController {
private final UpdateDiaryUseCase updateDiaryUseCase;

@ApiOperation("일기 수정")
@PreAuthorize("isAuthenticated()")
@PatchMapping("diary/{id}")
public ResponseEntity<MessageResponse> updateDiary(
@Parameter(name = "id", in = ParameterIn.PATH, description = "일기 id") @PathVariable("id") Long id,
@RequestBody UpdateDiaryRequest updateDiaryRequest,
@AuthenticationPrincipal SessionUser sessionUser
) {
updateDiaryUseCase.updateDiary(sessionUser.getUuid(), id, updateDiaryRequest);
return new ResponseEntity<>(MessageResponse.of(HttpStatus.OK, "일기 수정 성공"), HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;

import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -42,7 +43,7 @@
@RequiredArgsConstructor
@Slf4j
public class DiaryAdapter implements SaveDiaryPort, LoadDiaryPort {
private final int PAGE_SIZE = 20;
private final EntityManager entityManager;

private final FriendTagRepository friendTagRepository;
private final FriendRepository friendRepository;
Expand All @@ -61,39 +62,161 @@ public void createDiary(Long friendId, Diary diary) {
FriendEntity friend = friendRepository.findById(friendId).orElseThrow(() -> new BusinessException(FRIEND_NOT_FOUND));

// 1. 태그들 중 id 가 없는 태그가 있다면 Friend Tag Entity 생성
diary.getTags().forEach(tag -> {
if (tag.getId() == null) {
FriendTagEntity friendTagEntity = friendTagRepository.save(FriendTagEntity.builder()
.friend(friend)
.name(tag.getTag())
.build());
tag.setId(friendTagEntity.getId());
}
});

if (diary.getTags() != null) {
diary.getTags().forEach(tag -> {
if (tag.getId() == null) {
FriendTagEntity friendTagEntity = friendTagRepository.save(FriendTagEntity.builder()
.friend(friend)
.name(tag.getTag())
.build());
tag.setId(friendTagEntity.getId());
}
});
}

// 2. 다이어리 생성
DiaryEntity diaryEntity = diaryRepository.save(DiaryEntity.builder()
.friend(friend)
.contents(diary.getContents())
.diaryDate(diary.getDiaryDate())
.isDeleted(false)
.emoji(diary.getEmoji())
.sticker(diary.getSticker())
.diaryScore(diary.getDiaryScore())
.build());

// 3. 다이어리 태그 생성
List<FriendTagEntity> friendTagEntities = friendTagRepository.findAllByFriendId(friendId);
List<DiaryTagEntity> diaryTagEntities = new ArrayList<>();
diary.getTags().forEach(tag -> {
FriendTagEntity friendTagEntity = friendTagEntities.stream().filter(ele -> Objects.equals(ele.getName(), tag.getTag())).findFirst().orElseThrow();
diaryTagEntities.add(DiaryTagEntity.builder()
.diaryEntity(diaryEntity)
.friendTagEntity(friendTagEntity)
.build());
});
diaryTagRepository.saveAll(diaryTagEntities);
if (diary.getTags().size() > 0) {
List<FriendTagEntity> friendTagEntities = friendTagRepository.findAllByFriendId(friendId);
List<DiaryTagEntity> diaryTagEntities = new ArrayList<>();
diary.getTags().forEach(tag -> {
FriendTagEntity friendTagEntity = friendTagEntities.stream().filter(ele -> Objects.equals(ele.getName(), tag.getTag())).findFirst().orElseThrow();
diaryTagEntities.add(DiaryTagEntity.builder()
.diaryEntity(diaryEntity)
.friendTagEntity(friendTagEntity)
.build());
});
diaryTagRepository.saveAll(diaryTagEntities);
}


// 4. 다이어리 체크리스트 생성
if (diary.getDiaryChecklist().size() > 0) {
createDiaryChecklistEntity(diary, diaryEntity);
}
}

@Override
@Transactional
public void saveDiary(Diary diary) {
FriendEntity friendEntity = friendRepository.findById(diary.getFriendId()).orElseThrow(() -> new BusinessException(FRIEND_NOT_FOUND));
DiaryEntity diaryEntity = diaryMapper.toEntity(diary, friendEntity);
List<DiaryTagEntity> prevTagEntities = diaryTagRepository.findByDiaryId(diary.getId());
List<Tag> prevTags = diaryTagMapper.toDomain(prevTagEntities);
List<FriendTagEntity> friendTagEntities = null;
for (Tag tag : diary.getTags()) {
if (prevTags.stream().noneMatch(prevTag -> Objects.equals(tag.getTag(), prevTag.getTag()))) {
// 없던 태그가 생겼으므로 새로 생성해야 함
if (friendTagEntities == null) {
friendTagEntities = friendTagRepository.findAllByFriendId(friendEntity.getId());
}

// 아예 처음 생기는 태그인 경우 Friend Tag 생성
FriendTagEntity friendTagEntity;
if (tag.getId() == null) {
log.info("새로운 Friend Tag 저장");
friendTagEntity = friendTagRepository.save(FriendTagEntity.builder()
.friend(friendEntity)
.name(tag.getTag())
.build());
tag.setId(friendTagEntity.getId());
entityManager.persist(friendTagEntity);
friendTagEntities.add(friendTagEntity);
log.info("새로운 Friend Tag 저장 완료");
}
}
}
List<DiaryTagEntity> diaryTagEntities = diaryTagMapper.toEntity(diary.getTags(), diaryEntity, prevTagEntities, friendEntity, friendTagEntities);
List<MemberChecklistEntity> memberChecklistEntities = memberChecklistRepository.findByIdIn(diary.getDiaryChecklist().stream().map(DiaryChecklist::getMemberChecklistId).collect(Collectors.toList()));
log.info("체크리스트 갯수");
log.info(diary.getDiaryChecklist().toString());
List<DiaryChecklistEntity> diaryChecklistEntities = diaryChecklistMapper.toEntity(diary.getDiaryChecklist(), memberChecklistEntities, diaryEntity);
diaryEntity.setDiaryTags(diaryTagEntities);
diaryEntity.setDiaryChecklists(diaryChecklistEntities);
diaryRepository.save(diaryEntity);
}

// @Transactional
// public void saveDiary(Diary diary) {
// FriendEntity friendEntity = friendRepository.findById(diary.getFriendId()).orElseThrow(() -> new BusinessException(FRIEND_NOT_FOUND));
// DiaryEntity diaryEntity = diaryMapper.toEntity(diary, friendEntity);
//
// // 1. 다이어리 컬럼 내부 값 업데이트
// diaryRepository.save(diaryEntity);
//
// // 2. 태그 변경사항 확인하여 없어진 태그는 삭제, 생긴 태그는 추가
//
// // 이전 태그 목록 가져와서 없어진 태그 삭제하기
// List<Tag> prevTags = diaryTagMapper.toDomain(diaryTagRepository.findByDiaryId(diary.getId()));
// List<Long> deleteTagIds = new ArrayList<>();
// prevTags.forEach(prevTag -> {
// if (diary.getTags().stream().noneMatch(tag -> Objects.equals(tag.getTag(), prevTag.getTag()))) {
// deleteTagIds.add(prevTag.getId());
// }
// });
// diaryTagRepository.deleteAllById(deleteTagIds);
//
// // 이전 태그 목록과 대조하며 새로 생긴 태그 추가히기
// List<DiaryTagEntity> diaryTagEntities = new ArrayList<>();
//
// List<FriendTagEntity> friendTagEntities = null;
// for (Tag tag : diary.getTags()) {
// if (prevTags.stream().noneMatch(prevTag -> Objects.equals(tag.getTag(), prevTag.getTag()))) {
// // 없던 태그가 생겼으므로 새로 생성해야 함
// if (friendTagEntities == null) {
// friendTagEntities = friendTagRepository.findAllByFriendId(friendEntity.getId());
// }
//
// // 아예 처음 생기는 태그인 경우 Friend Tag 생성
// FriendTagEntity friendTagEntity;
// if (tag.getId() == null) {
// friendTagEntity = friendTagRepository.save(FriendTagEntity.builder()
// .friend(friendEntity)
// .name(tag.getTag())
// .build());
// tag.setId(friendTagEntity.getId());
// } else {
// friendTagEntity = friendTagEntities.stream().filter(ele -> Objects.equals(ele.getName(), tag.getTag())).findFirst().orElseThrow();
// }
// diaryTagEntities.add(DiaryTagEntity.builder()
// .diaryEntity(diaryEntity)
// .friendTagEntity(friendTagEntity)
// .build());
// }
// }
//
// diaryTagRepository.saveAll(diaryTagEntities);
//
//
// // 3. 체크리스트 변경사항 확인하여 작성 안했다가 추가한 경우, 체크리스트 수정만 한 경우, 작성했다가 없앤 경우 Case 에 맞게 CRD 작업
// List<DiaryChecklistEntity> prevDiaryChecklistEntities = diaryChecklistRepository.getDiaryChecklistByDiaryId(diary.getId());
// log.info(String.valueOf(prevDiaryChecklistEntities.get(0).getId()));
// // Case 1. 작성 안했다가 추가한 경우 처리 (전부 추가)
// if (prevDiaryChecklistEntities.size() == 0 && diary.getDiaryChecklist().size() != 0) {
// createDiaryChecklistEntity(diary, diaryEntity);
// }
//
// // Case 2. 작성했다가 없앤 경우 (전부 삭제)
// if (prevDiaryChecklistEntities.size() > 0 && diary.getDiaryChecklist().size() == 0) {
// diaryChecklistRepository.deleteAll(prevDiaryChecklistEntities);
// }
//
// // Case 3. 체크리스트 수정만 한 경우 처리
// List<MemberChecklistEntity> memberChecklistEntities = memberChecklistRepository.findByIdIn(diary.getDiaryChecklist().stream().map(DiaryChecklist::getMemberChecklistId).collect(Collectors.toList()));
// diaryChecklistRepository.saveAll(diaryChecklistMapper.toEntity(diary.getDiaryChecklist(), memberChecklistEntities, diaryEntity));
// }

private void createDiaryChecklistEntity(Diary diary, DiaryEntity diaryEntity) {
List<MemberChecklistEntity> memberChecklistEntities = memberChecklistRepository.findByIdIn(diary.getDiaryChecklist().stream().map(DiaryChecklist::getMemberChecklistId).collect(Collectors.toList()));
List<DiaryChecklistEntity> diaryChecklistEntities = new ArrayList<>();
diary.getDiaryChecklist().forEach(diaryChecklist -> {
Expand All @@ -112,7 +235,7 @@ public void createDiary(Long friendId, Diary diary) {
public Diary loadDiary(Long diaryId) {
List<Tag> tags = diaryTagMapper.toDomain(diaryTagRepository.findByDiaryId(diaryId));
List<DiaryChecklist> diaryChecklists = diaryChecklistMapper.toDomain(diaryChecklistRepository.getDiaryChecklistByDiaryId(diaryId));
return diaryMapper.toEntity(diaryRepository.findById(diaryId).orElseThrow(() -> new BusinessException(DIARY_NOT_FOUND)), tags, diaryChecklists);
return diaryMapper.toDomain(diaryRepository.findById(diaryId).orElseThrow(() -> new BusinessException(DIARY_NOT_FOUND)), tags, diaryChecklists);
}

@Override
Expand All @@ -122,6 +245,7 @@ public Page<Diary> loadDiaries(Long friendId, Integer offset, String order, Stri
}

Pageable pageable;
int PAGE_SIZE = 20;
if (Objects.equals(order, "asc")) {
pageable = PageRequest.of(offset / PAGE_SIZE, PAGE_SIZE, Sort.Direction.ASC, "diaryDate");
} else {
Expand All @@ -142,10 +266,21 @@ public Page<Diary> loadDiaries(Long friendId, Integer offset, String order, Stri
List<Tag> tags = diaryTagMapper.toDomain(diaryTagRepository.findByDiaryIds(diaryIds));
List<DiaryChecklist> checklists = diaryChecklistMapper.toDomain(diaryChecklistRepository.getDiaryChecklistByDiaryIds(diaryIds));

Page<Diary> diaryPage = diaryEntityPage.map(diaryEntity -> diaryMapper.toEntity(diaryEntity, tags, checklists));
Page<Diary> diaryPage = diaryEntityPage.map(diaryEntity -> diaryMapper.toDomain(diaryEntity, tags, checklists));
return diaryPage;
}

/**
* 친구 점수 전체 재계산을 위해 사용하는 메소드
*
* @param friendId 친구 아이디
* @return 태그와 체크리스트가 비어있는 일기 도메인 리스트
*/
@Override
public List<Diary> loadDiariesByFriendId(Long friendId) {
return diaryRepository.findAllByFriendIdAndIsDeletedIsFalse(friendId).stream().map(entity -> diaryMapper.toDomain(entity, new ArrayList<>(), new ArrayList<>())).collect(Collectors.toList());
}

@Override
public int countDiariesByFriendId(Long friendId) {
return this.diaryRepository.countDiariesByFriendId(friendId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ public class DiaryChecklistEntity {
private MemberChecklistEntity memberChecklistEntity;

@Builder
public DiaryChecklistEntity(boolean isChecked, DiaryEntity diaryEntity, MemberChecklistEntity memberChecklistEntity) {
public DiaryChecklistEntity(Long id, boolean isChecked, DiaryEntity diaryEntity, MemberChecklistEntity memberChecklistEntity) {
this.id = id;
this.isChecked = isChecked;
this.diaryEntity = diaryEntity;
this.memberChecklistEntity = memberChecklistEntity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ public class DiaryEntity extends BaseTimeEntity {
@NotNull
private String sticker;

@NotNull
private Integer diaryScore;

@NotNull
private Boolean isDeleted;

/**
* 일화와 친구를 다대일 관계 매핑
*/
Expand All @@ -52,12 +58,24 @@ public class DiaryEntity extends BaseTimeEntity {
private List<DiaryChecklistEntity> diaryChecklists = new ArrayList<>();

@Builder
public DiaryEntity(Long id, Emoji emoji, String contents, LocalDate diaryDate, FriendEntity friend, String sticker) {
public DiaryEntity(Long id, Emoji emoji, String contents, LocalDate diaryDate, String sticker, Integer diaryScore, Boolean isDeleted, FriendEntity friend, List<DiaryTagEntity> diaryTags, List<DiaryChecklistEntity> diaryChecklists) {
this.id = id;
this.emoji = emoji;
this.contents = contents;
this.diaryDate = diaryDate;
this.friend = friend;
this.sticker = sticker;
this.diaryScore = diaryScore;
this.isDeleted = isDeleted;
this.friend = friend;
this.diaryTags = diaryTags;
this.diaryChecklists = diaryChecklists;
}

public void setDiaryTags(List<DiaryTagEntity> diaryTags) {
this.diaryTags = diaryTags;
}

public void setDiaryChecklists(List<DiaryChecklistEntity> diaryChecklists) {
this.diaryChecklists = diaryChecklists;
}
}
Loading

0 comments on commit 1854f13

Please sign in to comment.