Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;
import java.util.Optional;

@Service
Expand Down Expand Up @@ -75,35 +76,40 @@ public UserDetailResponse updateUserProfile(Long userId, UserProfileRequest requ
throw new CustomException(ErrorCode.NICKNAME_DUPLICATED);
}


// UserProfile 업데이트
UserProfile profile = user.getUserProfile();
profile.setNickname(request.nickname());
profile.setProfileImageUrl(request.profileImageUrl());
profile.setBio(request.bio());
profile.setBirthDate(request.birthDate());

// 프로필 이미지 및 매핑 업데이트
updateProfileImage(userId, request.profileImageUrl());
// TODO: 프로필 이미지 및 매핑 업데이트 리팩토링 필요
// 프로필 이미지 변경이 있는 경우만 수행
String newUrl = request.profileImageUrl();
String oldUrl = profile.getProfileImageUrl();
if (!Objects.equals(newUrl, oldUrl)) {
// 외부 이미지(S3 외부 URL)는 매핑 로직 제외
if (isExternalImageUrl(newUrl)) {
// 기존 매핑만 제거 (소셜 이미지로 바뀌면 내부 매핑 필요 없음)
removeExistingMapping(userId);
} else {
updateProfileImage(userId, newUrl);
}
profile.setProfileImageUrl(newUrl);
}

// UserDetailResponse로 변환하여 반환
return UserDetailResponse.from(user);
}

/**
* 프로필 이미지 및 매핑 교체 로직
* - 기존 이미지(S3 + FileAttachment + Mapping) 삭제 후 새 매핑 생성
* 내부 저장소(S3) 이미지 교체 로직
* - 기존 매핑 및 파일 삭제 후 새 매핑 생성
*/
private void updateProfileImage(Long userId, String newImageUrl) {

// 기존 매핑 및 파일 삭제
attachmentMappingRepository.findByEntityTypeAndEntityId(EntityType.PROFILE, userId)
.ifPresent(existingMapping -> {
FileAttachment oldAttachment = existingMapping.getFileAttachment();
if (oldAttachment != null) {
fileService.deleteFile(oldAttachment.getId(), userId);
}
attachmentMappingRepository.delete(existingMapping);
});
// 기존 매핑 제거
removeExistingMapping(userId);

// 새 이미지가 없는 경우
if (newImageUrl == null || newImageUrl.isBlank()) {
Expand All @@ -124,6 +130,33 @@ private void updateProfileImage(Long userId, String newImageUrl) {
attachmentMappingRepository.save(newMapping);
}

/**
* 기존 프로필 이미지 매핑 및 파일 삭제
*/
private void removeExistingMapping(Long userId) {
attachmentMappingRepository.findByEntityTypeAndEntityId(EntityType.PROFILE, userId)
.ifPresent(mapping -> {
FileAttachment oldAttachment = mapping.getFileAttachment();
if (oldAttachment != null) {
fileService.deleteFile(oldAttachment.getId(), userId);
}
attachmentMappingRepository.delete(mapping);
});
}

/**
* 외부 이미지 URL 판별
* - 우리 S3 또는 CDN이 아니면 true
* - 필요 시 application.yml에서 환경변수로 관리
*/
private boolean isExternalImageUrl(String url) {
if (url == null || url.isBlank()) return true;

// TODO: 하드 코딩 제거
return !(url.startsWith("https://team5-s3-1.s3.ap-northeast-2.amazonaws.com")
|| url.contains("cdn.example.com"));
}

/**
* 비밀번호 변경 서비스
* 1. 사용자 조회 및 상태 검증
Expand Down Expand Up @@ -164,7 +197,7 @@ public void deleteUser(Long userId) {
User user = getValidUser(userId);

// 프로필 이미지 및 매핑 삭제
deleteProfileImage(userId);
removeExistingMapping(userId);

// 상태 변경 (soft delete)
user.setUserStatus(UserStatus.DELETED);
Expand All @@ -185,20 +218,6 @@ public void deleteUser(Long userId) {
}
}

/**
* 프로필 이미지 및 매핑 삭제
*/
private void deleteProfileImage(Long userId) {
attachmentMappingRepository.findByEntityTypeAndEntityId(EntityType.PROFILE, userId)
.ifPresent(mapping -> {
FileAttachment attachment = mapping.getFileAttachment();
if (attachment != null) {
fileService.deleteFile(attachment.getId(), userId);
}
attachmentMappingRepository.delete(mapping);
});
}

/**
* 내 게시글 목록 조회 서비스
* 1. 사용자 조회 및 상태 검증
Expand Down