Skip to content

Commit

Permalink
Merge pull request #65 from Team-baebae/fix/image/#64
Browse files Browse the repository at this point in the history
Fix/image/#64
  • Loading branch information
tioon authored May 13, 2024
2 parents f3e3040 + 0c68ade commit 7d13ff0
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.web.baebaeBE.domain.answer.exception.AnswerError;
import com.web.baebaeBE.domain.category.exception.CategoryException;
import com.web.baebaeBE.domain.login.exception.LoginException;
import com.web.baebaeBE.domain.member.dto.MemberResponse;
import com.web.baebaeBE.domain.member.exception.MemberException;
import com.web.baebaeBE.global.error.exception.BusinessException;
import com.web.baebaeBE.domain.answer.entity.Answer;
import com.web.baebaeBE.domain.answer.repository.AnswerRepository;
Expand All @@ -13,43 +15,54 @@
import com.web.baebaeBE.domain.member.entity.Member;
import com.web.baebaeBE.domain.member.repository.MemberRepository;
import com.web.baebaeBE.domain.category.dto.CategoryResponse;
import com.web.baebaeBE.global.image.s3.S3ImageStorageService;
import jakarta.persistence.EntityManager;
import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
@RequiredArgsConstructor
@Transactional
public class CategoryService {
private final CategoryRepository categoryRepository;
private final CategorizedAnswerRepository categoryAnswerRepository;
private final MemberRepository memberRepository;
private final AnswerRepository answerRepository;
private final EntityManager entityManager; // Answer 엔티티 프록시 가져오기 위함.
private final CategoryRepository categoryRepository;
private final CategorizedAnswerRepository categoryAnswerRepository;
private final MemberRepository memberRepository;
private final AnswerRepository answerRepository;
private final EntityManager entityManager; // Answer 엔티티 프록시 가져오기 위함.
private final S3ImageStorageService s3ImageStorageService;

public Category createCategory(Long memberId, MultipartFile categoryImage, String categoryName) {
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new BusinessException(LoginException.NOT_EXIST_MEMBER));

String imagePath = "default_image_path";
if (categoryImage != null) {
//imagePath = imageStorageService.save(categoryImage); //추후 수정 예정
}

Category category = Category.builder()
.member(member)
.categoryName(categoryName)
.categoryImage(imagePath)
.build();

return categoryRepository.save(category);
category = categoryRepository.save(category);

String imageUrl = null;
if(categoryImage == null)
imageUrl = s3ImageStorageService.getDefaultFileUrl();
else
imageUrl = convertImageToObject(memberId, category.getCategoryId(), categoryImage);

category.updateCategoryImage(imageUrl);

return category;
}

