Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
db8d81d
Merge pull request #117 from autoever-ob/dev
k-oyun Sep 22, 2025
be0136c
Merge pull request #118 from autoever-ob/dev
CHOOSLA Sep 22, 2025
71ac81a
Merge pull request #121 from autoever-ob/dev
Hojip-Kim Sep 22, 2025
c4fd5cf
Merge pull request #123 from autoever-ob/dev
Gumraze-git Sep 22, 2025
4c82e1a
Merge pull request #126 from autoever-ob/dev
CHOOSLA Sep 22, 2025
9b79abd
Merge pull request #127 from autoever-ob/dev
CHOOSLA Sep 22, 2025
d38ab48
Merge pull request #128 from autoever-ob/dev
CHOOSLA Sep 22, 2025
0c7d802
Merge pull request #129 from autoever-ob/dev
Gumraze-git Sep 22, 2025
2763fa5
Merge pull request #130 from autoever-ob/dev
CHOOSLA Sep 22, 2025
ae2c721
Merge pull request #131 from autoever-ob/dev
Gumraze-git Sep 22, 2025
3e9f9c2
Merge pull request #132 from autoever-ob/dev
CHOOSLA Sep 22, 2025
875a61e
Merge pull request #134 from autoever-ob/dev
vivivim Sep 22, 2025
25ed3dc
Merge pull request #135 from autoever-ob/dev
Gumraze-git Sep 22, 2025
4710b36
Merge pull request #138 from autoever-ob/dev
Gumraze-git Sep 22, 2025
5dab465
Merge pull request #139 from autoever-ob/dev
Gumraze-git Sep 22, 2025
03e8910
Merge pull request #141 from autoever-ob/dev
Gumraze-git Sep 22, 2025
89c24bd
Merge pull request #142 from autoever-ob/dev
Gumraze-git Sep 22, 2025
27ea58a
Merge pull request #145 from autoever-ob/dev
vivivim Sep 23, 2025
2264bae
Merge pull request #148 from autoever-ob/dev
CHOOSLA Sep 23, 2025
6e0766b
Merge pull request #150 from autoever-ob/dev
CHOOSLA Sep 23, 2025
1a134fe
Merge pull request #151 from autoever-ob/dev
CHOOSLA Sep 23, 2025
3e823ba
Merge pull request #154 from autoever-ob/dev
CHOOSLA Sep 23, 2025
f199c54
Merge pull request #155 from autoever-ob/dev
vivivim Sep 23, 2025
e078cfc
Merge pull request #156 from autoever-ob/dev
CHOOSLA Sep 23, 2025
5025943
Merge pull request #157 from autoever-ob/dev
vivivim Sep 23, 2025
be29775
Merge pull request #158 from autoever-ob/dev
CHOOSLA Sep 23, 2025
17112a0
Merge pull request #159 from autoever-ob/dev
vivivim Sep 23, 2025
3c9e967
Merge pull request #162 from autoever-ob/dev
k-oyun Sep 23, 2025
4cf944d
Merge pull request #163 from autoever-ob/dev
k-oyun Sep 23, 2025
edeb67a
Merge pull request #166 from autoever-ob/dev
vivivim Sep 23, 2025
0056821
Merge pull request #167 from autoever-ob/dev
vivivim Sep 23, 2025
f78681f
Merge pull request #168 from autoever-ob/dev
vivivim Sep 23, 2025
79eba09
Merge pull request #169 from autoever-ob/dev
vivivim Sep 23, 2025
937fcea
Merge pull request #171 from autoever-ob/dev
Gumraze-git Sep 23, 2025
c611223
Merge pull request #177 from autoever-ob/dev
k-oyun Sep 24, 2025
f98a9be
Merge pull request #180 from autoever-ob/dev
CHOOSLA Sep 24, 2025
229bdb2
Merge pull request #184 from autoever-ob/dev
vivivim Sep 24, 2025
474c391
Merge pull request #186 from autoever-ob/dev
k-oyun Sep 24, 2025
2f0d231
Merge pull request #188 from autoever-ob/dev
CHOOSLA Sep 24, 2025
78752a6
Merge pull request #189 from autoever-ob/dev
k-oyun Sep 24, 2025
b6eb7e1
Revert "Merge pull request #189 from autoever-ob/dev"
Sep 24, 2025
f53c24a
Revert "Merge pull request #188 from autoever-ob/dev"
Sep 24, 2025
2c0a322
Revert "Merge pull request #186 from autoever-ob/dev"
Sep 24, 2025
3a072f6
fix: product error
Sep 24, 2025
13dcd43
fix: websocket handler
Sep 24, 2025
a7d7f19
Merge pull request #190 from autoever-ob/revert-chatPage
Gumraze-git Sep 24, 2025
3e16ac5
#160 config(Database): 데이터베이스 초기화
CHOOSLA Sep 24, 2025
f86c60b
#160 config(Database): 데이터베이스 스키마 추가
CHOOSLA Sep 25, 2025
4a4f826
Merge pull request #191 from autoever-ob/dev
vivivim Sep 25, 2025
aa6d5b2
Merge pull request #192 from autoever-ob/dev
CHOOSLA Sep 26, 2025
192a99c
fix: chat
Sep 26, 2025
1d3ec45
Merge pull request #195 from autoever-ob/fix/#194-chat
CHOOSLA Sep 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@
import com.campick.server.api.chat.entity.ChatRoom;
import com.campick.server.api.chat.service.ChatService;
import com.campick.server.common.config.security.SecurityMember;
import com.campick.server.common.dto.PageResponseDto;
import com.campick.server.common.response.ApiResponse;
import com.campick.server.common.response.SuccessStatus;
import lombok.RequiredArgsConstructor;
import org.checkerframework.checker.units.qual.A;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
Expand All @@ -35,11 +32,8 @@ public ResponseEntity<ApiResponse<Long>> startChat(@RequestBody ChatRoomReqDto c
}

