Skip to content
Merged
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 @@ -4,6 +4,7 @@

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;
Expand Down Expand Up @@ -31,4 +32,11 @@ public interface ChatMessageRepository extends Repository<ChatMessage, Integer>
AND cm.isRead = false
""")
List<ChatMessage> findUnreadMessages(@Param("chatRoomId") Integer chatRoomId, @Param("receiverId") Integer receiverId);

@Modifying
@Query("""
DELETE FROM ChatMessage cm
WHERE cm.sender.id = :userId OR cm.receiver.id = :userId
""")
void deleteByUserId(@Param("userId") Integer userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.List;
import java.util.Optional;

import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;
Expand Down Expand Up @@ -40,4 +41,11 @@ public interface ChatRoomRepository extends Repository<ChatRoom, Integer> {
OR (cr.sender.id = :userId2 AND cr.receiver.id = :userId1)
""")
Optional<ChatRoom> findByTwoUsers(@Param("userId1") Integer userId1, @Param("userId2") Integer userId2);

@Modifying
@Query("""
DELETE FROM ChatRoom cr
WHERE cr.sender.id = :userId OR cr.receiver.id = :userId
""")
void deleteByUserId(@Param("userId") Integer userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ public interface ClubApplyRepository extends Repository<ClubApply, Integer> {
boolean existsByClubIdAndUserId(Integer clubId, Integer userId);

ClubApply save(ClubApply clubApply);

void deleteByUserId(Integer userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,8 @@ public interface ClubMemberRepository extends Repository<ClubMember, ClubMemberI
Optional<ClubMember> findPresidentByClubId(@Param("clubId") Integer clubId);

boolean existsByClubIdAndUserId(Integer clubId, Integer userId);

List<ClubMember> findByUserId(Integer userId);

void deleteByUserId(Integer userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ WHERE NOT EXISTS (
)
""")
Long countUnreadNoticesByUserId(@Param("userId") Integer userId);

void deleteByUserId(Integer userId);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gg.agit.konect.domain.user.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
Expand Down Expand Up @@ -57,4 +58,8 @@ ResponseEntity<Void> updateMyInfo(
@PostMapping("/logout")
@PublicApi
ResponseEntity<Void> logout(HttpServletRequest request);

@Operation(summary = "회원탈퇴를 한다.")
@DeleteMapping("/withdraw")
ResponseEntity<Void> logout(@UserId Integer userId);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gg.agit.konect.domain.user.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
Expand Down Expand Up @@ -77,4 +78,10 @@ public ResponseEntity<Void> logout(HttpServletRequest request) {

return ResponseEntity.ok().build();
}

@DeleteMapping("/withdraw")
public ResponseEntity<Void> logout(@UserId Integer userId) {
userService.deleteUser(userId);
return ResponseEntity.notFound().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ default User getById(Integer id) {
boolean existsByPhoneNumberAndIdNot(String phoneNumber, Integer id);

User save(User user);

void delete(User user);
}
30 changes: 30 additions & 0 deletions src/main/java/gg/agit/konect/domain/user/service/UserService.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package gg.agit.konect.domain.user.service;

import static gg.agit.konect.global.code.ApiResponseCode.CANNOT_DELETE_CLUB_PRESIDENT;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import gg.agit.konect.domain.chat.repository.ChatMessageRepository;
import gg.agit.konect.domain.chat.repository.ChatRoomRepository;
import gg.agit.konect.domain.club.model.ClubMember;
import gg.agit.konect.domain.club.repository.ClubApplyRepository;
import gg.agit.konect.domain.club.repository.ClubMemberRepository;
import gg.agit.konect.domain.notice.repository.CouncilNoticeReadRepository;
import gg.agit.konect.domain.university.model.University;
Expand All @@ -30,6 +38,9 @@ public class UserService {
private final UniversityRepository universityRepository;
private final ClubMemberRepository clubMemberRepository;
private final CouncilNoticeReadRepository councilNoticeReadRepository;
private final ClubApplyRepository clubApplyRepository;
private final ChatMessageRepository chatMessageRepository;
private final ChatRoomRepository chatRoomRepository;

@Transactional
public Integer signup(String email, Provider provider, SignupRequest request) {
Expand Down Expand Up @@ -117,4 +128,23 @@ private void validatePhoneNumberDuplication(User user, UserUpdateRequest request
throw CustomException.of(ApiResponseCode.DUPLICATE_PHONE_NUMBER);
}
}

@Transactional
public void deleteUser(Integer userId) {
User user = userRepository.getById(userId);

List<ClubMember> clubMembers = clubMemberRepository.findByUserId(userId);
boolean isPresident = clubMembers.stream().anyMatch(ClubMember::isPresident);
if (isPresident) {
throw CustomException.of(CANNOT_DELETE_CLUB_PRESIDENT);
}

// TODO. 메시지 데이터 히스토리 테이블로 이관 로직 추가
chatMessageRepository.deleteByUserId(userId);
chatRoomRepository.deleteByUserId(userId);
councilNoticeReadRepository.deleteByUserId(userId);
clubApplyRepository.deleteByUserId(userId);
clubMemberRepository.deleteByUserId(userId);
userRepository.delete(user);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public enum ApiResponseCode {
FAILED_EXTRACT_EMAIL(HttpStatus.BAD_REQUEST, "OAuth 로그인 과정에서 이메일 정보를 가져올 수 없습니다."),
CANNOT_CREATE_CHAT_ROOM_WITH_SELF(HttpStatus.BAD_REQUEST, "자기 자신과는 채팅방을 만들 수 없습니다."),
REQUIRED_CLUB_APPLY_ANSWER_MISSING(HttpStatus.BAD_REQUEST, "필수 가입 답변이 누락되었습니다."),
CANNOT_DELETE_CLUB_PRESIDENT(HttpStatus.BAD_REQUEST, "동아리 회장인 경우 회장을 양도하고 탈퇴해야 합니다."),

// 401 Unauthorized
INVALID_SESSION(HttpStatus.UNAUTHORIZED, "올바르지 않은 인증 정보 입니다."),
Expand Down