public CategoryResponse.CategoryInformationResponse createAnswersToCategory(Long categoryId, List<Long> answerIds) {
Expand Down Expand Up @@ -87,15 +100,41 @@ public Category updateCategoryName(Long categoryId, String categoryName) {
return categoryRepository.save(category);
}



public CategoryResponse.CategoryInformationResponse updateCategoryImage(Long categoryId, MultipartFile imageFile) {
// Category 엔티티 조회
// 엔티티 조회
Category category = categoryRepository.findById(categoryId)
.orElseThrow(() -> new BusinessException(CategoryException.CATEGORY_NOT_FOUND));
Member member = memberRepository.findById(category.getMember().getId())
.orElseThrow(() -> new BusinessException(LoginException.NOT_EXIST_MEMBER));

String imageUrl
= convertImageToObject(member.getId(), category.getCategoryId(), imageFile);

category.updateCategoryImage(imageUrl);
categoryRepository.save(category);

category.updateCategoryImage("default_image_path"); // 저장방식 추후 수정

return CategoryResponse.CategoryInformationResponse.of(category);
}
public String convertImageToObject(Long memberId, Long categoryId, MultipartFile image) {
if (image.isEmpty()) {
throw new BusinessException(MemberException.INVAILD_IMAGE_FILE);
}
String fileType = "category";
int index = 0; // 카테고리 이미지에는 인덱스가 필요 없으므로 사용하지 않음
String fileName = memberId + "_" + categoryId +"_category_image.jpg";

try (InputStream inputStream = image.getInputStream()) {
long size = image.getSize();
String contentType = image.getContentType();
return s3ImageStorageService.uploadFile(memberId.toString(), categoryId.toString(), fileType, index, inputStream, size, contentType);
} catch (IOException e) {
log.error(e.toString());
throw new RuntimeException(e);
}
}
public CategoryResponse.CategoryInformationResponse updateAnswersToCategory(Category category, List<Long> answerIds) {

// 새로운 Answer들의 id들을 Set에 저장
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public static class SignUpResponse {
private String nickname;
@Schema(example = "KAKAO")
private MemberType memberType;
private String profileImage;
@Schema(example = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJiZWJlLXNlcnZlciIsImlhdCI6MTcxMzQxNjgyNSwiZXhwIjoxNzEzNTAzMjI1LCJzdWIiOiJ1amozOTAwQG5hdmVyLmNvbSIsImp0aSI6IjIifQ.wvQR4Uoa8KtMgIDwRn7AwKy60olwnzP33_WLI1l3q4I")
private String accessToken;
@Schema(example = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJiZWJlLXNlcnZlciIsImlhdCI6MTcxMzQxNjgyNSwiZXhwIjoxNzE0NjI2NDI1LCJzdWIiOiJ1amozOTAwQG5hdmVyLmNvbSIsImp0aSI6IjIifQ.BYrRkhwK1SSAe3nanmRIT_oSZkWyZlNnl3wFLI_nIqY")
Expand All @@ -41,6 +42,7 @@ public static SignUpResponse of(Member member, String accessToken) {
.email(member.getEmail())
.nickname(member.getNickname())
.memberType(member.getMemberType())
.profileImage(member.getProfileImage())
.refreshToken(member.getRefreshToken())
.accessToken(accessToken)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.web.baebaeBE.domain.oauth2.service.Oauth2Service;
import com.web.baebaeBE.domain.login.exception.LoginException;
import com.web.baebaeBE.global.error.exception.BusinessException;
import com.web.baebaeBE.global.image.s3.S3ImageStorageService;
import com.web.baebaeBE.global.jwt.JwtTokenProvider;
import com.web.baebaeBE.domain.member.entity.Member;
import com.web.baebaeBE.domain.member.repository.MemberRepository;
Expand All @@ -14,6 +15,7 @@
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
Expand All @@ -24,6 +26,7 @@ public class LoginService {
private final MemberRepository memberRepository;
private final Oauth2Service oauth2Service;
private final JwtTokenProvider jwtTokenProvider;
private final S3ImageStorageService s3ImageStorageService;
public static final Duration REFRESH_TOKEN_DURATION = Duration.ofDays(14); // 리프레시 토큰 유효기간.
public static final Duration ACCESS_TOKEN_DURATION = Duration.ofHours(1); // 액세스 토큰 유효기간.

Expand Down Expand Up @@ -85,6 +88,7 @@ public LoginResponse.SignUpResponse signUpNewUser(KakaoUserInfoDto kakaoUserInfo
.nickname(signUpRequest.getNickname())
.memberType(signUpRequest.getMemberType())
.refreshToken(null)
.profileImage(s3ImageStorageService.getDefaultFileUrl())
.tokenExpirationTime(LocalDateTime.now().plus(REFRESH_TOKEN_DURATION))
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,34 +39,31 @@ public MemberResponse.ProfileImageResponse getProfileImage(Long memberId) {
}

public MemberResponse.ProfileImageResponse updateProfileImage(Long memberId, MultipartFile image) {
String imageUrl = null;
try {
imageUrl = convertImageToObject(memberId, image);
} catch (IOException e) {
log.error(String.valueOf(e));
throw new RuntimeException(e);
}
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new BusinessException(LoginException.NOT_EXIST_MEMBER));

String imageUrl = convertImageToObject(memberId, image);
member.updateProfileImage(imageUrl);
memberRepository.save(member);

return MemberResponse.ProfileImageResponse.of(imageUrl);
}

public String convertImageToObject(Long memberId, MultipartFile image) throws IOException {
public String convertImageToObject(Long memberId, MultipartFile image){
if (image.isEmpty()) {
throw new BusinessException(MemberException.INVAILD_IMAGE_FILE);
}
String fileType = "profile";
int index = 0; // 프로필 이미지에는 인덱스가 필요 없으므로 사용하지 않음
String fileName = memberId + "_profile.jpg";
String path = memberId + "/" + fileName;

try (InputStream inputStream = image.getInputStream()) {
long size = image.getSize();
String contentType = image.getContentType();
return s3ImageStorageService.uploadFile(memberId.toString(), null, fileType, index, inputStream, size, contentType);
} catch (IOException e) {
log.error(e.toString());
throw new RuntimeException(e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ public class S3ImageStorageService implements ImageStorageService {
private String bucketName;

@Override
public String uploadFile(String memberId, String answerId, String fileType, int index, InputStream inputStream, long size, String contentType) {
String key = generateFilePath(memberId, answerId, fileType, index);
public String uploadFile(String memberId, String Id, String fileType, int index, InputStream inputStream, long size, String contentType) {
String key = generateFilePath(memberId, Id, fileType, index);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(size);
metadata.setContentType(contentType);
PutObjectRequest request = new PutObjectRequest(bucketName, key, inputStream, metadata)
.withCannedAcl(CannedAccessControlList.PublicRead);
amazonS3Client.putObject(request);
return getFileUrl(memberId, answerId, fileType, index);
return getFileUrl(memberId, Id, fileType, index);
}

@Override
Expand All @@ -38,22 +38,30 @@ public void deleteFile(String memberId, String answerId, String fileType, int in
amazonS3Client.deleteObject(bucketName, key);
}

// 여기서 Id는 answerId OR categoryId
@Override
public String getFileUrl(String memberId, String answerId, String fileType, int index) {
String key = generateFilePath(memberId, answerId, fileType, index);
public String getFileUrl(String memberId, String Id, String fileType, int index) {
String key = generateFilePath(memberId, Id, fileType, index);
return amazonS3Client.getUrl(bucketName, key).toExternalForm();
}

public String generateFilePath(String memberId, String answerId, String fileType, int index) {
public String getDefaultFileUrl() {
return amazonS3Client.getUrl(bucketName,"default_image.jpg").toExternalForm();
}

// 여기서 Id는 answerId OR categoryId
public String generateFilePath(String memberId, String id, String fileType, int index) {
switch (fileType) {
case "profile":
return memberId + "/profile.jpg";
case "image":
return memberId + "/" + answerId + "/image_" + index + ".jpg";
return memberId + "/" + id + "/image_" + index + ".jpg";
case "music":
return memberId + "/" + answerId + "/music.jpg";
return memberId + "/" + id + "/music.jpg";
case "audio":
return memberId + "/" + answerId + "/audio.mp3";
return memberId + "/" + id + "/audio.mp3";
case "category":
return memberId + "/" + id + "/category_image.jpg";
default:
throw new IllegalArgumentException("Unknown file type");
}
Expand Down

0 comments on commit 7d13ff0

Please sign in to comment.