@GetMapping("/{chatRoomId}")
public ResponseEntity<ApiResponse<ChatRoomPageResDto<ChatMessageResDto>>> getChatRoom(@PathVariable Long chatRoomId,
@RequestParam(defaultValue = "0") Integer page,
@RequestParam(defaultValue = "20") Integer size) {
Pageable pageable = PageRequest.of(page, size);
return ApiResponse.success(SuccessStatus.SEND_LOAD_CHATROOM, chatService.getChatRoom(chatRoomId, pageable));
public ResponseEntity<ApiResponse<ChatRoomResDto>> getChatRoom(@PathVariable Long chatRoomId) {
return ApiResponse.success(SuccessStatus.SEND_LOAD_CHATROOM, chatService.getChatRoom(chatRoomId));
}

@PatchMapping("/{chatRoomId}")
Expand All @@ -51,13 +45,10 @@ public ResponseEntity<ApiResponse<Void>> readChatRoom(@PathVariable Long chatRoo
}

@GetMapping("/my")
public ResponseEntity<ApiResponse<MyChatPageResDto<ChatListDto>>> getMyChatRoom(@RequestParam(defaultValue = "0") Integer page,
@RequestParam(defaultValue = "10") Integer size,
@AuthenticationPrincipal SecurityMember securityMember) {
Pageable pageable = PageRequest.of(page, size);
public ResponseEntity<ApiResponse<MyChatResDto>> getMyChatRoom(@AuthenticationPrincipal SecurityMember securityMember) {
Long memberId = securityMember.getId();

return ApiResponse.success(SuccessStatus.SEND_MY_CHATROOMS, chatService.getMyChatRooms(memberId, pageable));
return ApiResponse.success(SuccessStatus.SEND_MY_CHATROOMS, chatService.getMyChatRooms(memberId));
}

@GetMapping("/totalUnreadMessage")
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.campick.server.api.chat.repository;

import com.campick.server.api.chat.entity.ChatMessage;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
Expand Down Expand Up @@ -32,15 +30,6 @@ Integer markMessagesAsRead(@Param("chatRoomId") Long chatRoomId,
"ORDER BY m.createdAt DESC LIMIT 1")
ChatMessage findLastMessageByChatRoomId(@Param("chatRoomId") Long chatRoomId);

@Query("""
SELECT m FROM ChatMessage m
WHERE m.chatRoom.id IN :chatRoomIds
AND m.createdAt IN (
SELECT MAX(m2.createdAt) FROM ChatMessage m2 WHERE m2.chatRoom.id = m.chatRoom.id
)
""")
List<ChatMessage> findLastMessages(@Param("chatRoomIds") List<Long> chatRoomIds);

@Query("SELECT COUNT(m) FROM ChatMessage m " +
"WHERE m.chatRoom.id = :chatRoomId " +
"AND m.isRead = false " +
Expand All @@ -54,6 +43,4 @@ Integer countUnreadMessages(@Param("chatRoomId") Long chatRoomId,
"AND cm.isRead = false " +
"AND cm.member.id <> :memberId")
Integer countAllUnreadMessages(@Param("memberId") Long memberId);

Page<ChatMessage> findByChatRoomIdOrderByCreatedAtDesc(Long chatRoomId, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import com.campick.server.api.chat.entity.ChatRoom;
import com.campick.server.api.member.entity.Member;
import com.campick.server.api.product.entity.Product;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
Expand All @@ -30,20 +28,5 @@ public interface ChatRoomRepository extends JpaRepository<ChatRoom, Long> {
" OR (b.id = :memberId AND cr.isBuyerOut = false))")
List<ChatRoom> findAllByMemberId(@Param("memberId") Long memberId);

@Query("""
SELECT c FROM ChatRoom c
WHERE c.seller.id = :memberId OR c.buyer.id = :memberId
ORDER BY (
SELECT MAX(m.createdAt) FROM ChatMessage m WHERE m.chatRoom = c
) DESC
""")
Page<ChatRoom> findByMemberIdOrderByLastMessageDesc(@Param("memberId") Long memberId, Pageable pageable);

Optional<ChatRoom> findByProductAndSellerAndBuyer(Product product, Member seller, Member buyer);

@Query("""
SELECT COUNT(c) FROM ChatRoom c
WHERE c.seller.id = :memberId OR c.buyer.id = :memberId
""")
long countChatRoomByMemberId(@Param("memberId") Long memberId);
}
79 changes: 33 additions & 46 deletions src/main/java/com/campick/server/api/chat/service/ChatService.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,12 @@
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
Expand Down Expand Up @@ -116,35 +111,21 @@ public Long startChatRoom(ChatRoomReqDto chatRoomReqDto, Long memberId) {
return chatRoom.getId();
}

public ChatRoomPageResDto<ChatMessageResDto> getChatRoom(Long chatRoomId, Pageable pageable) {
public ChatRoomResDto getChatRoom(Long chatRoomId) {
ChatRoom chatRoom = chatRoomRepository.findDetailById(chatRoomId).orElseThrow(
() -> new NotFoundException(ErrorStatus.CHAT_NOT_FOUND.getMessage())
);
Page<ChatMessage> chatMessages = chatMessageRepository.findByChatRoomIdOrderByCreatedAtDesc(chatRoomId, pageable);
Page<ChatMessageResDto> chatMessageResDtos = chatMessages.map(
cm -> ChatMessageResDto.builder()
.message(cm.getMessage())
.senderId(cm.getMember().getId())
.sendAt(TimeUtil.getTimeAgo(cm.getCreatedAt()))
.isRead(cm.getIsRead())
.build()
);
List<ChatMessage> chatMessages = chatMessageRepository.findMessagesByChatRoomId(chatRoomId);

return convertToChatRoomResDto(chatRoom, chatMessageResDtos);
return convertToChatRoomResDto(chatRoom, chatMessages);
}

public void readChatRoom(Long chatRoomId, Long memberId) {
Integer readMessageCount = chatMessageRepository.markMessagesAsRead(chatRoomId, memberId);
}

public MyChatPageResDto<ChatListDto> getMyChatRooms(Long memberId, Pageable pageable) {
Page<ChatRoom> myChatRooms = chatRoomRepository.findByMemberIdOrderByLastMessageDesc(memberId, pageable);
List<Long> chatRoomIds = myChatRooms.stream().map(ChatRoom::getId).toList();
Map<Long, ChatMessage> lastMessageMap = chatMessageRepository.findLastMessages(chatRoomIds)
.stream()
.collect(Collectors.toMap(m -> m.getChatRoom().getId(), Function.identity()));
long total = chatRoomRepository.countChatRoomByMemberId(memberId);

public MyChatResDto getMyChatRooms(Long memberId) {
List<ChatRoom> myChatRooms = chatRoomRepository.findAllByMemberId(memberId);
List<ChatListDto> chatListDtos = myChatRooms.stream().map(
chatRoom -> {
String thumbnailUrl = chatRoom.getProduct().getImages().stream()
Expand All @@ -153,7 +134,7 @@ public MyChatPageResDto<ChatListDto> getMyChatRooms(Long memberId, Pageable page
.findFirst()
.orElse(null);

ChatMessage lastChatMessage = lastMessageMap.get(chatRoom.getId());
ChatMessage lastChatMessage = chatMessageRepository.findLastMessageByChatRoomId(chatRoom.getId());
Integer unreadMessageCount = chatMessageRepository.countUnreadMessages(chatRoom.getId(), memberId);

return ChatListDto.builder()
Expand All @@ -168,10 +149,10 @@ public MyChatPageResDto<ChatListDto> getMyChatRooms(Long memberId, Pageable page
.build();
}).toList();

Integer totalUnreadMessage = chatMessageRepository.countAllUnreadMessages(memberId);
Page<ChatListDto> pageImpl = new PageImpl<>(chatListDtos, pageable, total);

return new MyChatPageResDto<>(pageImpl, totalUnreadMessage);
return MyChatResDto.builder()
.chatRoom(chatListDtos)
.totalUnreadMessage(chatMessageRepository.countAllUnreadMessages(memberId))
.build();
}

public Integer getTotalUnreadMessage(Long memberId) {
Expand Down Expand Up @@ -201,6 +182,7 @@ public void handleChatMessage(WebSocketSession session, JsonNode data) {

private ChatMessageResDto convertToChatMessageResDto(ChatMessage chatMessage, Long chatRoomId) {
return ChatMessageResDto.builder()
.chatId(chatRoomId)
.message(chatMessage.getMessage())
.chatId(chatRoomId)
.senderId(chatMessage.getMember().getId())
Expand Down Expand Up @@ -271,29 +253,34 @@ public void broadcastSoldEvent(WebSocketSession session, JsonNode data) {
}
}

private ChatRoomPageResDto<ChatMessageResDto> convertToChatRoomResDto(ChatRoom chatRoom, Page<ChatMessageResDto> chatMessages) {
private ChatRoomResDto convertToChatRoomResDto(ChatRoom chatRoom, List<ChatMessage> chatMessages) {
String thumbnailImage = chatRoom.getProduct().getImages().stream()
.filter(ProductImage::getIsThumbnail)
.map(ProductImage::getImageUrl)
.findFirst()
.orElse(null);

ChatRoomPageResDto<ChatMessageResDto> chatRoomPageResDto = new ChatRoomPageResDto<>(chatMessages);

chatRoomPageResDto.setSellerId(chatRoom.getSeller().getId());
chatRoomPageResDto.setSellerNickname(chatRoom.getSeller().getNickname());
chatRoomPageResDto.setBuyerId(chatRoom.getBuyer().getId());
chatRoomPageResDto.setBuyerNickname(chatRoom.getBuyer().getNickname());
chatRoomPageResDto.setSellerProfileImage(chatRoom.getSeller().getProfileImageUrl());
chatRoomPageResDto.setSellerPhoneNumber(chatRoom.getSeller().getMobileNumber());
chatRoomPageResDto.setProductId(chatRoom.getProduct().getId());
chatRoomPageResDto.setProductTitle(chatRoom.getProduct().getTitle());
chatRoomPageResDto.setProductImage(thumbnailImage);
chatRoomPageResDto.setProductStatus(chatRoom.getProduct().getStatus().toString());
chatRoomPageResDto.setProductPrice(chatRoom.getProduct().getCost().toString());
chatRoomPageResDto.setIsActive(!chatRoom.getIsSellerOut() && !chatRoom.getIsBuyerOut());

return chatRoomPageResDto;
ChatRoomResDto chatRoomResDto = new ChatRoomResDto();
chatRoomResDto.setSellerId(chatRoom.getSeller().getId());
chatRoomResDto.setSellerNickname(chatRoom.getSeller().getNickname());
chatRoomResDto.setBuyerId(chatRoom.getBuyer().getId());
chatRoomResDto.setBuyerNickname(chatRoom.getBuyer().getNickname());
chatRoomResDto.setSellerProfileImage(chatRoom.getSeller().getProfileImageUrl());
chatRoomResDto.setSellerPhoneNumber(chatRoom.getSeller().getMobileNumber());
chatRoomResDto.setProductId(chatRoom.getProduct().getId());
chatRoomResDto.setProductTitle(chatRoom.getProduct().getTitle());
chatRoomResDto.setProductImage(thumbnailImage);
chatRoomResDto.setProductStatus(chatRoom.getProduct().getStatus().toString());
chatRoomResDto.setProductPrice(chatRoom.getProduct().getCost().toString());
chatRoomResDto.setIsActive(!chatRoom.getIsSellerOut() && !chatRoom.getIsBuyerOut());

List<ChatMessageResDto> chatMessageResDto = chatMessages.stream()
.map(
cm -> convertToChatMessageResDto(cm, chatRoom.getId())
).toList();
chatRoomResDto.setChatData(chatMessageResDto);

return chatRoomResDto;
}

public void removeFromChatRoomMap(Long memberId, WebSocketSession session) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,7 @@
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;


Expand Down Expand Up @@ -86,7 +82,6 @@ public Long createProduct(ProductCreateReqDto dto, Long memberId) {
Random random = new Random();
Car car = cars.get(random.nextInt(cars.size()));


Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new BadRequestException(ErrorStatus.MEMBER_NOT_FOUND.getMessage()));

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ spring.datasource.password=${SPRING_DATASOURCE_PASSWORD}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

#! TODO When Start Deploy must change this option 'create' to 'update'
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.ddl-auto=create
spring.jpa.defer-datasource-initialization=true
#spring.sql.init.mode=always
spring.jpa.show-sql=true
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ INSERT INTO model (type_id, model_name) VALUES ((SELECT type_id FROM `type` WHER
-- TRUCK_CAMPER
INSERT INTO model (type_id, model_name) VALUES ((SELECT type_id FROM `type` WHERE type_name = 'TRUCK_CAMPER'), '그외');

-- ETC
INSERT INTO model (type_id, model_name) VALUES ((SELECT type_id FROM `type` WHERE type_name = 'ETC'), '기타');

-- Engines
INSERT INTO `engine` (feul_type, transmission, horse_power, fuel_efficiency) VALUES ('GASOLINE', 'MANUAL', 150, 10.0);
INSERT INTO `engine` (feul_type, transmission, horse_power, fuel_efficiency) VALUES ('GASOLINE', 'AUTOMATIC', 150, 10.0);
Expand Down