채팅 10분 이내 응답시 보너스를 주는 로직을 짜보자
접근법)
chatroom의 Id값을 찾아야 된다는 가정하여 코드를 만들었습니다.
다행히도 프론트에서 상대의 ID값을 주기로 하였습니다.
1. 채팅목록 레포지토리
Param으로부터 유저ID와 상대ID를 받아서, 요청하였습니다.
@Query문에
requesterId(요청자 아이디) = 유저아이디
acceptorId(수신자 아이디) = 상대아이디
// 내가 요청한 채팅방
@Query("SELECT cr FROM ChatRoom cr WHERE cr.requesterId =:userId AND cr.acceptorId = :opponentUserId")
ChatRoom findMyRequestChatRoom(@Param("userId") Long userId, @Param("opponentUserId") Long opponentUserId);
반대일 경우도 있을 수 있기 때문에 else문을 통해서 반대의 경우에도 조회하는 쿼리문을 만들었습니다.
// 내가 요청받은 채팅방
@Query("SELECT cr FROM ChatRoom cr WHERE cr.requesterId = :opponentUserId AND cr.acceptorId = :userId")
ChatRoom findMyAcceptorIdChatRoom(@Param("userId") Long userId, @Param("opponentUserId") Long opponentUserId);
평가하기 서비스
// 내 포지션이 바이어라면 -> roomId를 모를 떄
if (myPosition.equals("buyer")) {
chatRoomChek = chatRoomRepository.findMyRequestChatRoom(user.getId(), opponentUserId);
// 내포지션이 셀러라면
} else {
chatRoomChek = chatRoomRepository.findMyAcceptorIdChatRoom(user.getId(), opponentUserId);
}
2. 채팅 레포지토리
조건1 : 유저Id와 조건2 : 채팅룸Id을 조회하였습니다.
나의 메시지 목록과 상대의 마세지 목록을 리스트로 조회하였습니다.
// 내가 요청받은 채팅방
@Query("SELECT cm FROM ChatMessage cm WHERE cm.userId =:userId AND cm.roomId =:roomId")
List<ChatMessage> findMyChatMessage(@Param("userId") Long userId, @Param("roomId") Long roomId);
평가하기 서비스
Long chatRoomId = chatRoomChek.getId();
Long myUserId = user.getId();
myMessageList = chatMessageRepository.findMyChatMessage(myUserId , chatRoomId);
opponentMessageList = chatMessageRepository.findMyChatMessage(opponentUserId, chatRoomId);
3. 최초의 메시지 시간을 조회한다.
1번째 메시지를 참고하기위해서 for문을 통해서 cnt값이 1일 경우 break를 하여
firstMyTime과 firstOppoentTime을 조회하여 -> ChronoUnit.MINUTES.between(조건1, 조건2)을 통해서
조건1과 조건2사이의 시간차이를 구하였다.
-> if문을 통해서 minut값이 10이하일 경우 true값을 반환하고, 아닐경우는 false값을 반환하여
-> 이후 보너스 점수를 줄 수 있는 가능성을 열어 놓았다.
걱정)
=> 본인은 아직 웹소켓의 개념을 잘 모르기 때문에 H2콘솔을 통해서 직접 데이터를 입력하였는데,
=> 실제로 테스트를 하게 되었을 때 어떤 오류가 발생할 지는 미지수이다.
// 각자의 최초 메시지의 시간을 조회한다
int cnt = 0;
LocalDateTime firstMyTime = null;
LocalDateTime firstOppoentTime = null;
for (ChatMessage myChat : myMessageList) {
System.out.println("내 첫메시지 내용 : " + myChat.getMessage());
firstMyTime = myChat.getCreatedAt();
cnt++;
if (cnt == 1) {
break;
}
}
cnt = 0;
for (ChatMessage opponetChat : opponentMessageList) {
System.out.println("상대의 첫 메시지 내용 : " + opponetChat.getMessage());
firstOppoentTime = opponetChat.getCreatedAt();
cnt++;
if (cnt == 1) {
break;
}
}
System.out.println("내 첫메시지 : " + firstMyTime.getMinute());
Long minute = ChronoUnit.MINUTES.between(firstMyTime, firstOppoentTime);
System.out.println("비투인 사이 시간 " + minute);
boolean chatTime = false;
if (minute <= 10) {
chatTime = true;
System.out.println("10분 이내인가 : " + chatTime);
}
// 성훈 - 상대 평점주기
@Transactional
public void gradeScore(GradeScoreRequestDto gradeScoreRequestDto, UserDetailsImpl userDetails) {
User user = userRepository.findById(userDetails.getUserId()).orElseThrow(
() -> new IllegalArgumentException("user not found")
);
// 상대 userId
Long opponentUserId = gradeScoreRequestDto.getUserId();
// 평가주기
float gradeScore = gradeScoreRequestDto.getScore();
// 상대찾기
User opponentUser = userRepository.findById(opponentUserId).orElseThrow(() -> new IllegalArgumentException("user not found"));
// 상대 등급
String opponentDegree;
// 상대의 총점수
float opponentUserTotalGrade = opponentUser.getTotalGrade();
// 상대 평가점수
float opponentGrade;
// 상대 평가자 수
int opponentRaterCnt = opponentUser.getRaterCount();
// 점수
// 거래내역 조회
Long barterId = gradeScoreRequestDto.getBarterId();
Barter barter = barterRepository.findById(barterId).orElseThrow(() -> new IllegalArgumentException("barter not found"));
System.out.println("거래상태 : " + barter.getStatus());
System.out.println("2번째 예외처리 : " + opponentUserId);
System.out.println("바이어아이디 : " + barter.getBuyerId());
System.out.println("셀러아이디 : " + barter.getSellerId());
// // 이미 평가를 완료한 경우
// if (barter.getStatus() != 3) {
// throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, "올바른 요청이 아닙니다");
// // 거래내역의 상대 Id와 Request로 전달받은 상대방의 정보와 다를 경우
// } else if ((opponentUserId != barter.getBuyerId()) && (opponentUserId != barter.getSellerId())) {
// throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, "올바른 요청이 아닙니다");
// // 자기 자신에게 점수를 줄 경우
// } else if (opponentUserId == user.getId()) {
// throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, "올바른 요청이 아닙니다");
// // 거래가 완료되지 않았을 경우
// } else if (barter.getStatus() == 0) {
// throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, "올바른 요청이 아닙니다");
// }
//협의 중 -> 총점수 = 이전의 총점수 + 평가된 평점
opponentUserTotalGrade = opponentUserTotalGrade + gradeScore;
// 평가자수 +1
opponentRaterCnt = opponentRaterCnt + 1;
// 유저의 평균 평점
opponentGrade = opponentUserTotalGrade / opponentRaterCnt;
// 10분이네 응답 보너스
// 내 포지션 확인
String myPosition = null;
if (barter.getSellerId().equals(opponentUserId)) {
myPosition = "buyer";
} else {
myPosition = "seller";
}
System.out.println("내 포지션은 : " + myPosition);
ChatRoom chatRoomChek;
List<ChatMessage> myMessageList;
List<ChatMessage> opponentMessageList;
// 내 포지션이 바이어라면 -> roomId를 모를 떄
if (myPosition.equals("buyer")) {
chatRoomChek = chatRoomRepository.findMyRequestChatRoom(user.getId(), opponentUserId);
// 내포지션이 셀러라면
} else {
chatRoomChek = chatRoomRepository.findMyAcceptorIdChatRoom(user.getId(), opponentUserId);
}
System.out.println("채팅방 아이디 " + chatRoomChek.getId());
System.out.println("유저아이디 " + user.getId());
System.out.println("상대 아이디 :" + opponentUserId);
Long chatRoomId = chatRoomChek.getId();
Long myUserId = user.getId();
myMessageList = chatMessageRepository.findMyChatMessage(myUserId , chatRoomId);
opponentMessageList = chatMessageRepository.findMyChatMessage(opponentUserId, chatRoomId);
System.out.println("채팅방 아이디는 : " + chatRoomChek.getRequesterId());
// 각자의 최초 메시지의 시간을 조회한다
int cnt = 0;
LocalDateTime firstMyTime = null;
LocalDateTime firstOppoentTime = null;
for (ChatMessage myChat : myMessageList) {
System.out.println("내 첫메시지 내용 : " + myChat.getMessage());
firstMyTime = myChat.getCreatedAt();
cnt++;
if (cnt == 1) {
break;
}
}
cnt = 0;
for (ChatMessage opponetChat : opponentMessageList) {
System.out.println("상대의 첫 메시지 내용 : " + opponetChat.getMessage());
firstOppoentTime = opponetChat.getCreatedAt();
cnt++;
if (cnt == 1) {
break;
}
}
System.out.println("내 첫메시지 : " + firstMyTime.getMinute());
Long minute = ChronoUnit.MINUTES.between(firstMyTime, firstOppoentTime);
System.out.println("비투인 사이 시간 " + minute);
boolean chatTime = false;
if (minute <= 10) {
chatTime = true;
System.out.println("10분 이내인가 : " + chatTime);
}
//
// 상대의 전체 점수에 1, 2은 - / 3은 0 / 4, 5은 +
if (gradeScore <= 2) {
opponentUserTotalGrade = opponentUserTotalGrade - (gradeScore - 3.0f);
} else if (gradeScore >= 4) {
opponentUserTotalGrade = opponentUserTotalGrade + (3 - gradeScore);
}
// 10분 이내 응답했을 때의 보너스
if (chatTime) {
opponentUserTotalGrade = opponentUserTotalGrade + 2.0f;
}
//임의로 넣어줌 -> 상의해야됨
if (opponentUserTotalGrade >= 200.0f) {
opponentDegree = "물물박사";
} else if (opponentUserTotalGrade >= 100.0f) {
opponentDegree = "물물석사";
} else if (opponentUserTotalGrade >= 30.0f) {
opponentDegree = "물물학사";
} else if (opponentUserTotalGrade >= 10.0f) {
opponentDegree = "물물학생";
} else {
opponentDegree = "물물어린이";
}
opponentUser.updateScore(
opponentUserTotalGrade,
opponentGrade,
opponentRaterCnt,
opponentDegree
);
// 거래완료인 상태가 아니면 예외처리
String[] barterIdList = barter.getBarter().split(";");
String[] buyerItemId = barterIdList[0].split(",");
String sellerItemId = barterIdList[1];
int status = 4;
for (String eachBuyer : buyerItemId) {
Long buyerId = Long.valueOf(eachBuyer);
Item buyerItem = itemRepository.findById(buyerId).orElseThrow(
() -> new IllegalArgumentException("buyerItem not found"));
buyerItem.statusUpdate(buyerItem.getId(), status);
}
//셀러(유저)의 물품을 찾아서 정보를 넣기
Long sellerId = Long.parseLong(sellerItemId);
Item sellerItem = itemRepository.findById(sellerId).orElseThrow(
() -> new IllegalArgumentException("sellerItem not found")
);
sellerItem.statusUpdate(sellerItem.getId(), status);
// 유저 정보를 업데이트 이후 status를 거래완료(3) -> 평가완료(4)으로 업데이트를 한다.
barter.updateBarter(status);
}
}
채팅 메시지 레포지토리
package com.sparta.mulmul.repository.chat;
import com.sparta.mulmul.model.ChatMessage;
import com.sparta.mulmul.model.ChatRoom;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface ChatMessageRepository extends JpaRepository<ChatMessage, Long> {
ChatMessage findByUserId(Long oppentUserId);
List<ChatMessage> findAllByRoomIdAndUserId(Long roomId, Long userId);
// 내가 요청받은 채팅방
@Query("SELECT cm FROM ChatMessage cm WHERE cm.userId =:userId AND cm.roomId =:roomId")
List<ChatMessage> findMyChatMessage(@Param("userId") Long userId, @Param("roomId") Long roomId);
}
채팅룸 메시지 레포지토리
package com.sparta.mulmul.repository.chat;
import com.sparta.mulmul.model.ChatRoom;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface ChatRoomRepository extends JpaRepository<ChatRoom, Long> {
ChatRoom findByRequesterIdAndAcceptorId(Long id, Long opponentUserId);
// 성훈 - 내 아이템 찾기 (마이페이지)
// 내가 요청한 채팅방
@Query("SELECT cr FROM ChatRoom cr WHERE cr.requesterId =:userId AND cr.acceptorId = :opponentUserId")
ChatRoom findMyRequestChatRoom(@Param("userId") Long userId, @Param("opponentUserId") Long opponentUserId);
// 내가 요청받은 채팅방
@Query("SELECT cr FROM ChatRoom cr WHERE cr.requesterId = :opponentUserId AND cr.acceptorId = :userId")
ChatRoom findMyAcceptorIdChatRoom(@Param("userId") Long userId, @Param("opponentUserId") Long opponentUserId);
}
출력결과
FALSE
거래상태 : 4
2번째 예외처리 : 2
바이어아이디 : 1
셀러아이디 : 2
내 포지션은 : buyer
Hibernate: select chatroom0_.room_id as room_id1_3_, chatroom0_.created_at as created_2_3_, chatroom0_.acceptor_id as acceptor3_3_, chatroom0_.acceptor_show as acceptor4_3_, chatroom0_.requester_id as requeste5_3_, chatroom0_.requester_show as requeste6_3_ from chat_room chatroom0_ where chatroom0_.requester_id=? and chatroom0_.acceptor_id=?
채팅방 아이디 1
유저아이디 1
상대 아이디 :2
Hibernate: select chatmessag0_.message_id as message_1_2_, chatmessag0_.created_at as created_2_2_, chatmessag0_.is_read as is_read3_2_, chatmessag0_.message as message4_2_, chatmessag0_.room_id as room_id5_2_, chatmessag0_.type as type6_2_, chatmessag0_.user_id as user_id7_2_ from chat_message chatmessag0_ where chatmessag0_.user_id=? and chatmessag0_.room_id=?
Hibernate: select chatmessag0_.message_id as message_1_2_, chatmessag0_.created_at as created_2_2_, chatmessag0_.is_read as is_read3_2_, chatmessag0_.message as message4_2_, chatmessag0_.room_id as room_id5_2_, chatmessag0_.type as type6_2_, chatmessag0_.user_id as user_id7_2_ from chat_message chatmessag0_ where chatmessag0_.user_id=? and chatmessag0_.room_id=?
채팅방 아이디는 : 1
내 첫메시지 내용 : ㅁㄴㅇㄹ
상대의 첫 메시지 내용 : ㅂㅈㄷㄱ
내 첫메시지 : 58
비투인 사이 시간 22
TRUE
거래상태 : 2
2번째 예외처리 : 2
바이어아이디 : 1
셀러아이디 : 2
내 포지션은 : buyer
Hibernate: select chatroom0_.room_id as room_id1_3_, chatroom0_.created_at as created_2_3_, chatroom0_.acceptor_id as acceptor3_3_, chatroom0_.acceptor_show as acceptor4_3_, chatroom0_.requester_id as requeste5_3_, chatroom0_.requester_show as requeste6_3_ from chat_room chatroom0_ where chatroom0_.requester_id=? and chatroom0_.acceptor_id=?
채팅방 아이디 1
유저아이디 1
상대 아이디 :2
Hibernate: select chatmessag0_.message_id as message_1_2_, chatmessag0_.created_at as created_2_2_, chatmessag0_.is_read as is_read3_2_, chatmessag0_.message as message4_2_, chatmessag0_.room_id as room_id5_2_, chatmessag0_.type as type6_2_, chatmessag0_.user_id as user_id7_2_ from chat_message chatmessag0_ where chatmessag0_.user_id=? and chatmessag0_.room_id=?
Hibernate: select chatmessag0_.message_id as message_1_2_, chatmessag0_.created_at as created_2_2_, chatmessag0_.is_read as is_read3_2_, chatmessag0_.message as message4_2_, chatmessag0_.room_id as room_id5_2_, chatmessag0_.type as type6_2_, chatmessag0_.user_id as user_id7_2_ from chat_message chatmessag0_ where chatmessag0_.user_id=? and chatmessag0_.room_id=?
채팅방 아이디는 : 1
내 첫메시지 내용 : ㅁㄴㅇㄹ
상대의 첫 메시지 내용 : ㅂㅈㄷㄱ
내 첫메시지 : 58
비투인 사이 시간 1
10분 이내인가 : true
채팅 웹소켓도입이후 새로 바뀐 ERD
'일기 > 항해99' 카테고리의 다른 글
[항해99 6기] 실전프로젝트 3주차 - 느낀점 (0) | 2022.05.15 |
---|---|
[항해99 6기] 실전프로젝트 2주차 - 느낀점 (0) | 2022.05.08 |
[항해99 6기] 실전프로젝트 1주차 느낀점 (0) | 2022.05.01 |
[항해99 6기] 실전프로젝트 - 업무 방향성 업데이트 (0) | 2022.05.01 |
[항해99 6기] 실전프로젝트 - 예외성 검사 & 새로운 문제 (0) | 2022.04.29 |