diff --git a/build.gradle b/build.gradle
index 6505e07..17a8a2b 100755
--- a/build.gradle
+++ b/build.gradle
@@ -48,7 +48,8 @@ dependencies {
// graphQL 클래스, 인터페이스를 제공하는 라이브러리
implementation 'com.graphql-java-kickstart:graphql-spring-boot-starter:11.0.0'
- runtimeOnly 'com.graphql-java-kickstart:graphiql-spring-boot-starter:11.0.0'
+ implementation 'org.projectlombok:lombok:1.18.26'
+ runtimeOnly 'com.graphql-java-kickstart:graphiql-spring-boot-starter:11.0.0'
// graphQL 쿼리 요청에 사용되는 라이브러리
implementation 'com.graphql-java-kickstart:playground-spring-boot-starter:11.0.0'
diff --git a/src/main/java/com/example/ai_jeju/config/WebConfig.java b/src/main/java/com/example/ai_jeju/config/WebConfig.java
index 02a3dfe..845f243 100644
--- a/src/main/java/com/example/ai_jeju/config/WebConfig.java
+++ b/src/main/java/com/example/ai_jeju/config/WebConfig.java
@@ -13,7 +13,6 @@ public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
- // 모든 경로에 대해 인터셉터를 적용 (필요에 따라 경로를 지정할 수 있음)
registry.addInterceptor(headerCheckInterceptor).addPathPatterns("/**");
}
}
diff --git a/src/main/java/com/example/ai_jeju/controller/ChatController.java b/src/main/java/com/example/ai_jeju/controller/ChatController.java
index d0f7aa8..5083046 100644
--- a/src/main/java/com/example/ai_jeju/controller/ChatController.java
+++ b/src/main/java/com/example/ai_jeju/controller/ChatController.java
@@ -46,12 +46,16 @@ public void message(ChatMessageDto messageDto, @Header("simpSessionAttributes")
try {
String nickname = (String) sessionAttributes.get("nickname");
+ String profileImg = (String) sessionAttributes.get("profileImg");
log.info("Received message: " + messageDto.toString());
// sender가 null일 경우 세션에서 추출한 nickname을 sender로 설정
if (messageDto.getSender() == null) {
messageDto.setSender(nickname);
}
+ if (messageDto.getProfileImg() == null) {
+ messageDto.setProfileImg(profileImg);
+ }
switch (messageDto.getType()) {
case ENTER:
@@ -64,14 +68,28 @@ public void message(ChatMessageDto messageDto, @Header("simpSessionAttributes")
break;
}
- ChatMessage chatMessage = ChatMessage.builder()
- .roomId(messageDto.getRoomId())
- .sender(messageDto.getSender()) // nickname이 sender로 설정됨
- .message(messageDto.getMessage())
- .timestamp(LocalDateTime.now())
- .type(messageDto.getType().name())
- .build();
- chatMessageRepository.save(chatMessage);
+ // roomId를 사용해 ChatRoom 객체를 가져오기
+ ChatRoom chatRoom = chatRoomRepository.findByRoomId(messageDto.getRoomId())
+ .orElseThrow(() -> new IllegalArgumentException("Invalid roomId: " + messageDto.getRoomId()));
+
+ // ENTER 타입이 아닌 경우에만 메시지를 저장하기
+ if (messageDto.getType() != ChatMessageDto.MessageType.ENTER) {
+ try {
+ ChatMessage chatMessage = ChatMessage.builder()
+ .chatRoom(chatRoom)
+ .sender(messageDto.getSender())
+ .message(messageDto.getMessage())
+ .profileImg(messageDto.getProfileImg())
+ .timestamp(LocalDateTime.now())
+ .type(messageDto.getType().name())
+ .build();
+ log.info("Saving ChatMessage: " + chatMessage.toString());
+ chatMessageRepository.save(chatMessage);
+ } catch (Exception e) {
+ log.error("Error saving ChatMessage", e);
+ }
+ }
+
log.info("Sending message to /sub/chat/room/" + messageDto.getRoomId() + ": " + messageDto.toString());
messagingTemplate.convertAndSend("/sub/chat/room/" + messageDto.getRoomId(), messageDto);
@@ -81,26 +99,48 @@ public void message(ChatMessageDto messageDto, @Header("simpSessionAttributes")
}
- //@GetMapping("/chatroom")
- //public String chat(@RequestParam("roomId") String roomId, Model model) {
- // model.addAttribute("roomId", roomId);
- // return "chat"; // chat.html 파일을 반환
- //}
+ @GetMapping("/chatroom")
+ public String chat(@RequestParam("roomId") String roomId, Model model) {
+ model.addAttribute("roomId", roomId);
+ return "chat"; // chat.html 파일을 반환
+ }
@GetMapping("/chat/previous")
@ResponseBody
public List getPreviousMessages(
@RequestParam("roomId") String roomId,
@RequestParam(value = "lastMessageid", required = false) Optional lastMessageId) {
- return chatService.previousMessages(roomId, lastMessageId.orElse(null));
+
+ // roomId를 사용해 ChatRoom 객체 가져오기
+ ChatRoom chatRoom = chatRoomRepository.findByRoomId(roomId)
+ .orElseThrow(() -> new IllegalArgumentException("Invalid roomId: " + roomId));
+
+ return chatService.previousMessages(chatRoom, lastMessageId.orElse(null));
}
@GetMapping("/chat/allprevious")
@ResponseBody
public List getAllMessages(@RequestParam("roomId") String roomId) {
- return chatService.getAllMessages(roomId);
+
+ // roomId를 사용해 ChatRoom 객체를 가져오기
+ ChatRoom chatRoom = chatRoomRepository.findByRoomId(roomId)
+ .orElseThrow(() -> new IllegalArgumentException("Invalid roomId: " + roomId));
+
+ return chatService.getAllMessages(chatRoom);
}
+ @GetMapping("/chat/messagecount")
+ @ResponseBody
+ public int getMessageCount(@RequestParam("roomId") String roomId) {
+
+
+ ChatRoom chatRoom = chatRoomRepository.findByRoomId(roomId)
+ .orElseThrow(() -> new IllegalArgumentException("Invalid roomId: " + roomId));
+
+ return chatService.getMessageCount(chatRoom);
+ }
+
+
diff --git a/src/main/java/com/example/ai_jeju/controller/ChatRoomController.java b/src/main/java/com/example/ai_jeju/controller/ChatRoomController.java
index 5e3c599..e045f0f 100644
--- a/src/main/java/com/example/ai_jeju/controller/ChatRoomController.java
+++ b/src/main/java/com/example/ai_jeju/controller/ChatRoomController.java
@@ -1,12 +1,17 @@
package com.example.ai_jeju.controller;
+import com.example.ai_jeju.domain.ChatMessage;
import com.example.ai_jeju.domain.ChatRoom;
+import com.example.ai_jeju.handler.StompHandler;
import com.example.ai_jeju.service.ChatService;
import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
@RequiredArgsConstructor
@RestController
@@ -14,6 +19,7 @@
public class ChatRoomController {
private final ChatService chatService;
+ private final StompHandler stompHandler;
@GetMapping("/rooms")
public List room() {
@@ -34,4 +40,25 @@ public String chatRooms() {
return "chatrooms";
}
}
-}
+
+ @GetMapping("/room/{roomId}/lastmessage")
+ public ChatMessage getLastMessage(@PathVariable("roomId") String roomId) {
+ ChatRoom chatRoom = chatService.findRoomById(roomId);
+ if (chatRoom == null) {
+ throw new IllegalArgumentException("Invalid roomId: " + roomId);
+ }
+ return chatService.findLastMessage(chatRoom);
+ }
+
+
+ @GetMapping("/users/{roomId}/count")
+ public int getUserCount(@PathVariable("roomId") String roomId) {
+ return stompHandler.getUserCount(roomId);
+ }
+
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/ai_jeju/controller/UserController.java b/src/main/java/com/example/ai_jeju/controller/UserController.java
index ae9b7d0..4b67745 100755
--- a/src/main/java/com/example/ai_jeju/controller/UserController.java
+++ b/src/main/java/com/example/ai_jeju/controller/UserController.java
@@ -13,6 +13,7 @@
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
+import java.util.Map;
@RestController
@RequestMapping("/api/users")
@@ -29,10 +30,11 @@ public Long registerUser(@RequestBody SignUpRequest signUpRequest, HttpServletRe
}
@GetMapping("/checks")
- public Long CheckIfUser(@RequestParam(name = "email") String email, HttpServletRequest request, HttpServletResponse response){
- return userService.checkIfUser(email,request,response);
+ public Map CheckIfUser(@RequestParam(name = "email") String email, HttpServletRequest request, HttpServletResponse response){
+ return userService.checkIfUser(email, request, response);
}
+
//탈퇴하기
@GetMapping("/withdraw")
public ResponseEntity signOut(@RequestBody WithdrawRequest withdrawRequest) {
diff --git a/src/main/java/com/example/ai_jeju/domain/ChatMessage.java b/src/main/java/com/example/ai_jeju/domain/ChatMessage.java
index 58b75aa..9689688 100644
--- a/src/main/java/com/example/ai_jeju/domain/ChatMessage.java
+++ b/src/main/java/com/example/ai_jeju/domain/ChatMessage.java
@@ -1,13 +1,11 @@
package com.example.ai_jeju.domain;
-import jakarta.persistence.Entity;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
+import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
+import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDateTime;
@@ -22,9 +20,15 @@ public class ChatMessage {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
- private String roomId;
+ @ManyToOne
+ @JoinColumn(name = "room_id", referencedColumnName = "roomId")
+ private ChatRoom chatRoom;
+
private String sender;
private String message;
private String type;
+ @UpdateTimestamp
+ @Column(name = "timestamp")
private LocalDateTime timestamp;
+ private String profileImg;
}
\ No newline at end of file
diff --git a/src/main/java/com/example/ai_jeju/domain/ChatRoom.java b/src/main/java/com/example/ai_jeju/domain/ChatRoom.java
index fd3b3e3..3b43b88 100644
--- a/src/main/java/com/example/ai_jeju/domain/ChatRoom.java
+++ b/src/main/java/com/example/ai_jeju/domain/ChatRoom.java
@@ -1,9 +1,6 @@
package com.example.ai_jeju.domain;
-import jakarta.persistence.Entity;
-import jakarta.persistence.Id;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
+import jakarta.persistence.*;
import lombok.Data;
@Data
@@ -11,23 +8,25 @@
public class ChatRoom {
@Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
-
private String roomId;
+
private String name;
+ private String description;
+ private String imgurl;
// 기본 생성자
public ChatRoom() {
}
// 이름과 roomId를 인자로 받는 생성자
- public ChatRoom(String roomId, String name) {
+ public ChatRoom(String roomId, String name, String description, String imgurl) {
this.roomId = roomId;
this.name = name;
+ this.description = description;
+ this.imgurl = imgurl;
}
- public static ChatRoom create(String roomId, String name) {
- return new ChatRoom(roomId, name);
+ public static ChatRoom create(String roomId, String name, String description, String imgurl) {
+ return new ChatRoom(roomId, name, description, imgurl);
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/ai_jeju/domain/Emergency.java b/src/main/java/com/example/ai_jeju/domain/Emergency.java
index 7bc6050..da89b69 100644
--- a/src/main/java/com/example/ai_jeju/domain/Emergency.java
+++ b/src/main/java/com/example/ai_jeju/domain/Emergency.java
@@ -24,6 +24,8 @@ public class Emergency {
private String imgsrc;
@Column(length = 1024)
private String operationtime;
+ @Column(length = 1024)
+ private String breaktime;
private String category;
double mapx;
double mapy;
diff --git a/src/main/java/com/example/ai_jeju/domain/Store.java b/src/main/java/com/example/ai_jeju/domain/Store.java
index 193d407..3d45a8a 100644
--- a/src/main/java/com/example/ai_jeju/domain/Store.java
+++ b/src/main/java/com/example/ai_jeju/domain/Store.java
@@ -21,7 +21,7 @@ public class Store {
String name;
//이미지 소스
- @Column(name = "imgSrc",updatable = false,nullable = true)
+ @Column(name = "imgSrc",updatable = false,nullable = true, columnDefinition = "TEXT")
String imgSrc;
@Column(name = "address",updatable = false,nullable = true)
@@ -46,26 +46,26 @@ public class Store {
//유모차 대여여부
@Column(name = "stroller",updatable = false,nullable = true)
- boolean stroller;
+ Boolean stroller;
//유모차 편의성
@Column(name = "strollerVal",updatable = false,nullable = true)
- boolean strollerVal;
+ Boolean strollerVal;
//아이 스페어 체어
@Column(name = "babySpareChair",updatable = false,nullable = true)
- boolean babySpareChair;
+ Boolean babySpareChair;
//아이 놀이방
@Column(name = "playground",updatable = false,nullable = true)
- boolean playground;
+ Boolean playground;
//노키즈존 여부
@Column(name = "noKidsZone",updatable = false,nullable = true)
- boolean noKidsZone;
+ Boolean noKidsZone;
@Column(name = "categoryId",updatable = false,nullable = true)
- int categoryId;
+ Integer categoryId;
@Column(name = "operationTime",updatable = false,nullable = true)
String operationTime;
diff --git a/src/main/java/com/example/ai_jeju/dto/ChatMessageDto.java b/src/main/java/com/example/ai_jeju/dto/ChatMessageDto.java
index 31d1511..613756f 100644
--- a/src/main/java/com/example/ai_jeju/dto/ChatMessageDto.java
+++ b/src/main/java/com/example/ai_jeju/dto/ChatMessageDto.java
@@ -10,11 +10,12 @@
public class ChatMessageDto {
public enum MessageType {
- ENTER, TALK, EXIT;
+ TALK, EXIT, ENTER;
}
private MessageType type;
private String roomId;
private String sender;
private String message;
+ private String profileImg;
}
\ No newline at end of file
diff --git a/src/main/java/com/example/ai_jeju/handler/StompHandler.java b/src/main/java/com/example/ai_jeju/handler/StompHandler.java
index c58e43b..d92d775 100644
--- a/src/main/java/com/example/ai_jeju/handler/StompHandler.java
+++ b/src/main/java/com/example/ai_jeju/handler/StompHandler.java
@@ -1,6 +1,5 @@
package com.example.ai_jeju.handler;
-import com.example.ai_jeju.domain.User;
import com.example.ai_jeju.jwt.TokenProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -10,6 +9,12 @@
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.stereotype.Component;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.Map;
@RequiredArgsConstructor
@Component
@@ -18,39 +23,141 @@ public class StompHandler implements ChannelInterceptor {
private final TokenProvider tokenProvider;
private static final String BEARER_PREFIX = "Bearer ";
+ private final ConcurrentMap roomUserCount = new ConcurrentHashMap<>();
+ private final ConcurrentMap> userRoomEntryCount = new ConcurrentHashMap<>();
@Override
public Message> preSend(Message> message, MessageChannel channel) {
log.info("preSend method called");
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
- if (StompCommand.CONNECT == accessor.getCommand()) { // WebSocket 연결 요청
+ // WebSocket 연결 요청 처리
+ if (StompCommand.CONNECT == accessor.getCommand()) {
String jwtToken = accessor.getFirstNativeHeader("Authorization");
- if (jwtToken == null) {
- log.error("Authorization header is missing");
+ if (jwtToken == null || !jwtToken.startsWith(BEARER_PREFIX)) {
+ log.error("Authorization header is missing or does not start with 'Bearer '");
+ throw new IllegalArgumentException("Invalid or missing Authorization header");
+ }
+
+ String token = jwtToken.substring(BEARER_PREFIX.length());
+ log.info("Extracted token: {}", token);
+
+ if (token.isEmpty()) {
+ log.error("JWT token is empty");
+ throw new IllegalArgumentException("JWT token is empty");
+ }
+
+ boolean isValid = tokenProvider.validToken(token);
+ if (isValid) {
+ log.info("JWT Token is valid. Proceeding with connection.");
+
+ // 토큰에서 nickname 추출
+ String nickname = tokenProvider.extractNickname(token);
+
+ String profileImg = tokenProvider.extractProfileImg(token);
+ log.info("Extracted nickname: {}", nickname);
+
+ // WebSocket 세션에 nickname 저장
+ accessor.getSessionAttributes().put("nickname", nickname);
+ accessor.getSessionAttributes().put("profileImg", profileImg);
+ accessor.getSessionAttributes().put("connected", true); // 연결 상태 저장
+ accessor.getSessionAttributes().put("enter", false); // 초기에는 false로 설정
+
+
} else {
- log.info("Authorization header present: {}", jwtToken);
- String token = jwtToken.substring(7);
- log.info("Extracted token: {}", token);
-
- boolean isValid = tokenProvider.validToken(token);
- if (isValid) {
- log.info("JWT Token is valid. Proceeding with connection.");
-
- // 토큰에서 nickname 추출
- String nickname = tokenProvider.extractNickname(token);
- log.info("Extracted nickname: {}", nickname);
-
- // WebSocket 세션에 nickname 저장
- accessor.getSessionAttributes().put("nickname", nickname);
- } else {
- log.error("Invalid JWT Token");
- throw new IllegalArgumentException("Invalid JWT Token provided");
+ log.error("Invalid JWT Token");
+ throw new IllegalArgumentException("Invalid JWT Token provided");
+ }
+ }
+
+ // 메시지 전송 요청 처리
+ else if (StompCommand.SEND == accessor.getCommand()) {
+ String destination = accessor.getDestination();
+
+ // 메시지의 목적지가 "/pub/chat/message"인지 확인
+ if ("/pub/chat/message".equals(destination)) {
+ String messageBody = new String((byte[]) message.getPayload());
+ log.info("Message body: {}", messageBody);
+
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ JsonNode jsonNode = objectMapper.readTree(messageBody);
+
+ String roomId = jsonNode.get("roomId").asText();
+ String messageType = jsonNode.get("type").asText();
+
+ // 토큰에서 가져온 nickname을 sender로 사용
+ String sender = (String) accessor.getSessionAttributes().get("nickname");
+ log.info("Sender retrieved from session: {}", sender);
+
+ if ("ENTER".equals(messageType)) {
+ log.info("User '{}' has entered room '{}'", sender, roomId);
+
+ // 사용자가 방에 입장할 때마다 방의 사용자 수 증가
+ roomUserCount.merge(roomId, 1, Integer::sum);
+ log.info("Room '{}' user count: {}", roomId, roomUserCount.get(roomId));
+
+ // 사용자 방 입장 횟수 증가
+ userRoomEntryCount
+ .computeIfAbsent(sender, k -> new ConcurrentHashMap<>())
+ .merge(roomId, 1, Integer::sum);
+ log.info("User '{}' entry count for room '{}': {}", sender, roomId, userRoomEntryCount.get(sender).get(roomId));
+
+ // 사용자가 실제로 ENTER 했음을 표시
+ accessor.getSessionAttributes().put("enter", true);
+
+ accessor.getSessionAttributes().put("roomId", roomId);
+ }
+
+ // 메시지 전송 시 sender를 설정
+ if ("TALK".equals(messageType)) {
+ log.info("User '{}' sent message to room '{}': {}", sender, roomId, jsonNode.get("message").asText());
+ // 메시지에 sender 추가하여 브로드캐스트
+ // messagingTemplate.convertAndSend("/sub/chat/room/" + roomId, updatedMessage);
+ }
+
+ } catch (Exception e) {
+ log.error("Error parsing message body", e);
+ }
+ }
+ }
+
+ else if (StompCommand.DISCONNECT == accessor.getCommand()) {
+ String sessionId = accessor.getSessionId();
+ log.info("DISCONNECT command received for session: {}", sessionId);
+
+ Boolean connected = (Boolean) accessor.getSessionAttributes().get("connected");
+ Boolean entered = (Boolean) accessor.getSessionAttributes().get("enter");
+
+ if (connected != null && connected && entered != null && entered) {
+ String nickname = (String) accessor.getSessionAttributes().get("nickname");
+ String roomId = (String) accessor.getSessionAttributes().get("roomId"); // 세션에서 roomId를 가져옴
+
+ if (nickname != null && roomId != null) {
+ Integer count = userRoomEntryCount.getOrDefault(nickname, new ConcurrentHashMap<>()).get(roomId);
+ if (count != null && count > 0) {
+ roomUserCount.merge(roomId, -1, Integer::sum);
+ userRoomEntryCount.get(nickname).merge(roomId, -1, Integer::sum);
+ log.info("User '{}' has left room '{}'. Updated user count: {}", nickname, roomId, roomUserCount.get(roomId));
+
+ // 마지막 입장인 경우 방 목록에서 제거
+ if (userRoomEntryCount.get(nickname).get(roomId) == 0) {
+ userRoomEntryCount.get(nickname).remove(roomId);
+ }
+ }
}
+
+ accessor.getSessionAttributes().put("connected", false);
+ } else {
+ log.warn("DISCONNECT called but user was not marked as connected or had not entered.");
}
}
return message;
}
+
+ public int getUserCount(String roomId) {
+ return roomUserCount.getOrDefault(roomId, 0);
+ }
}
diff --git a/src/main/java/com/example/ai_jeju/jwt/TokenProvider.java b/src/main/java/com/example/ai_jeju/jwt/TokenProvider.java
index 710bb85..146926c 100644
--- a/src/main/java/com/example/ai_jeju/jwt/TokenProvider.java
+++ b/src/main/java/com/example/ai_jeju/jwt/TokenProvider.java
@@ -44,6 +44,7 @@ private String makeToken(Date expiry, User user) {
.setSubject(user.getEmail())
.claim("id", user.getId())
.claim("nickname", user.getNickname())
+ .claim("profileImg", user.getProfileImg())
.signWith(key, SignatureAlgorithm.HS512) // 동일한 키와 알고리즘 사용
.compact();
}
@@ -81,6 +82,11 @@ public String extractNickname(String token) {
return claims.get("nickname", String.class);
}
+ public String extractProfileImg(String token) {
+ Claims claims = getClaims(token);
+ return claims.get("profileImg", String.class);
+ }
+
private Claims getClaims(String token) {
return Jwts.parser()
.setSigningKey(key)
diff --git a/src/main/java/com/example/ai_jeju/repository/ChatMessageRepository.java b/src/main/java/com/example/ai_jeju/repository/ChatMessageRepository.java
index f23e8a0..371ee1a 100644
--- a/src/main/java/com/example/ai_jeju/repository/ChatMessageRepository.java
+++ b/src/main/java/com/example/ai_jeju/repository/ChatMessageRepository.java
@@ -1,16 +1,25 @@
package com.example.ai_jeju.repository;
import com.example.ai_jeju.domain.ChatMessage;
+import com.example.ai_jeju.domain.ChatRoom;
import org.apache.logging.log4j.message.Message;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
+import java.util.Optional;
@Repository
public interface ChatMessageRepository extends JpaRepository {
- List findByRoomIdOrderByIdAsc(String roomId);
- List findTop10ByRoomIdOrderByIdDesc(String roomId);
- List findTop10ByRoomIdAndIdLessThanOrderByIdDesc(String roomId, Long id);
+ // ChatRoom 객체를 기반으로 메시지를 가져옵니다.
+ List findByChatRoomOrderByIdAsc(ChatRoom chatRoom);
+
+ List findTop10ByChatRoomOrderByIdDesc(ChatRoom chatRoom);
+
+ List findTop10ByChatRoomAndIdLessThanOrderByIdDesc(ChatRoom chatRoom, Long id);
+
+ Optional findTop1ByChatRoomOrderByIdDesc(ChatRoom chatRoom);
+
+ int countByChatRoom(ChatRoom chatRoom);
}
\ No newline at end of file
diff --git a/src/main/java/com/example/ai_jeju/repository/ChatRoomRepository.java b/src/main/java/com/example/ai_jeju/repository/ChatRoomRepository.java
index 5bab7ab..8972938 100644
--- a/src/main/java/com/example/ai_jeju/repository/ChatRoomRepository.java
+++ b/src/main/java/com/example/ai_jeju/repository/ChatRoomRepository.java
@@ -7,6 +7,6 @@
import java.util.Optional;
@Repository
-public interface ChatRoomRepository extends JpaRepository {
+public interface ChatRoomRepository extends JpaRepository {
Optional findByRoomId(String roomId);
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/ai_jeju/service/ChatService.java b/src/main/java/com/example/ai_jeju/service/ChatService.java
index 43763bc..923e10f 100644
--- a/src/main/java/com/example/ai_jeju/service/ChatService.java
+++ b/src/main/java/com/example/ai_jeju/service/ChatService.java
@@ -15,20 +15,16 @@
@RequiredArgsConstructor
public class ChatService {
- @Autowired
- private ChatMessageRepository chatMessageRepository;
-
+ private final ChatMessageRepository chatMessageRepository;
private final ChatRoomRepository chatRoomRepository;
@PostConstruct
public void init() {
- // 데이터베이스에 이미 채팅방이 존재하는지 확인
if (chatRoomRepository.count() == 0) {
- // 방 3개를 고정적으로 생성하여 데이터베이스에 저장
- chatRoomRepository.save(new ChatRoom("1", "Room 1"));
- chatRoomRepository.save(new ChatRoom("2", "Room 2"));
- chatRoomRepository.save(new ChatRoom("3", "Room 3"));
+ chatRoomRepository.save(new ChatRoom("1", "설렘 가득한 여행 준비", "제주 여행 계획을 짜고있는 엄마아빠들과 소통해요", "https://ai-jeju.s3.ap-northeast-2.amazonaws.com/%EC%9D%B4%EB%AF%B8%EC%A7%801.png"));
+ chatRoomRepository.save(new ChatRoom("2", "즐거운 제주 여행", "제주 여행을 즐기고 있는 엄마아빠들과 소통해요", "https://ai-jeju.s3.ap-northeast-2.amazonaws.com/%EC%9D%B4%EB%AF%B8%EC%A7%802.png"));
+ chatRoomRepository.save(new ChatRoom("3", "제주에서 새로운 인연", "아이제주를 통해 새로운 인연을 만들어요", "https://ai-jeju.s3.ap-northeast-2.amazonaws.com/%EC%9D%B4%EB%AF%B8%EC%A7%803.jpg"));
}
}
@@ -40,16 +36,26 @@ public ChatRoom findRoomById(String roomId) {
return chatRoomRepository.findByRoomId(roomId).orElse(null);
}
- public List getAllMessages(String roomId) {
- return chatMessageRepository.findByRoomIdOrderByIdAsc(roomId);
+ public List getAllMessages(ChatRoom chatRoom) {
+ return chatMessageRepository.findByChatRoomOrderByIdAsc(chatRoom);
}
- public List previousMessages(String roomId, Long lastMessageId) {
+ public List previousMessages(ChatRoom chatRoom, Long lastMessageId) {
if (lastMessageId == null) {
// 마지막 메시지 ID가 없으면 해당 채팅방의 최신 메시지 10개 가져오기
- return chatMessageRepository.findTop10ByRoomIdOrderByIdDesc(roomId);
+ return chatMessageRepository.findTop10ByChatRoomOrderByIdDesc(chatRoom);
}
// 특정 ID 이전의 해당 채팅방 메시지 10개 가져오기
- return chatMessageRepository.findTop10ByRoomIdAndIdLessThanOrderByIdDesc(roomId, lastMessageId);
+ return chatMessageRepository.findTop10ByChatRoomAndIdLessThanOrderByIdDesc(chatRoom, lastMessageId);
+ }
+
+ public ChatMessage findLastMessage(ChatRoom chatRoom) {
+ return chatMessageRepository.findTop1ByChatRoomOrderByIdDesc(chatRoom).orElse(null);
}
-}
+
+ public int getMessageCount(ChatRoom chatRoom) {
+ return chatMessageRepository.countByChatRoom(chatRoom);
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/ai_jeju/service/UserService.java b/src/main/java/com/example/ai_jeju/service/UserService.java
index 0ba82d8..45f3f8e 100755
--- a/src/main/java/com/example/ai_jeju/service/UserService.java
+++ b/src/main/java/com/example/ai_jeju/service/UserService.java
@@ -27,9 +27,7 @@
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
import static com.example.ai_jeju.handler.SignUpHandler.ACCESS_TOKEN_COOKIE_NAME;
//import static com.example.ai_jeju.handler.SignUpHandler.REFRESH_TOKEN_COOKIE_NAME;
@@ -58,20 +56,29 @@ public class UserService {
* checkIfUser : 기존 회원여부 확인
* 기존 회원이라면 객체 (아이디만) 반환 , AccessToken 쿠키로 발급
*/
- public Long checkIfUser(String email, HttpServletRequest request, HttpServletResponse response){
+ public Map checkIfUser(String email, HttpServletRequest request, HttpServletResponse response) {
Optional existingUser = userRepository.findByEmail(email);
- /*--------------------------------------------------------------------------------------------------*/
+ Map result = new HashMap<>();
+
if (existingUser.isPresent()) {
User user = existingUser.get();
- String accessToken = tokenProvider.generateToken(user,ACCESS_TOKEN_DURATION);
- addAccessTokenToCookie(request,response, accessToken);
- return user.getId();
- }
- /*--------------------------------------------------------------------------------------------------*/
- else{
- return null;
+ String accessToken = tokenProvider.generateToken(user, ACCESS_TOKEN_DURATION);
+
+ result.put("statusCode", 1000);
+ result.put("message", "existinguser");
+ result.put("data", Map.of(
+ "userId", user.getId(),
+ "accessToken", accessToken
+ ));
+ } else {
+ result.put("statusCode", 2000);
+ result.put("message", "notexistinguser");
+ result.put("data", null);
}
+
+ return result;
}
+
/**
* login/signu up flow-3
* registerUser : 새로운 회원 DB 저장
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 1efe566..8eabd73 100755
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,21 +1,21 @@
spring.application.name=ai_jeju
-server.port = 7080
+server.port = 5000
spring.jpa.open-in-view=false
# MySQL
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# DB Source URL
-spring.datasource.url=jdbc:mysql://112.219.81.130:3310/ai_jeju?serverTimezone=UTC
+spring.datasource.url=jdbc:mysql://database-1.c5u0os4m64uc.ap-northeast-2.rds.amazonaws.com/shop
# DB username
-spring.datasource.username=root
+spring.datasource.username=shop
# DB password
-spring.datasource.password=!@Knp2020!@
-
+spring.datasource.password=shopsuccess
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
+
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
diff --git a/src/main/resources/templates/chat.html b/src/main/resources/templates/chat.html
index 68af15b..6c4d01c 100644
--- a/src/main/resources/templates/chat.html
+++ b/src/main/resources/templates/chat.html
@@ -27,9 +27,10 @@
width: calc(100% - 60px);
padding: 10px;
}
- .send-button {
+ .send-button, .leave-button, .back-button {
padding: 10px;
cursor: pointer;
+ margin-top: 10px;
}
@@ -40,20 +41,25 @@
+
+
+
+
diff --git a/src/main/resources/templates/chatrooms.html b/src/main/resources/templates/chatrooms.html
index 1e3a1fb..168963b 100644
--- a/src/main/resources/templates/chatrooms.html
+++ b/src/main/resources/templates/chatrooms.html
@@ -1,10 +1,10 @@