Skip to content
This repository was archived by the owner on Jan 11, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions src/main/java/com/example/spot/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,10 @@ public void updateInfo(MemberUpdateDTO req) {
this.profileImage = req.getProfileImage();
}

public void updateProfileImage(String profileImage) {
this.profileImage = profileImage;
}

public void addStudyPost(StudyPost studyPost) {
if (this.studyPostList == null) {
this.studyPostList = new ArrayList<>();
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/example/spot/domain/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class Post extends BaseEntity {

private int hitNum;

private String image;

@Enumerated(EnumType.STRING)
private Board board;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ public MemberResponseDTO.SocialLoginSignInDTO signUpByKAKAO(String accessToken)
// 존재하는 경우, 사용자 정보를 가져옴
Member member = memberRepository.findByEmail(kaKaoUser.toMember().getEmail())
.orElseThrow(() -> new GeneralException(ErrorStatus._MEMBER_NOT_FOUND));

updateMemberProfileImage(member, kaKaoUser);

isSpotMember = true;
// JWT 토큰 생성
TokenDTO token = jwtTokenProvider.createToken(member.getId());
Expand Down Expand Up @@ -143,6 +146,12 @@ public MemberResponseDTO.SocialLoginSignInDTO signUpByKAKAO(String accessToken)
return SocialLoginSignInDTO.toDTO(isSpotMember, dto);
}

private void updateMemberProfileImage(Member member, KaKaoUser kaKaoUser) {
if (!member.getProfileImage().equals(kaKaoUser.getProperties().getProfile_image())) {
member.updateProfileImage(kaKaoUser.getProperties().getProfile_image());
}
}

/**
* 리프레시 토큰을 DB에 저장합니다.
* @param member 리프레시 토큰을 발급한 회원 정보
Expand Down Expand Up @@ -299,6 +308,8 @@ public SocialLoginSignInDTO signUpByKAKAOForTest(String code) throws JsonProcess
Member member = memberRepository.findByEmail(kaKaoUser.toMember().getEmail())
.orElseThrow(() -> new MemberHandler(ErrorStatus._MEMBER_NOT_FOUND));

updateMemberProfileImage(member, kaKaoUser);

// 탈퇴한(inactive) 회원이면 기존 정보 삭제
if (member.getInactive() != null) {
refreshTokenRepository.deleteByMemberId(member.getId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
import com.example.spot.domain.enums.PostStatus;
import com.example.spot.domain.mapping.MemberScrap;
import com.example.spot.repository.*;
import com.example.spot.service.s3.S3ImageService;
import com.example.spot.web.dto.post.*;
import com.example.spot.web.dto.util.response.ImageResponse.ImageUploadResponse;
import com.example.spot.web.dto.util.response.ImageResponse.Images;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -30,6 +33,7 @@ public class PostCommandServiceImpl implements PostCommandService {
private final MemberScrapRepository memberScrapRepository;
private final PostReportRepository postReportRepository;

private final S3ImageService s3ImageService;
private final LikedPostQueryService likedPostQueryService;
private final LikedPostCommentQueryService likedPostCommentQueryService;

Expand All @@ -54,8 +58,11 @@ public PostCreateResponse createPost(Long memberId, PostCreateRequest postCreate
throw new PostHandler(ErrorStatus._FORBIDDEN); // 관리자만 접근 가능
}

List<String> imageUrls = getImageUrls(postCreateRequest);

// Post 객체 생성 및 연관 관계 설정
Post post = createPostEntity(postCreateRequest, member);
Post post = createPostEntity(postCreateRequest, member, imageUrls);

// 게시글 저장
post = postRepository.save(post);

Expand All @@ -64,19 +71,33 @@ public PostCreateResponse createPost(Long memberId, PostCreateRequest postCreate
// 게시글 생성 정보 반환
return PostCreateResponse.toDTO(post);
}

private List<String> getImageUrls(PostCreateRequest postCreateRequest) {
ImageUploadResponse imageUploadResponse = s3ImageService.uploadImages(List.of(postCreateRequest.getImage()));

List<String> imageUrls = imageUploadResponse.getImageUrls().stream()
.map(Images::getImageUrl)
.toList();
return imageUrls;
}

/**
* 게시글 객체를 생성합니다.
* @param postCreateRequest 생성할 게시글 정보
* @param currentMember 게시글을 작성하는 회원 정보
* @return 생성된 게시글 객체
*/
private Post createPostEntity(PostCreateRequest postCreateRequest, Member currentMember) {
private Post createPostEntity(PostCreateRequest postCreateRequest, Member currentMember, List<String> images) {
String image = (images != null && !images.isEmpty() && !images.get(0).isEmpty())
? images.get(0)
: null;

return Post.builder()
.isAnonymous(postCreateRequest.isAnonymous())
.title(postCreateRequest.getTitle())
.content(postCreateRequest.getContent())
.scrapNum(0)
.image(image)
.commentNum(0)
.hitNum(0)
.board(postCreateRequest.getType())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

Expand All @@ -39,13 +41,13 @@ public class PostController {

익명 여부를 선택할 수 있습니다.

생성된 게시글의 고유 ID와 게시글 종류, 생성 시간을 반환합니다.
생성된 게시글의 고유 ID와 게시글 종류, 생성 시간을 반환합니다. 요청 시, 요청 타입은 Multipart/form-data로 보내야 합니다.
""",
security = @SecurityRequirement(name = "accessToken")
)
@PostMapping
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ApiResponse<PostCreateResponse> create(
@RequestBody @Valid PostCreateRequest postCreateRequest
@ModelAttribute @Valid PostCreateRequest postCreateRequest
) {
PostCreateResponse response = postCommandService.createPost(SecurityUtils.getCurrentUserId(), postCreateRequest);
return ApiResponse.onSuccess(SuccessStatus._CREATED, response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.web.multipart.MultipartFile;

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PostCreateRequest {
Expand All @@ -32,4 +37,7 @@ public class PostCreateRequest {
@Schema(description = "익명 여부", example = "false")
private boolean anonymous;

@Schema(description = "이미지 파일", type = "string", format = "binary")
private MultipartFile image;

}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ public class PostSingleResponse {
)
private int viewCount;

private String imageUrl;

@Schema(
description = "현재 사용자의 해당 게시글 좋아요 여부입니다."
)
Expand Down Expand Up @@ -140,6 +142,7 @@ public static PostSingleResponse toDTO(Post post, long likeCount, long scrapCoun
.title(post.getTitle())
.content(post.getContent())
.likeCount(likeCount)
.imageUrl(post.getImage())
.likedByCurrentUser(likedByCurrentUser)
.createdByCurrentUser(createdByCurrentUser)
.commentCount(commentResponse.getComments().size())
Expand Down
Loading