-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #68 from NU-BIM/feat/user-block
[NB-249, NB-251] 사용자 간 차단 기능 구현
- Loading branch information
Showing
16 changed files
with
382 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
src/main/java/com/soyeon/nubim/domain/user_block/UserBlock.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package com.soyeon.nubim.domain.user_block; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
import org.hibernate.annotations.CreationTimestamp; | ||
|
||
import com.soyeon.nubim.domain.user.User; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import jakarta.persistence.Table; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Entity | ||
@Getter | ||
@Builder | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Table(name = "user_block") | ||
public class UserBlock { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long userBlockId; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "blocking_user_id", nullable = false) | ||
private User blockingUser; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "blocked_user_id", nullable = false) | ||
private User blockedUser; | ||
|
||
@CreationTimestamp | ||
@Column(nullable = false, updatable = false) | ||
private LocalDateTime blockedAt; | ||
} |
51 changes: 51 additions & 0 deletions
51
src/main/java/com/soyeon/nubim/domain/user_block/UserBlockControllerV1.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package com.soyeon.nubim.domain.user_block; | ||
|
||
import java.util.List; | ||
|
||
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.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import com.soyeon.nubim.domain.user_block.dto.UserBlockCreateResponse; | ||
import com.soyeon.nubim.domain.user_block.dto.UserBlockDeleteResponse; | ||
import com.soyeon.nubim.domain.user_block.dto.UserBlockReadResponse; | ||
import com.soyeon.nubim.domain.user_block.dto.UserBlockRequest; | ||
|
||
import io.swagger.v3.oas.annotations.Operation; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@RestController | ||
@RequestMapping("/v1/user-block") | ||
@RequiredArgsConstructor | ||
public class UserBlockControllerV1 { | ||
|
||
private final UserBlockService userBlockService; | ||
|
||
@Operation(description = "사용자가 다른 사용자를 차단한다") | ||
@PostMapping | ||
public ResponseEntity<UserBlockCreateResponse> blockUser(@RequestBody UserBlockRequest userBlockRequest) { | ||
UserBlockCreateResponse blockCreateResponse = userBlockService.blockUser(userBlockRequest); | ||
|
||
return ResponseEntity.ok().body(blockCreateResponse); | ||
} | ||
|
||
@Operation(description = "사용자가 차단한 사용자들의 리스트를 검색한다") | ||
@GetMapping | ||
public ResponseEntity<List<UserBlockReadResponse>> getBlockedUsers() { | ||
List<UserBlockReadResponse> userBlockReadResponses = userBlockService.getBlockedUsers(); | ||
|
||
return ResponseEntity.ok().body(userBlockReadResponses); | ||
} | ||
|
||
@Operation(description = "사용자가 다른 사용자에 대한 차단을 해제한다") | ||
@DeleteMapping | ||
public ResponseEntity<UserBlockDeleteResponse> unblockUser(@RequestBody UserBlockRequest userBlockRequest) { | ||
UserBlockDeleteResponse blockDeleteResponse = userBlockService.unblockUser(userBlockRequest); | ||
|
||
return ResponseEntity.ok().body(blockDeleteResponse); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
src/main/java/com/soyeon/nubim/domain/user_block/UserBlockMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.soyeon.nubim.domain.user_block; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.springframework.stereotype.Component; | ||
|
||
import com.soyeon.nubim.domain.user.User; | ||
import com.soyeon.nubim.domain.user.UserMapper; | ||
import com.soyeon.nubim.domain.user.dto.UserSimpleResponseDto; | ||
import com.soyeon.nubim.domain.user_block.dto.UserBlockCreateResponse; | ||
import com.soyeon.nubim.domain.user_block.dto.UserBlockReadResponse; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class UserBlockMapper { | ||
|
||
private final UserMapper userMapper; | ||
|
||
public UserBlock toEntity(User blockingUser, User blockedUser) { | ||
return UserBlock.builder() | ||
.blockingUser(blockingUser) | ||
.blockedUser(blockedUser) | ||
.build(); | ||
} | ||
|
||
public UserBlockCreateResponse toUserBlockCreateResponse(UserBlock userBlock) { | ||
UserSimpleResponseDto blockedUser = userMapper.toUserSimpleResponseDto(userBlock.getBlockedUser()); | ||
|
||
return UserBlockCreateResponse.builder() | ||
.blockedUser(blockedUser) | ||
.blockedAt(userBlock.getBlockedAt()) | ||
.build(); | ||
} | ||
|
||
public UserBlockReadResponse toUserBlockReadResponse(UserBlock userBlock) { | ||
UserSimpleResponseDto blockedUser = userMapper.toUserSimpleResponseDto(userBlock.getBlockedUser()); | ||
|
||
return UserBlockReadResponse.builder() | ||
.blockedUser(blockedUser) | ||
.blockedAt(userBlock.getBlockedAt()) | ||
.build(); | ||
} | ||
|
||
public List<UserBlockReadResponse> toUserBlockReadResponses(List<UserBlock> userBlocks) { | ||
List<UserBlockReadResponse> userBlockReadResponses = new ArrayList<>(userBlocks.size()); | ||
for (UserBlock userBlock : userBlocks) { | ||
userBlockReadResponses.add(toUserBlockReadResponse(userBlock)); | ||
} | ||
return userBlockReadResponses; | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/main/java/com/soyeon/nubim/domain/user_block/UserBlockRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.soyeon.nubim.domain.user_block; | ||
|
||
import java.util.List; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.data.jpa.repository.Modifying; | ||
import org.springframework.data.jpa.repository.Query; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import com.soyeon.nubim.domain.user.User; | ||
|
||
@Repository | ||
public interface UserBlockRepository extends JpaRepository<UserBlock, Long> { | ||
|
||
@Query("SELECT EXISTS( SELECT 1 FROM UserBlock ub" | ||
+ " WHERE ub.blockingUser = :blockingUser AND ub.blockedUser = :blockedUser)") | ||
boolean existsByBlockingUserAndBlockedUser(User blockingUser, User blockedUser); | ||
|
||
@Query("SELECT EXISTS( SELECT 1 FROM UserBlock ub WHERE " | ||
+ "(ub.blockingUser = :user1 AND ub.blockedUser = :user2 ) OR " | ||
+ "(ub.blockingUser = :user2 AND ub.blockedUser = :user1 ))") | ||
boolean existsBlockRelationBetweenUser(User user1, User user2); | ||
|
||
@Query("SELECT ub FROM UserBlock ub WHERE ub.blockingUser = :blockingUser") | ||
List<UserBlock> findBlockedUsersByBlockingUser(User blockingUser); | ||
|
||
@Modifying | ||
@Query("DELETE FROM UserBlock ub WHERE ub.blockingUser = :blockingUser AND ub.blockedUser = :blockedUser") | ||
int deleteByBlockingUserAndBlockedUser(User blockingUser, User blockedUser); | ||
} |
90 changes: 90 additions & 0 deletions
90
src/main/java/com/soyeon/nubim/domain/user_block/UserBlockService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package com.soyeon.nubim.domain.user_block; | ||
|
||
import java.util.List; | ||
|
||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import com.soyeon.nubim.domain.user.LoggedInUserService; | ||
import com.soyeon.nubim.domain.user.User; | ||
import com.soyeon.nubim.domain.user.UserService; | ||
import com.soyeon.nubim.domain.user_block.dto.UserBlockCreateResponse; | ||
import com.soyeon.nubim.domain.user_block.dto.UserBlockDeleteResponse; | ||
import com.soyeon.nubim.domain.user_block.dto.UserBlockReadResponse; | ||
import com.soyeon.nubim.domain.user_block.dto.UserBlockRequest; | ||
import com.soyeon.nubim.domain.user_block.exception.AlreadyBlockedException; | ||
import com.soyeon.nubim.domain.user_block.exception.BlockedUserAccessDeniedException; | ||
import com.soyeon.nubim.domain.user_block.exception.MultipleUserBlockDeletedException; | ||
import com.soyeon.nubim.domain.user_block.exception.SelfBlockException; | ||
import com.soyeon.nubim.domain.user_block.exception.UserBlockDeleteFailException; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class UserBlockService { | ||
|
||
private static final int DELETE_SUCCESS = 1; | ||
private static final int DELETE_FAIL = 0; | ||
private final LoggedInUserService loggedInUserService; | ||
private final UserService userService; | ||
private final UserBlockRepository userBlockRepository; | ||
private final UserBlockMapper userBlockMapper; | ||
|
||
public UserBlockCreateResponse blockUser(UserBlockRequest userBlockRequest) { | ||
Long currentUserId = loggedInUserService.getCurrentUserId(); | ||
User blockingUser = new User(currentUserId); | ||
User blockedUser = userService.findByNickname(userBlockRequest.getBlockedUserNickname()); | ||
|
||
checkSelfBlock(blockingUser, blockedUser); | ||
validateUserBlockNotExists(blockingUser, blockedUser); | ||
|
||
UserBlock userBlock = userBlockMapper.toEntity(blockingUser, blockedUser); | ||
UserBlock savedUserBlock = userBlockRepository.save(userBlock); | ||
|
||
return userBlockMapper.toUserBlockCreateResponse(savedUserBlock); | ||
} | ||
|
||
public List<UserBlockReadResponse> getBlockedUsers() { | ||
Long currentUserId = loggedInUserService.getCurrentUserId(); | ||
User blockingUser = new User(currentUserId); | ||
|
||
List<UserBlock> blockedUsers = userBlockRepository.findBlockedUsersByBlockingUser(blockingUser); | ||
return userBlockMapper.toUserBlockReadResponses(blockedUsers); | ||
} | ||
|
||
@Transactional | ||
public UserBlockDeleteResponse unblockUser(UserBlockRequest userBlockRequest) { | ||
Long currentUserId = loggedInUserService.getCurrentUserId(); | ||
User blockingUser = new User(currentUserId); | ||
User blockedUser = userService.findByNickname(userBlockRequest.getBlockedUserNickname()); | ||
|
||
int deleteResult = userBlockRepository.deleteByBlockingUserAndBlockedUser(blockingUser, blockedUser); | ||
|
||
if (deleteResult == DELETE_SUCCESS) { | ||
return new UserBlockDeleteResponse("unblock success"); | ||
} | ||
if (deleteResult == DELETE_FAIL) { | ||
throw new UserBlockDeleteFailException(); | ||
} | ||
throw new MultipleUserBlockDeletedException(); | ||
} | ||
|
||
public void checkBlockRelation(User currentUser, User targetUser) { | ||
if (userBlockRepository.existsBlockRelationBetweenUser(currentUser, targetUser)) { | ||
throw new BlockedUserAccessDeniedException(); | ||
} | ||
} | ||
|
||
private void checkSelfBlock(User blockingUser, User blockedUser) { | ||
if (blockingUser.getUserId().equals(blockedUser.getUserId())) { | ||
throw new SelfBlockException(); | ||
} | ||
} | ||
|
||
private void validateUserBlockNotExists(User blockingUser, User blockedUser) { | ||
if (userBlockRepository.existsByBlockingUserAndBlockedUser(blockingUser, blockedUser)) { | ||
throw new AlreadyBlockedException(); | ||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/com/soyeon/nubim/domain/user_block/dto/UserBlockCreateResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.soyeon.nubim.domain.user_block.dto; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
import com.soyeon.nubim.domain.user.dto.UserSimpleResponseDto; | ||
|
||
import lombok.Builder; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@Builder | ||
public class UserBlockCreateResponse { | ||
private UserSimpleResponseDto blockedUser; | ||
private LocalDateTime blockedAt; | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/com/soyeon/nubim/domain/user_block/dto/UserBlockDeleteResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.soyeon.nubim.domain.user_block.dto; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
public class UserBlockDeleteResponse { | ||
private String message; | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/com/soyeon/nubim/domain/user_block/dto/UserBlockReadResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.soyeon.nubim.domain.user_block.dto; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
import com.soyeon.nubim.domain.user.dto.UserSimpleResponseDto; | ||
|
||
import lombok.Builder; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@Builder | ||
public class UserBlockReadResponse { | ||
private UserSimpleResponseDto blockedUser; | ||
private LocalDateTime blockedAt; | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/com/soyeon/nubim/domain/user_block/dto/UserBlockRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.soyeon.nubim.domain.user_block.dto; | ||
|
||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
@Getter | ||
@Setter | ||
public class UserBlockRequest { | ||
private String blockedUserNickname; | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/com/soyeon/nubim/domain/user_block/exception/AlreadyBlockedException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.soyeon.nubim.domain.user_block.exception; | ||
|
||
import org.springframework.http.HttpStatus; | ||
import org.springframework.web.server.ResponseStatusException; | ||
|
||
public class AlreadyBlockedException extends ResponseStatusException { | ||
public AlreadyBlockedException() { | ||
super(HttpStatus.CONFLICT, "Already Blocked User"); | ||
} | ||
} |
Oops, something went wrong.