Skip to content

Commit

Permalink
Merge pull request #199 from MoneyMakersClub/develop
Browse files Browse the repository at this point in the history
[Feat] 회원 탈퇴 내부에 로직 추가, 닉네임 관련 API 수정 등 배포
  • Loading branch information
seohyun-lee authored Dec 1, 2024
2 parents fe5cdf0 + 9f9e752 commit 1935e18
Show file tree
Hide file tree
Showing 19 changed files with 174 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public interface AlarmRepository extends JpaRepository<Alarm, Long> {
@Query("SELECT a FROM Alarm a WHERE a.receiver = :user ORDER BY a.createdTime DESC")
Page<Alarm> findByReceiverOrderByCreatedTimeDesc(@Param("user") User user, Pageable pageable);

void deleteAllBySender(User user);
void deleteAllByReceiver(User user);
void deleteBySender(User user);
void deleteByReceiver(User user);
void deleteByCreatedTimeBefore(LocalDateTime createdTime);

List<Alarm> findAllByReceiverAndIsReadFalse(User user);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ private void sendPushNotificationIfEnabled(User receiver, Alarm alarm) {
}
}

public void deleteAllAlarmsOfUser(User user){
alarmRepository.deleteAllBySender(user);
alarmRepository.deleteAllByReceiver(user);
public void deleteAlarmsOfUser(User user){
alarmRepository.deleteBySender(user);
alarmRepository.deleteByReceiver(user);
}

// Alarm 전체 읽음처리
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@

public interface UserBadgeRepository extends JpaRepository<UserBadge, Long> {
List<UserBadge> findAllByUser(User user);
void deleteAllByUser(User user);
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,9 @@ public List<UserBadge> deleteDuplicateUserBadges(List<UserBadge> userBadges) {

return new ArrayList<>(badgeIdToUniqueUserBadgeMap.values());
}

public void deleteUserBadgesByUser(User user) {
userBadgeRepository.deleteAllByUser(user);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.mmc.bookduck.domain.friend.repository;

import com.mmc.bookduck.domain.friend.entity.Friend;
import com.mmc.bookduck.domain.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
Expand All @@ -13,4 +14,7 @@ public interface FriendRepository extends JpaRepository<Friend, Long> {
"OR (f.user1.userId = :receiverId AND f.user2.userId = :senderId)")
Optional<Friend> findFriendBetweenUsers(@Param("senderId") Long senderId, @Param("receiverId") Long receiverId);
List<Friend> findAllByUser1UserIdOrUser2UserId(Long userId1, Long userId2);

void deleteByUser1(User user);
void deleteByUser2(User user);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.mmc.bookduck.domain.friend.entity.FriendRequest;
import com.mmc.bookduck.domain.friend.entity.FriendRequestStatus;
import com.mmc.bookduck.domain.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
Expand All @@ -14,4 +15,7 @@ public interface FriendRequestRepository extends JpaRepository<FriendRequest, Lo
List<FriendRequest> findAllFriendRequestsBetweenUsers(@Param("userId1") Long userId1, @Param("userId2") Long userId2, @Param("status") FriendRequestStatus status);
List<FriendRequest> findAllByReceiverUserIdAndFriendRequestStatus(Long receiverId, FriendRequestStatus status);
List<FriendRequest> findAllBySenderUserIdAndFriendRequestStatus(Long receiverId, FriendRequestStatus status);

void deleteBySender(User sender);
void deleteByReceiver(User receiver);
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,10 @@ public FriendRequest getPendingFriendRequestBetweenUsers(User currentUser, User
// 친구 요청 1개(1개여야만 함)를 반환
return existingRequests.getFirst();
}

public void deleteFriendRequestsByUser(User user) {
friendRequestRepository.deleteBySender(user);
friendRequestRepository.deleteByReceiver(user);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,9 @@ public Optional<Friend> getFriendBetweenUsers(User user, User otherUser) {
public User getFriendUser(Friend friend, User currentUser) {
return friend.getUser1().equals(currentUser) ? friend.getUser2() : friend.getUser1();
}

public void deleteFriendsOfUser(User user) {
friendRepository.deleteByUser1(user);
friendRepository.deleteByUser2(user);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@

public interface HomeCardRepository extends JpaRepository<HomeCard, Long> {
List<HomeCard> findAllByUserOrderByCardIndexAsc(User user);
List<HomeCard> findAllByUser(User user);
void deleteAllByUser(User user);
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,8 @@ public void updateHomeCards(ReadingSpaceUpdateRequestDto requestDto, User user)
homeCardRepository.deleteAll(cardsToDelete);
homeCardRepository.saveAll(cardsToUpdate);
}

public void deleteHomeCardsByUser(User user) {
homeCardRepository.deleteAllByUser(user);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@
@Getter
@RequiredArgsConstructor
public enum ItemUnlockCondition {
// 장르 조합 그룹화
FICTION_LITERARY_HUMANITIES_SCIENCE("FICTION+LITERARY+HUMANITIES+SCIENCE", 5),
SCIENCE("SCIENCE", 5),
ART_COMICS("ART+COMICS", 5),
TRAVEL("TRAVEL", 5),
ARCHITECTURE_TECHNOLOGY("ARCHITECTURE+TECHNOLOGY", 5),
COMPUTER("COMPUTER", 5),
HEALTH("HEALTH", 5),
OTHERS("OTHERS", 0),
HISTORY("HISTORY", 5),
BUSINESS_SOCIETY("BUSINESS+SOCIETY", 5),
HOME_COOKING("HOME_COOKING", 5);
FICTION_LITERARY_HUMANITIES_SCIENCE("FICTION+LITERARY+HUMANITIES+SCIENCE"),
SCIENCE("SCIENCE"),
ART_COMICS("ART+COMICS"),
TRAVEL("TRAVEL"),
ARCHITECTURE_TECHNOLOGY("ARCHITECTURE+TECHNOLOGY"),
COMPUTER("COMPUTER"),
HEALTH("HEALTH"),
OTHERS("OTHERS"),
HISTORY("HISTORY"),
BUSINESS_SOCIETY("BUSINESS+SOCIETY"),
HOME_COOKING("HOME_COOKING"),
SELF_HELP("SELF_HELP"),
ART_HOBBY("ART+HOBBY");

private final String genres;
private final int requiredCount;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@
public interface UserItemRepository extends JpaRepository<UserItem, Long> {
List<UserItem> findAllByUserAndIsEquippedTrue(User user);
List<UserItem> findAllByUser(User user);

void deleteAllByUser(User user);
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,9 @@ public List<ItemEquippedUnitDto> getUserItemEquippedListOfUser(User user) {
.map(entry -> new ItemEquippedUnitDto(entry.getKey(), entry.getValue() != null ? entry.getValue().getItem().getItemName() : null))
.collect(Collectors.toList());
}

public void deletUserItemsByUser(User user) {
userItemRepository.deleteAllByUser(user);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@

import com.mmc.bookduck.domain.user.dto.request.UserNicknameRequestDto;
import com.mmc.bookduck.domain.user.dto.request.UserSettingUpdateRequestDto;
import com.mmc.bookduck.domain.user.service.UserWithdrawService;
import com.mmc.bookduck.domain.user.service.UserSettingService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@Slf4j
@Tag(name = "UserSetting", description = "사용자 환경 설정 관련 API입니다.")
@RestController
@RequiredArgsConstructor
@RequestMapping("/settings")
public class UserSettingController {
private final UserSettingService userSettingService;
private final UserWithdrawService userWithdrawService;

@Operation(summary = "설정 정보 보기", description = "유저의 계정 정보, 사용 설정, 기록 폰트 정보를 조회합니다.")
@GetMapping
Expand Down Expand Up @@ -52,8 +56,8 @@ public ResponseEntity<?> updateOptions(@RequestBody @Valid UserSettingUpdateRequ

@Operation(summary = "회원 탈퇴", description = "회원을 탈퇴합니다.")
@PatchMapping("/status")
public ResponseEntity<?> deactivate(HttpServletResponse response) {
userSettingService.deactivate(response);
public ResponseEntity<?> withdrawUser(HttpServletResponse response) {
userWithdrawService.withdrawUser(response);
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,13 @@ public void setIsAnnouncementChecked(boolean isAnnouncementChecked) {
public void updateStatus(UserStatus userStatus) {
this.userStatus = userStatus;
}

public void clearUserData() {
this.email = "[deleted]";
this.nickname = "알 수 없는 사용자";
this.userStatus = UserStatus.DELETED;
this.fcmToken = null;
this.isOfficial = false;
this.isAnnouncementChecked = true;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.mmc.bookduck.domain.user.service;

import com.mmc.bookduck.domain.badge.service.UserBadgeService;
import com.mmc.bookduck.domain.book.service.BookInfoService;
import com.mmc.bookduck.domain.folder.service.FolderService;
import com.mmc.bookduck.domain.homecard.service.HomeCardService;
import com.mmc.bookduck.domain.item.service.UserItemService;
import com.mmc.bookduck.domain.user.dto.request.UserNicknameRequestDto;
import com.mmc.bookduck.domain.user.dto.request.UserSettingUpdateRequestDto;
import com.mmc.bookduck.domain.user.dto.response.UserNicknameResponseDto;
Expand Down Expand Up @@ -30,10 +33,6 @@
public class UserSettingService {
private final UserService userService;
private final UserSettingRepository userSettingRepository;
private final RedisService redisService;
private final CookieUtil cookieUtil;
private final FolderService folderService;
private final BookInfoService bookInfoService;

@Transactional(readOnly = true)
public UserSettingInfoResponseDto getUserSettingInfo() {
Expand All @@ -56,14 +55,19 @@ public UserNicknameResponseDto getUserNickname() {

@Transactional(readOnly = true)
public UserNicknameAvailabilityResponseDto checkNicknameAvailability(UserNicknameRequestDto requestDto) {
return new UserNicknameAvailabilityResponseDto(!userService.existsByNickname(requestDto.nickname()));
User user = userService.getCurrentUser();
String nickname = requestDto.nickname();
if (user.getNickname().equals(nickname))
return new UserNicknameAvailabilityResponseDto(true);
return new UserNicknameAvailabilityResponseDto(!userService.existsByNickname(nickname));
}

public void updateUserNickname(UserNicknameRequestDto requestDto) {
String nickname = requestDto.nickname();
User user = userService.getCurrentUser();
boolean isAvailable = !userService.existsByNickname(nickname);
if (isAvailable) {
if (user.getNickname().equals(nickname))
return;
if (!userService.existsByNickname(nickname)) {
user.updateNickname(nickname); // 트랜잭션 커밋 시 자동 저장
} else {
throw new CustomException(ErrorCode.NICKNAME_ALREADY_EXISTS);
Expand All @@ -85,22 +89,4 @@ public void updateOptions(UserSettingUpdateRequestDto requestDto) {
private <T> void updateSetting(T value, Consumer<T> updateFunction) {
Optional.ofNullable(value).ifPresent(updateFunction);
}

public void deactivate(HttpServletResponse response) {
User user = userService.getCurrentUser();

// 폴더 & 커스텀책 삭제
folderService.deleteUserFolder(user);
bookInfoService.deleteUserCustomBook(user);

String nickname = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 8);
user.updateNickname(nickname);
user.updateStatus(UserStatus.DELETED);
userService.saveUser(user);

// TODO: 추후 폴더 책들, 커스텀 책들, 친구 등 삭제 로직 작성

redisService.deleteValues(user.getEmail());
cookieUtil.deleteCookie(response, "refreshToken");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.mmc.bookduck.domain.user.service;

import com.mmc.bookduck.domain.alarm.service.AlarmService;
import com.mmc.bookduck.domain.badge.service.UserBadgeService;
import com.mmc.bookduck.domain.book.service.BookInfoService;
import com.mmc.bookduck.domain.folder.service.FolderService;
import com.mmc.bookduck.domain.friend.service.FriendRequestService;
import com.mmc.bookduck.domain.friend.service.FriendService;
import com.mmc.bookduck.domain.homecard.service.HomeCardService;
import com.mmc.bookduck.domain.item.service.UserItemService;
import com.mmc.bookduck.domain.user.entity.User;
import com.mmc.bookduck.global.security.CookieUtil;
import com.mmc.bookduck.global.security.RedisService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
@Transactional
@RequiredArgsConstructor
public class UserWithdrawService {
private final UserService userService;
private final RedisService redisService;
private final CookieUtil cookieUtil;
private final FolderService folderService;
private final BookInfoService bookInfoService;
private final UserBadgeService userBadgeService;
private final HomeCardService homeCardService;
private final UserItemService userItemService;
private final FriendRequestService friendRequestService;
private final FriendService friendService;
private final AlarmService alarmService;

public void withdrawUser(HttpServletResponse response) {
User user = userService.getCurrentUser();

log.info("userId: " + user.getUserId() +" | 이메일: " + user.getEmail() + " 회원이 탈퇴했습니다.");

// 폴더 & 커스텀책 삭제
folderService.deleteUserFolder(user);
bookInfoService.deleteUserCustomBook(user);

// 뱃지, 아이템, 카드(위젯) 삭제
userBadgeService.deleteUserBadgesByUser(user);
userItemService.deletUserItemsByUser(user);
homeCardService.deleteHomeCardsByUser(user);

// 친구 요청, 친구, 알림 삭제
friendRequestService.deleteFriendRequestsByUser(user);
friendService.deleteFriendsOfUser(user);
alarmService.deleteAlarmsOfUser(user);

// 글 삭제

// 유저 데이터 삭제
user.clearUserData();;
userService.saveUser(user);

redisService.deleteValues(user.getEmail());
cookieUtil.deleteCookie(response, "refreshToken");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void initializeItems() {
.itemType(itemData.getItemType())
.description(itemData.getDescription())
.unlockCondition(itemData.getUnlockCondition().getGenres()
+ "%" + itemData.getUnlockCondition().getRequiredCount())
+ "%" + itemData.getRequiredCount())
.build());
}
}
Expand Down
Loading

0 comments on commit 1935e18

Please sign in to comment.