Skip to content

Commit

Permalink
#237 #251 feat: 채팅 이미지 전송 API(createChatImage) 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
xhaktmchl committed Dec 6, 2022
1 parent 642f9ac commit 55dfeac
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ public enum BaseResponseStatus {
NOT_EXISTS_PARTYCHATROOM_MEMBER(false,2208,"채팅방 멤버가 존재하지 않습니다."),
ALREADY_PARTICIPATE_CHATROOM(false, 2209, "이미 채팅방에 참여하고 있습니다."),
NOT_EXISTS_CHAT(false,2210,"채팅이 존재하지 않습니다."),
EXCEEDED_IMAGE(false,2211,"이미지 갯수를 초과했습니다."),




Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ public void handleTextMessage(WebSocketSession session, TextMessage message) {
try {
// json 형식으로 변환 후 전송
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
PostChatRes postChatRes = mapper.readValue(msg, PostChatRes.class);
PostChatRes dto = mapper.readValue(msg, PostChatRes.class);

deliveryPartyChatService.createChat(postChatRes.getMemberId(), postChatRes.getEmail(), postChatRes.getChatRoomId(), postChatRes.getContent(), postChatRes.getIsSystemMessage(), postChatRes.getProfileImgUrl(), postChatRes.getChatType(), postChatRes.getChatId());
deliveryPartyChatService.createChat(dto.getMemberId(), dto.getEmail(), dto.getChatRoomId(), dto.getContent(), dto.getIsSystemMessage(), dto.getProfileImgUrl(), dto.getChatType(), dto.getChatId(), dto.getIsImageMessage());

} catch (Exception e) {
System.out.println("웹소켓 메시지 전송 에러 발생");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package shop.geeksasang.controller.chat;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import shop.geeksasang.config.response.BaseResponse;
import shop.geeksasang.domain.chat.Chat;
import shop.geeksasang.domain.chat.ChatRoom;
import shop.geeksasang.dto.chat.PostChatImageReq;
import shop.geeksasang.dto.chat.chatchief.PostRemoveMemberByChiefReq;
import shop.geeksasang.dto.chat.partychatroom.GetPartyChatRoomsRes;
import shop.geeksasang.dto.chat.PostChatReq;
Expand Down Expand Up @@ -46,11 +46,39 @@ public BaseResponse<PartyChatRoomRes> createPartyChatRoom(HttpServletRequest req
@PostMapping("/chat")
public BaseResponse<String> createChat(HttpServletRequest request, @RequestBody PostChatReq dto){
JwtInfo jwtInfo = (JwtInfo) request.getAttribute("jwtInfo");
deliveryPartyChatService.createChat(jwtInfo.getUserId(), dto.getEmail(), dto.getChatRoomId(), dto.getContent(), dto.getIsSystemMessage(), dto.getProfileImgUrl(), dto.getChatType(), dto.getChatId());
deliveryPartyChatService.createChat(jwtInfo.getUserId(), dto.getEmail(), dto.getChatRoomId(), dto.getContent(), dto.getIsSystemMessage(), dto.getProfileImgUrl(), dto.getChatType(), dto.getChatId(), dto.getIsImageMessage());
return new BaseResponse("채팅송신을 성공했습니다.");
}


@ApiOperation(value = "채팅 이미지 전송", notes = "채팅방에서 이미지 전송 API. swagger 에서 이미지(multipartfile)처리가 잘 되지 않으므로, postman으로 테스트 바랍니다.")
@ApiImplicitParams({
@ApiImplicitParam(name = "content", required = true, dataTypeClass = String.class, example = "이미지 채팅입니다."),
@ApiImplicitParam(name = "chatRoomId", required = true, dataTypeClass = String.class, example = "638ef5c109c1212827135cf3"),
@ApiImplicitParam(name = "isSystemMessage", dataTypeClass = Boolean.class, example = "false"),
@ApiImplicitParam(name = "email", required = true, dataTypeClass = String.class, example = "[email protected]"),
@ApiImplicitParam(name = "profileImgUrl", required = true, dataTypeClass = String.class, example = "https://yogit.s3.ap-northeast-2.amazonaws.com/boardimguuid2"),
@ApiImplicitParam(name = "chatType", required = true, dataTypeClass = String.class, example = "publish 또는 read"),
@ApiImplicitParam(name = "chatId", required = true, dataTypeClass = String.class, example = "publish일 때는 none / read일 때는 chatId(인덱스)"),
@ApiImplicitParam(name = "images", required = true, dataTypeClass = MultipartFile.class, example = "MultiPartFile 클래스 스웨거에서 에러나면 포스트맨에서 실행 바람"),
@ApiImplicitParam(name = "isImageMessage", dataTypeClass = Boolean.class, example = "false"),
})
@ApiResponses({
@ApiResponse(code = 1000 ,message ="요청에 성공하셨습니다."),
@ApiResponse(code = 2009, message ="존재하지 않는 멤버입니다"),
@ApiResponse(code = 2207, message ="채팅방이 존재하지 않습니다."),
@ApiResponse(code = 2208, message ="채팅방 멤버가 존재하지 않습니다."),
@ApiResponse(code = 2211, message ="이미지 갯수를 초과했습니다."),
@ApiResponse(code = 4000 ,message ="서버 오류입니다.")
})
@PostMapping("/chatimage")
public BaseResponse<String> createChatImage(HttpServletRequest request, @ModelAttribute @Validated PostChatImageReq dto){
JwtInfo jwtInfo = (JwtInfo) request.getAttribute("jwtInfo");
deliveryPartyChatService.createChatImage(jwtInfo.getUserId(), dto.getEmail(), dto.getChatRoomId(), dto.getContent(), dto.getIsSystemMessage(), dto.getProfileImgUrl(), dto.getChatType(), dto.getChatId(), dto.getImages(), dto.getIsImageMessage());
return new BaseResponse("채팅 이미지 전송을 성공했습니다.");
}


@ApiOperation(value = "채팅방 멤버 추가 및 rabbitmq 큐 생성", notes = "(jwt 토큰 필요)멤버의 정보만 추가")
@ApiResponses({
@ApiResponse(code = 1000 ,message ="요청에 성공하셨습니다."),
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/shop/geeksasang/domain/chat/Chat.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class Chat implements Serializable {

private List<Integer> readMembers = new ArrayList<>(); // 읽은 멤버 ID 리스트

private Boolean isImageMessage;

@Unwrapped(onEmpty = Unwrapped.OnEmpty.USE_EMPTY)
private BaseEntityMongo baseEntityMongo;

Expand All @@ -50,6 +52,18 @@ public Chat(String content, PartyChatRoom partyChatRoom, Boolean isSystemMessage
this.partyChatRoomMember = partyChatRoomMember;
this.profileImgUrl = profileImgUrl;
this.readMembers = readMembers;
this.isImageMessage = false;
this.baseEntityMongo = new BaseEntityMongo();
}

public Chat(String content, PartyChatRoom partyChatRoom, Boolean isSystemMessage, PartyChatRoomMember partyChatRoomMember, String profileImgUrl, List<Integer> readMembers, Boolean isimageMessage) {
this.content = content;
this.partyChatRoom = partyChatRoom;
this.isSystemMessage = isSystemMessage;
this.partyChatRoomMember = partyChatRoomMember;
this.profileImgUrl = profileImgUrl;
this.readMembers = readMembers;
this.isImageMessage = isimageMessage;
this.baseEntityMongo = new BaseEntityMongo();
}

Expand Down
34 changes: 34 additions & 0 deletions src/main/java/shop/geeksasang/dto/chat/PostChatImageReq.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package shop.geeksasang.dto.chat;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotBlank;
import java.util.List;

@NoArgsConstructor
@AllArgsConstructor
@Data
public class PostChatImageReq {

private String content;

private String chatRoomId;

private Boolean isSystemMessage;

private String email;

private String profileImgUrl;

private String chatType;

private String chatId;

private List<MultipartFile> images; // 최대 5개

private Boolean isImageMessage;
}
77 changes: 77 additions & 0 deletions src/main/java/shop/geeksasang/dto/chat/PostChatImageRes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package shop.geeksasang.dto.chat;


import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import shop.geeksasang.domain.chat.Chat;

import javax.validation.constraints.NotEmpty;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@NoArgsConstructor
@Getter
public class PostChatImageRes {

private String chatId;

private String content;

@NotEmpty
private String chatRoomId;

private Boolean isSystemMessage;

private int memberId;

private String email;

private String profileImgUrl;

private List<Integer> readMembers = new ArrayList<>(); // 읽은 멤버 ID 리스트

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
private LocalDateTime createdAt;

private String chatType;

private int unreadMemberCnt;

private Boolean isImageMessage;

@Builder
public PostChatImageRes(String chatId, String content, String chatRoomId, Boolean isSystemMessage, int memberId, String email, String profileImgUrl, List<Integer> readMembers, LocalDateTime createdAt, String chatType, int unreadMemberCnt, Boolean isImageMessage) {
this.chatId = chatId;
this.content = content;
this.chatRoomId = chatRoomId;
this.isSystemMessage = isSystemMessage;
this.memberId = memberId;
this.email = email;
this.profileImgUrl = profileImgUrl;
this.readMembers = readMembers;
this.createdAt = createdAt;
this.chatType = chatType;
this.unreadMemberCnt = unreadMemberCnt;
this.isImageMessage = isImageMessage;
}

public static PostChatImageRes toDto(Chat chat, String email, String chatType, int unreadMemberCnt){
return PostChatImageRes.builder()
.chatId(chat.getId())
.content(chat.getContent())
.chatRoomId(chat.getPartyChatRoom().getId())
.isSystemMessage(chat.getIsSystemMessage())
.memberId(chat.getPartyChatRoomMember().getMemberId())
.email(email)
.profileImgUrl(chat.getProfileImgUrl())
.readMembers(chat.getReadMembers())
.createdAt(chat.getBaseEntityMongo().getCreatedAt())
.chatType(chatType)
.unreadMemberCnt(unreadMemberCnt)
.isImageMessage(chat.getIsImageMessage())
.build();
}
}
2 changes: 2 additions & 0 deletions src/main/java/shop/geeksasang/dto/chat/PostChatReq.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public class PostChatReq {

private String chatId;

private Boolean isImageMessage;

public PostChatReq(String chatRoomId, String content) {
this.chatRoomId = chatRoomId;
this.content = content;
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/shop/geeksasang/dto/chat/PostChatRes.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public class PostChatRes {

private int unreadMemberCnt;

private Boolean isImageMessage;

public PostChatRes(String chatRoomId, String content, LocalDateTime createdAt, int memberId) {
this.chatRoomId = chatRoomId;
this.content = content;
Expand All @@ -56,7 +58,7 @@ public PostChatRes(String email, String chatRoomId, String content, LocalDateTim
}

@Builder
public PostChatRes(String chatId, String content, String chatRoomId, Boolean isSystemMessage, int memberId, String email, String profileImgUrl, List<Integer> readMembers, LocalDateTime createdAt, String chatType, int unreadMemberCnt) {
public PostChatRes(String chatId, String content, String chatRoomId, Boolean isSystemMessage, int memberId, String email, String profileImgUrl, List<Integer> readMembers, LocalDateTime createdAt, String chatType, int unreadMemberCnt, Boolean isImageMessage) {
this.chatId = chatId;
this.content = content;
this.chatRoomId = chatRoomId;
Expand All @@ -67,6 +69,7 @@ public PostChatRes(String chatId, String content, String chatRoomId, Boolean isS
this.readMembers = readMembers;
this.createdAt = createdAt;
this.chatType = chatType;
this.isImageMessage = isImageMessage;
this.unreadMemberCnt = unreadMemberCnt;
}

Expand All @@ -83,6 +86,7 @@ public static PostChatRes toDto(Chat chat, String email, String chatType, int un
.createdAt(chat.getBaseEntityMongo().getCreatedAt())
.chatType(chatType)
.unreadMemberCnt(unreadMemberCnt)
.isImageMessage(chat.getIsImageMessage())
.build();
}
}
39 changes: 39 additions & 0 deletions src/main/java/shop/geeksasang/rabbitmq/RabbitMQTut5Receiver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package shop.geeksasang.rabbitmq;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.util.StopWatch;

//TODO: rabbitmq 5번 튜토리얼 Consumer 코드임, 구독 및 수신 로컬 스프링에서는 테스트 성공.
public class RabbitMQTut5Receiver {

@RabbitListener(queues = "87")
public void receive1(String in) throws InterruptedException {
receive(in, 1);
}

@RabbitListener(queues = "neo")
public void receive2(String in) throws InterruptedException {
receive(in, 2);
}

public void receive(String in, int receiver) throws
InterruptedException {
System.out.println("===============Received 5번 튜토리얼 소비자<" + in + ">");
StopWatch watch = new StopWatch();
watch.start();
System.out.println("instance " + receiver + " [x] Received '"
+ in + "'");
doWork(in);
watch.stop();
System.out.println("instance " + receiver + " [x] Done in "
+ watch.getTotalTimeSeconds() + "s");
}

private void doWork(String in) throws InterruptedException {
for (char ch : in.toCharArray()) {
if (ch == '.') {
Thread.sleep(1000);
}
}
}
}
5 changes: 5 additions & 0 deletions src/main/java/shop/geeksasang/rabbitmq/RabbitMqConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,9 @@ public class RabbitMqConfig {
public AmqpAdmin amqpAdmin() {
return new RabbitAdmin(rabbitTemplate.getConnectionFactory());
}

@Bean
public RabbitMQTut5Receiver receiver(){
return new RabbitMQTut5Receiver();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

@Repository
public interface PartyChatRoomRepository extends MongoRepository<PartyChatRoom, String> {
@Query("{_id:'?0', 'status' : 'ACTIVE'}") // 0번째 파라미터 조건
Optional<PartyChatRoom> findByPartyChatRoomId(String id);
@Query("{ '_id': ?0, 'status' : 'ACTIVE'}") // 0번째 파라미터 조건
Optional<PartyChatRoom> findByPartyChatRoomId(ObjectId id);

@Query("{ chief: ?0, 'status' : 'ACTIVE'}")
Optional<PartyChatRoom> findPartyChatRoomByChiefId(ObjectId chiefId);
Expand Down
Loading

0 comments on commit 55dfeac

Please sign in to comment.