본문 바로가기
프로젝트/PongGame

RelationService

by 히포파타마스 2022. 6. 3.

RelationService

Relation에 대한 business Logic을 처리하는 RelationService를 생성하고 구현한다.

 

 

 

 

1. RelationService

■ RelationService

[RelationService]

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class RelationService {

    private final AccountRepository accountRepository;
    private final RelationRepository relationRepository;
    
    .
    .
    .
    
}

 

 

□ requestFriend

fromAccountId -> toAccountId 방향의 "친구 요청" Relation을 생성한다.

 

[requestFriend]

@Transactional
public Relation requestFriend(Long fromAccountId, Long toAccountId) {

    Account fromAccount = accountRepository.findById(fromAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));
    Account toAccount = accountRepository.findById(toAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));

    Relation request = Relation.builder()
            .fromAccount(fromAccount)
            .toAccount(toAccount)
            .relationState(RelationState.REQUEST)
            .build();

    return relationRepository.save(request);
}

 

 

□ acceptFriend

fromAccount -> toAccount 방향의 "친구 요청" 상태인 Relation을 "친구" 상태로 변경한다.

toAccount -> fromAccount 방향의 "친구" 상태인 Relation이 없다면 새로 생성한다.

 

[acceptFriend]

@Transactional
public void acceptFriend(Long fromAccountId, Long toAccountId) {

    Account fromAccount = accountRepository.findById(fromAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));
    Account toAccount = accountRepository.findById(toAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));

    Relation requestingRelation = relationRepository
            .findByFromAccountAndToAccountAndRelationStateEquals(fromAccount, toAccount, RelationState.REQUEST)
            .orElseThrow(() -> new NonExistResourceException("해당 fromAccount를 갖는 Relation을 찾을 수 없습니다."));

    requestingRelation.makeFriend();

    Optional<Relation> optionalRelation = relationRepository.findByFromAccountAndToAccount(toAccount, fromAccount);
    if (optionalRelation.isEmpty()) {   //[1]
        Relation friend = Relation.builder()
                .fromAccount(fromAccount)
                .toAccount(toAccount)
                .relationState(RelationState.FRIEND)
                .build();

        relationRepository.save(friend);
        return;
    }
    optionalRelation.get().makeFriend();   //[2]
}

● [1] : toAccount -> fromAccount 방향의 Relation이 존재하지 않는다면 "친구" 상태인 Relation을 새로 생성

● [2] : toAccount -> fromAccount 방향의 Relation이 존재한다면 "친구" 상태로 변경

            "차단" 상태의 Account가 fromAccount에 들어올 수 없도록 Controller에서 검증할 것이기 때문에 "차단" 상태의 Relation일

            경우는 생각하지 않아도 된다.

 

 

□ rejectRequest

fromAccount -> toAccount 방향의 "친구 요청" 상태인 Relation을 삭제한다.

 

[rejectRequest]

