Skip to content

Commit

Permalink
Merge pull request #37 from Kusitms-29th-Meetup-TeamE/feat/33/chatroom
Browse files Browse the repository at this point in the history
Feat: 채팅방 api 완성
  • Loading branch information
nohy6630 authored May 14, 2024
2 parents 791aa83 + abae856 commit b4b44dd
Show file tree
Hide file tree
Showing 38 changed files with 668 additions and 213 deletions.
16 changes: 0 additions & 16 deletions src/main/java/com/meetup/teame/backend/TestChatController.java

This file was deleted.

9 changes: 0 additions & 9 deletions src/main/java/com/meetup/teame/backend/TestChatReq.java

This file was deleted.

17 changes: 0 additions & 17 deletions src/main/java/com/meetup/teame/backend/TestChatRes.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.meetup.teame.backend.domain.activity.entity;

import com.meetup.teame.backend.domain.chatroom.entity.DirectChatRoom;
import com.meetup.teame.backend.domain.chatroom.entity.GroupChatRoom;
import com.meetup.teame.backend.domain.like.entity.ActivityLike;
import com.meetup.teame.backend.domain.personality.Personality;
import jakarta.persistence.*;
Expand Down Expand Up @@ -35,21 +37,28 @@ public class Activity {
@Comment("최대 참여 인원")
private Long maxParticipants;

@Comment("썸네일 이미지")
private String imageUrl;

@ElementCollection
@Enumerated(EnumType.STRING)
private List<Personality> personalities;

@OneToMany(mappedBy = "activity", cascade = CascadeType.ALL)
private List<ActivityLike> activityLikes;

public static Activity of(String title, String location, LocalDateTime time, Long maxParticipants, List<Personality> personalities) {
@OneToOne(mappedBy = "activity", cascade = CascadeType.ALL)
private GroupChatRoom groupChatRoom;

public static Activity of(String title, String location, LocalDateTime time, Long maxParticipants, List<Personality> personalities, String imageUrl) {
return Activity.builder()
.title(title)
.location(location)
.time(time)
.currentParticipants(0L)
.maxParticipants(maxParticipants)
.personalities(personalities)
.imageUrl(imageUrl)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package com.meetup.teame.backend.domain.chatroom.controller;

import com.meetup.teame.backend.domain.chatroom.dto.response.GroupChatRoomRes;
import com.meetup.teame.backend.domain.chatroom.dto.response.ReadDirectChatRoomsRes;
import com.meetup.teame.backend.domain.chatroom.dto.response.ReadGroupChatRoomsRes;
import com.meetup.teame.backend.domain.chatroom.service.ChatRoomService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.net.URI;

//todo : 채팅방목록 페이지 진입시 프론트쪽에서 연결해야할 웹소켓 토픽(채팅방당 한개씩)리스트를 반환하는 api를 주고 다 sub하게 만들어야 될듯
@RestController
Expand All @@ -33,7 +33,7 @@ public ResponseEntity<ReadGroupChatRoomsRes> readGroupChatRooms() {
.ok(chatRoomService.readGroupChatRooms());
}

@Operation(summary = "경험나누기 대화방(1:1 대화방) 목록 조회", description = """
@Operation(summary = "배움나누기 대화방(1:1 대화방) 목록 조회", description = """
현재 로그인한 유저의 경험나누기 대화방을 조회합니다.
현재는 임시로 고정된 더미 유저의 데이터를 전달하는 식으로 구현되어 있습니다.
Expand All @@ -45,4 +45,30 @@ public ResponseEntity<ReadDirectChatRoomsRes> readDirectChatRooms() {
return ResponseEntity
.ok(chatRoomService.readDirectChatRooms());
}

@Operation(summary = "활동 대화방 참여", description = """
request header에 jwt토큰을 넣고 url parameter에 활동 id를 넣어 요청하면 대화방에 참여합니다.
""")
@PostMapping("/group/{activityId}")
public ResponseEntity<Void> joinGroupChatRoom(
@PathVariable Long activityId
) {
Long chatRoomId = chatRoomService.joinGroupChatRoom(activityId);
return ResponseEntity
.created(URI.create("/chatting/" + chatRoomId))
.build();
}

@Operation(summary = "배움나누기 대화방 참여", description = """
request header에 jwt토큰을 넣고 url parameter에 배움(경험) id를 넣어 요청하면 대화방에 참여합니다.
""")
@PostMapping("/direct/{experienceId}")
public ResponseEntity<Void> joinDirectChatRoom(
@PathVariable Long experienceId
) {
Long chatRoomId = chatRoomService.joinDirectChatRoom(experienceId);
return ResponseEntity
.created(URI.create("/chatting/" + chatRoomId))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package com.meetup.teame.backend.domain.chatroom.dto.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.meetup.teame.backend.domain.chatroom.entity.ChatRoom;
import com.meetup.teame.backend.domain.chatroom.entity.Appointment;
import com.meetup.teame.backend.domain.chatroom.entity.DirectChatRoom;
import com.meetup.teame.backend.domain.chatting.entity.document.ChatMessage;
import com.meetup.teame.backend.domain.user.entity.User;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.Optional;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
Expand All @@ -17,20 +23,49 @@ public class DirectChatRoomRes {

private String imageUrl;

private String opponent;
private String opponentName;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM월 dd일")
private LocalDate appointmentDate;

private String lastChatTime;

private String lastMessage;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd.")
private LocalDate appointmentDate;
private Boolean isMentor;

private String experienceType;

public static DirectChatRoomRes of(DirectChatRoom chatRoom, User me, ChatMessage lastChatMessage) {
User opponent;
boolean isMentor = me.getId().equals(chatRoom.getExperience().getUser().getId());
if (isMentor)
opponent = chatRoom.getMentee();//내가 멘토일 경우 멘티를 가져옴
else
opponent = chatRoom.getExperience().getUser();//내가 멘티일 경우 멘토를 가져옴

LocalDate appointmentDate = Optional.ofNullable(chatRoom.getNextAppointment())
.map(Appointment::getAppointmentDate)
.orElse(null);

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("a h시 m분", new Locale("ko", "KR"));
String lastChatTime = Optional.ofNullable(lastChatMessage)
.map(chatMessage -> chatMessage.getCreatedAt().format(formatter))
.orElse(null);

String lastMessage = Optional.ofNullable(lastChatMessage)
.map(ChatMessage::getMessage)
.orElse(null);

public static DirectChatRoomRes of(ChatRoom chatRoom) {
return DirectChatRoomRes.builder()
.id(chatRoom.getId())
.imageUrl(chatRoom.getImageUrl())
.opponent(chatRoom.getTitle())
.lastMessage(chatRoom.getLastMessage())
.appointmentDate(chatRoom.getAppointmentDate().toLocalDate())
.imageUrl(opponent.getImageUrl())
.opponentName(opponent.getName())
.appointmentDate(appointmentDate)
.lastMessage(lastMessage)
.lastChatTime(lastChatTime)
.isMentor(isMentor)
.experienceType(chatRoom.getExperience().getType().getDescription())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package com.meetup.teame.backend.domain.chatroom.dto.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.meetup.teame.backend.domain.chatroom.entity.Appointment;
import com.meetup.teame.backend.domain.chatroom.entity.ChatRoom;
import com.meetup.teame.backend.domain.chatroom.entity.ChatType;
import com.meetup.teame.backend.domain.chatroom.entity.GroupChatRoom;
import com.meetup.teame.backend.domain.chatting.entity.document.ChatMessage;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Locale;
import java.util.Optional;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
Expand All @@ -24,16 +29,40 @@ public class GroupChatRoomRes {

private Long lastMeetingDate;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd (E)")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM월 dd일")
private LocalDate appointmentDate;

public static GroupChatRoomRes of(ChatRoom chatRoom) {
private String lastChatTime;

private String lastMessage;

public static GroupChatRoomRes of(GroupChatRoom chatRoom, ChatMessage lastChatMessage) {
Long lastMeetingDate = Optional.ofNullable(chatRoom.getLastAppointment())
.map(Appointment::getAppointmentDate)
.map(date -> ChronoUnit.DAYS.between(date, LocalDate.now()))
.orElse(null);

LocalDate appointmentDate = Optional.ofNullable(chatRoom.getNextAppointment())
.map(Appointment::getAppointmentDate)
.orElse(null);

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("a h시 m분", new Locale("ko", "KR"));
String lastChatTime = Optional.ofNullable(lastChatMessage)
.map(chatMessage -> chatMessage.getCreatedAt().format(formatter))
.orElse(null);

String lastMessage = Optional.ofNullable(lastChatMessage)
.map(ChatMessage::getMessage)
.orElse(null);

return GroupChatRoomRes.builder()
.id(chatRoom.getId())
.imageUrl(chatRoom.getImageUrl())
.title(chatRoom.getTitle())
.lastMeetingDate(ChronoUnit.DAYS.between(chatRoom.getLastMeetingDate(), LocalDate.now()))
.appointmentDate(chatRoom.getAppointmentDate().toLocalDate())
.imageUrl(chatRoom.getActivity().getImageUrl())
.title(chatRoom.getActivity().getTitle())
.lastMeetingDate(lastMeetingDate)
.appointmentDate(appointmentDate)
.lastChatTime(lastChatTime)
.lastMessage(lastMessage)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.meetup.teame.backend.domain.chatroom.entity;

import jakarta.persistence.Embeddable;
import lombok.*;
import org.hibernate.annotations.Comment;

import java.time.LocalDate;
import java.time.LocalDateTime;


@Embeddable
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
@Builder
public class Appointment {
@Comment("약속 시간")
private LocalDate appointmentDate;

@Comment("약속 장소")
private String appointmentLocation;

public static Appointment of(LocalDate appointmentDate, String appointmentLocation) {
return Appointment.builder()
.appointmentDate(appointmentDate)
.appointmentLocation(appointmentLocation)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,48 @@
import lombok.*;
import org.hibernate.annotations.Comment;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
@Builder
@Comment("채팅방")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "chat_type")
public class ChatRoom {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Comment("채팅방 유형 (그룹, 1:1)")
@Enumerated(EnumType.STRING)
private ChatType chatType;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "appointmentDate", column = @Column(name = "last_appointment_date")),
@AttributeOverride(name = "appointmentLocation", column = @Column(name = "last_appointment_location"))
})
private Appointment lastAppointment;

@Comment("채팅방 이미지")
private String imageUrl;//단체방일때만 필요
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "appointmentDate", column = @Column(name = "next_appointment_date")),
@AttributeOverride(name = "appointmentLocation", column = @Column(name = "next_appointment_location"))
})
private Appointment nextAppointment;

@Comment("채팅방 제목")
private String title;
private LocalDateTime updatedAt = LocalDateTime.now();

@Comment("최근 만남 날짜")
private LocalDate lastMeetingDate;//단체방일때만 필요

@Comment("약속 날짜")
private LocalDateTime appointmentDate;
@OneToMany(mappedBy = "chatRoom", cascade = CascadeType.ALL)
private List<UserChatRoom> userChatRooms;

@Comment("최근 메세지")
private String lastMessage;
public void setLastAppointment(Appointment lastAppointment) {
this.lastAppointment = lastAppointment;
}

@Comment("최근 채팅 시간")
private LocalDateTime lastChatTime;
public void setNextAppointment(Appointment nextAppointment) {
this.nextAppointment = nextAppointment;
}

@OneToMany(mappedBy = "chatRoom", cascade = CascadeType.ALL)
List<UserChatRoom> userChatRooms;
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
}
Loading

0 comments on commit b4b44dd

Please sign in to comment.