Skip to content

Commit ba34bbf

Browse files
fix duplicate method
1 parent de4c4f1 commit ba34bbf

3 files changed

Lines changed: 98 additions & 93 deletions

File tree

src/main/java/com/_oormthon/seasonthon/domain/ai/service/ConversationStateService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ public MessageResult processUserMessageTransactional(Long userId, String userMes
170170
.stepDate(step.stepDate())
171171
.day(step.day())
172172
.description(step.description())
173+
.tips(step.tips())
173174
.build())
174175
.toList();
175176
todoStepRepository.saveAll(todoSteps);

src/main/java/com/_oormthon/seasonthon/domain/member/controller/UserController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public ResponseEntity<UserResponse> getMyPage(@AuthenticationPrincipal User user
3737

3838
@PutMapping("/my-page")
3939
public ResponseEntity<UserResponse> updateMyPage(@AuthenticationPrincipal User user,
40-
@RequestBody UpdateMypageRequest request) {
40+
@RequestBody UpdateMypageRequest request) {
4141
return ResponseEntity.ok(userService.updateMyPage(user.getUserId(), request));
4242
}
4343
}
Lines changed: 96 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
package com._oormthon.seasonthon.domain.s3.service;
22

3-
import lombok.RequiredArgsConstructor;
4-
import org.springframework.beans.factory.annotation.Value;
5-
import org.springframework.stereotype.Service;
6-
73
import com._oormthon.seasonthon.domain.member.dto.res.UserResponse;
84
import com._oormthon.seasonthon.domain.member.service.UserService;
95
import com._oormthon.seasonthon.domain.s3.dto.PresignedUrlResponse;
10-
6+
import lombok.RequiredArgsConstructor;
7+
import org.springframework.beans.factory.annotation.Value;
8+
import org.springframework.stereotype.Service;
119
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
1210
import software.amazon.awssdk.regions.Region;
1311
import software.amazon.awssdk.services.s3.S3Client;
14-
import software.amazon.awssdk.services.s3.model.*;
12+
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
13+
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
1514
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
16-
import software.amazon.awssdk.services.s3.presigner.model.*;
15+
import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest;
1716