@Transactional
public void rejectRequest(Long fromAccountId, Long toAccountId) {
    Account fromAccount = accountRepository.findById(fromAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 id를 갖는 Account를 찾을 수 없습니다."));
    Account toAccount = accountRepository.findById(toAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 id를 갖는 Account를 찾을 수 없습니다."));

    Relation relation = relationRepository
            .findByFromAccountAndToAccountAndRelationStateEquals(fromAccount, toAccount, RelationState.REQUEST)
            .orElseThrow(() -> new NonExistResourceException("해당 친구 요청을 찾을 수 없습니다."));

    relation.softDelete();
}

 

 

□ block

fromAccount -> toAccount 방향의 Relation을 "차단" 상태로 만든다.

Relation이 없을 경위 "차단" 상태로 생성한다.

 

[block]

@Transactional
public void block(Long fromAccountId, Long toAccountId) {
    Account fromAccount = accountRepository.findById(fromAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 id를 갖는 Account를 찾을 수 없습니다."));
    Account toAccount = accountRepository.findById(toAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 id를 갖는 Account를 찾을 수 없습니다."));

    Optional<Relation> optionalRelation = relationRepository.findByFromAccountAndToAccount(fromAccount, toAccount);
    if (optionalRelation.isEmpty()) {
        Relation blockRelation = Relation.builder()
                .fromAccount(fromAccount)
                .toAccount(toAccount)
                .relationState(RelationState.BLOCK)
                .build();
        relationRepository.save(blockRelation);
        return;
    }

    optionalRelation.get().block();
}

 

 

□ unbBlock

fromAccount -> toAccount 방향의 "차단" 상태인 Relation을 삭제한다.

 

[unbBlock]

@Transactional
public void unBlock(Long fromAccountId, Long toAccountId) {
    Account fromAccount = accountRepository.findById(fromAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 id를 갖는 Account를 찾을 수 없습니다."));
    Account toAccount = accountRepository.findById(toAccountId)
            .orElseThrow(() -> new NonExistResourceException("해당 id를 갖는 Account를 찾을 수 없습니다."));

    Relation relation = relationRepository.findByFromAccountAndToAccountAndRelationStateEquals(fromAccount,
                    toAccount, RelationState.BLOCK)
            .orElseThrow(() -> new NonExistResourceException("해당 Account의 Block된 Relation을 찾을 수 없습니다."));
    relation.softDelete();
}

 

 

□ 조회용 메서드

Relation에 대한 각종 조회용 메서드

RelationRepository를 통해, Relation을 List나 Page로 반환한다.

 

[조회용 메서드]

public List<Relation> findAllRequest(Long accountId) {
    return relationRepository.findAllRequest(accountId);
}

public QueryResults<Relation> findRequestsByPage(Long accountId, Pageable pageable) {
    return relationRepository.findRequestsByPage(accountId, pageable);
}

public List<Relation> findAllRequestFromOther(Long accountId) {
    return relationRepository.findAllRequestFromOther(accountId);
}

public QueryResults<Relation> findRequestsFromOtherByPage(Long accountId, Pageable pageable) {
    return relationRepository.findRequestsFromOtherByPage(accountId, pageable);
}

public List<Relation> findAllFriend(Long accountId) {
    return relationRepository.findAllFriend(accountId);
}

public QueryResults<Relation> findFriendsByPage(Long accountId, Pageable pageable) {
    return relationRepository.findFriendsByPage(accountId, pageable);
}

public List<Relation> findAllBlock(Long accountId) {
    return relationRepository.findAllBlock(accountId);
}

public QueryResults<Relation> findBlocksByPage(Long accountId, Pageable pageable) {
    return relationRepository.findBlocksByPage(accountId, pageable);
}

 

 

 

■ RelationService 전체 코드

[RelationService 전체 코드]

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class RelationService {

    private final AccountRepository accountRepository;
    private final RelationRepository relationRepository;
    private final ApplicationEventPublisher eventPublisher;

    @Transactional
    public Relation requestFriend(Long fromAccountId, Long toAccountId) {

        Account fromAccount = accountRepository.findById(fromAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));
        Account toAccount = accountRepository.findById(toAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));

        Relation request = Relation.builder()
                .fromAccount(fromAccount)
                .toAccount(toAccount)
                .relationState(RelationState.REQUEST)
                .build();

        return relationRepository.save(request);
    }

    @Transactional
    public void acceptFriend(Long fromAccountId, Long toAccountId) {

        Account fromAccount = accountRepository.findById(fromAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));
        Account toAccount = accountRepository.findById(toAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 Id를 갖는 Account를 찾을 수 없습니다."));

        Relation requestingRelation = relationRepository
                .findByFromAccountAndToAccountAndRelationStateEquals(fromAccount, toAccount, RelationState.REQUEST)
                .orElseThrow(() -> new NonExistResourceException("해당 fromAccount를 갖는 Relation을 찾을 수 없습니다."));

        requestingRelation.makeFriend();

        Optional<Relation> optionalRelation = relationRepository.findByFromAccountAndToAccount(toAccount, fromAccount);
        if (optionalRelation.isEmpty()) {
            Relation friend = Relation.builder()
                    .fromAccount(fromAccount)
                    .toAccount(toAccount)
                    .relationState(RelationState.FRIEND)
                    .build();

            relationRepository.save(friend);
            return;
        }
        optionalRelation.get().makeFriend();
    }

    @Transactional
    public void rejectRequest(Long fromAccountId, Long toAccountId) {
        Account fromAccount = accountRepository.findById(fromAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 id를 갖는 Account를 찾을 수 없습니다."));
        Account toAccount = accountRepository.findById(toAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 id를 갖는 Account를 찾을 수 없습니다."));

        Relation relation = relationRepository
                .findByFromAccountAndToAccountAndRelationStateEquals(fromAccount, toAccount, RelationState.REQUEST)
                .orElseThrow(() -> new NonExistResourceException("해당 친구 요청을 찾을 수 없습니다."));

        relation.softDelete();
    }

    @Transactional
    public void block(Long fromAccountId, Long toAccountId) {
        Account fromAccount = accountRepository.findById(fromAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 id를 갖는 Account를 찾을 수 없습니다."));
        Account toAccount = accountRepository.findById(toAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 id를 갖는 Account를 찾을 수 없습니다."));

        Optional<Relation> optionalRelation = relationRepository.findByFromAccountAndToAccount(fromAccount, toAccount);
        if (optionalRelation.isEmpty()) {
            Relation blockRelation = Relation.builder()
                    .fromAccount(fromAccount)
                    .toAccount(toAccount)
                    .relationState(RelationState.BLOCK)
                    .build();
            relationRepository.save(blockRelation);
            return;
        }

        optionalRelation.get().block();
    }

    @Transactional
    public void unBlock(Long fromAccountId, Long toAccountId) {
        Account fromAccount = accountRepository.findById(fromAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 id를 갖는 Account를 찾을 수 없습니다."));
        Account toAccount = accountRepository.findById(toAccountId)
                .orElseThrow(() -> new NonExistResourceException("해당 id를 갖는 Account를 찾을 수 없습니다."));

        Relation relation = relationRepository.findByFromAccountAndToAccountAndRelationStateEquals(fromAccount,
                        toAccount, RelationState.BLOCK)
                .orElseThrow(() -> new NonExistResourceException("해당 Account의 Block된 Relation을 찾을 수 없습니다."));
        relation.softDelete();
    }

    public List<Relation> findAllRequest(Long accountId) {
        return relationRepository.findAllRequest(accountId);
    }

    public QueryResults<Relation> findRequestsByPage(Long accountId, Pageable pageable) {
        return relationRepository.findRequestsByPage(accountId, pageable);
    }

    public List<Relation> findAllRequestFromOther(Long accountId) {
        return relationRepository.findAllRequestFromOther(accountId);
    }

    public QueryResults<Relation> findRequestsFromOtherByPage(Long accountId, Pageable pageable) {
        return relationRepository.findRequestsFromOtherByPage(accountId, pageable);
    }

    public List<Relation> findAllFriend(Long accountId) {
        return relationRepository.findAllFriend(accountId);
    }

    public QueryResults<Relation> findFriendsByPage(Long accountId, Pageable pageable) {
        return relationRepository.findFriendsByPage(accountId, pageable);
    }

    public List<Relation> findAllBlock(Long accountId) {
        return relationRepository.findAllBlock(accountId);
    }

    public QueryResults<Relation> findBlocksByPage(Long accountId, Pageable pageable) {
        return relationRepository.findBlocksByPage(accountId, pageable);
    }
}

 

 

 

'프로젝트 > PongGame' 카테고리의 다른 글

RelationController  (0) 2022.06.03
RelationRepository  (0) 2022.06.01
Relation API 명세  (0) 2022.05.30
myLogin  (0) 2022.05.18
Account Controller  (0) 2022.05.11

댓글