1817
import java.time.Duration;
1918
import java.util.UUID;
@@ -22,89 +21,94 @@
2221
@RequiredArgsConstructor
2322
public class S3Service {
2423

25-
private final S3Presigner s3Presigner;
26-
private final UserService userService;
27-
28-
@Value("${cloud.s3.bucket}")
29-
private String bucket;
30-
31-
/**
32-
* S3 Presigned URL (PUT) 발급
33-
*/
34-
public PresignedUrlResponse generateUploadPresignedUrl(Long userId, String fileName, String fileType) {
35-
UserResponse user = userService.getUserById(userId);
36-
37-
// 고유한 S3 키 생성 (닉네임/UUID-파일명)
38-
String key = user.nickname() + "/" + UUID.randomUUID() + "-" + fileName;
39-
40-
// Presigned URL 발급용 요청 생성
41-
PutObjectRequest objectRequest = PutObjectRequest.builder()
42-
.bucket(bucket)
43-
.key(key)
44-
.contentType(fileType)
45-
.build();
46-
47-
// Presigned URL 생성
48-
PresignedPutObjectRequest presignedRequest = s3Presigner.presignPutObject(
49-
r -> r.putObjectRequest(objectRequest)
50-
.signatureDuration(Duration.ofMinutes(10)));
51-
52-
// JSON 형태로 리턴
53-
return new PresignedUrlResponse(presignedRequest.url().toString(), key);
54-
}
55-
56-
/**
57-
* S3 객체 삭제
58-
*/
59-
public void deleteFile(Long userId, String fileName) {
60-
61-
String key = userService.getUserById(userId).nickname() + "/" + fileName;
62-
63-
S3Client s3 = S3Client.builder()
64-
.region(Region.AP_NORTHEAST_2)
65-
.credentialsProvider(DefaultCredentialsProvider.builder().build())
66-
.build();
67-
68-
s3.deleteObject(DeleteObjectRequest.builder()
69-
.bucket(bucket)
70-
.key(key)
71-
.build());
72-
}
73-
74-
/**
75-
* 파일명에서 Content-Type 추론
76-
*/
77-
// private String determineContentTypeFromKey(String key) {
78-
// if (key == null)
79-
// return "application/octet-stream"; // 기본값
80-
81-
// String lowerKey = key.toLowerCase();
82-
83-
// if (lowerKey.endsWith(".jpg") || lowerKey.endsWith(".jpeg"))
84-
// return "image/jpeg";
85-
// if (lowerKey.endsWith(".png"))
86-
// return "image/png";
87-
// if (lowerKey.endsWith(".gif"))
88-
// return "image/gif";
89-
// if (lowerKey.endsWith(".webp"))
90-
// return "image/webp";
91-
// if (lowerKey.endsWith(".svg"))
92-
// return "image/svg+xml";
93-
94-
// return "application/octet-stream"; // 모르는 확장자일 경우
95-
// }
96-
97-
/**
98-
* URL에서 파일명만 추출
99-
* 예: https://t1.kakaocdn.net/account_images/default_profile.jpeg →
100-
* default_profile.jpeg
101-
*/
102-
// private String extractFileNameFromUrl(String url) {
103-
// if (url == null)
104-
// return "unknown";
105-
// int lastSlash = url.lastIndexOf('/');
106-
// if (lastSlash == -1 || lastSlash == url.length() - 1)
107-
// return "unknown";
108-
// return url.substring(lastSlash + 1);
109-
// }
24+
private final S3Presigner s3Presigner;
25+
private final UserService userService;
26+
27+
@Value("${cloud.s3.bucket}")
28+
private String bucket;
29+
30+
@Value("${cloud.aws.region.static}")
31+
private String region;
32+
33+
/**
34+
* Presigned URL 발급 (파일 타입 제공)
35+
*/
36+
public PresignedUrlResponse generateUploadPresignedUrl(Long userId, String fileName, String fileType) {
37+
return createPresignedUrl(userId, fileName, fileType);
38+
}
39+
40+
/**
41+
* Presigned URL 발급 (파일 타입 미제공 시 자동 추론)
42+
*/
43+
public PresignedUrlResponse generateUploadPresignedUrlWithoutFileType(Long userId, String fileName) {
44+
String fileType = determineContentTypeFromKey(fileName);
45+
return createPresignedUrl(userId, fileName, fileType);
46+
}
47+
48+
/**
49+
* S3 객체 삭제
50+
*/
51+
public void deleteFile(Long userId, String fileName) {
52+
String key = buildS3Key(userService.getUserById(userId).nickname(), fileName);
53+
54+
try (S3Client s3 = S3Client.builder()
55+
.region(Region.of(region))
56+
.credentialsProvider(DefaultCredentialsProvider.builder().build())
57+
.build()) {
58+
59+
s3.deleteObject(DeleteObjectRequest.builder()
60+
.bucket(bucket)
61+
.key(key)
62+
.build());
63+
}
64+
}
65+
66+
/**
67+
* Presigned URL 생성 로직 (공통)
68+
*/
69+
private PresignedUrlResponse createPresignedUrl(Long userId, String fileName, String fileType) {
70+
UserResponse user = userService.getUserById(userId);
71+
String key = buildS3Key(user.nickname(), fileName);
72+
73+
PutObjectRequest putRequest = PutObjectRequest.builder()
74+
.bucket(bucket)
75+
.key(key)
76+
.contentType(fileType)
77+
.build();
78+
79+
PresignedPutObjectRequest presignedRequest = s3Presigner
80+
.presignPutObject(builder -> builder.putObjectRequest(putRequest)
81+
.signatureDuration(Duration.ofMinutes(10)));
82+
83+
return new PresignedUrlResponse(presignedRequest.url().toString(), key);
84+
}
85+
86+
/**
87+
* S3 키 생성: 닉네임/UUID-파일명
88+
*/
89+
private String buildS3Key(String nickname, String fileName) {
90+
return String.format("%s/%s-%s", nickname, UUID.randomUUID(), fileName);
91+
}
92+
93+
/**
94+
* 파일 확장자 기반 Content-Type 추론
95+
*/
96+
private String determineContentTypeFromKey(String key) {
97+
if (key == null)
98+
return "application/octet-stream";
99+
100+
String lowerKey = key.toLowerCase();
101+
if (lowerKey.endsWith(".jpg") || lowerKey.endsWith(".jpeg"))
102+
return "image/jpeg";
103+
if (lowerKey.endsWith(".png"))
104+
return "image/png";
105+
if (lowerKey.endsWith(".gif"))
106+
return "image/gif";
107+
if (lowerKey.endsWith(".webp"))
108+
return "image/webp";
109+
if (lowerKey.endsWith(".svg"))
110+
return "image/svg+xml";
111+
112+
return "application/octet-stream";
113+
}
110114
}

0 commit comments

Comments
 (0)