Skip to content

Commit aafa9f7

Browse files
committed
fix : aws sdk를 사용하도록 수정
1 parent ed1aafe commit aafa9f7

1 file changed

Lines changed: 57 additions & 135 deletions

File tree

  • casper-application-infrastructure/src/main/kotlin/hs/kr/entrydsm/application/global/pdf/data

casper-application-infrastructure/src/main/kotlin/hs/kr/entrydsm/application/global/pdf/data/PdfDataConverter.kt

Lines changed: 57 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,28 @@
11
package hs.kr.entrydsm.application.global.pdf.data
22

3+
import com.amazonaws.services.s3.AmazonS3
4+
import com.amazonaws.services.s3.model.GetObjectRequest
5+
import hs.kr.entrydsm.application.global.storage.AwsProperties
36
import hs.kr.entrydsm.domain.application.aggregates.Application
47
import hs.kr.entrydsm.domain.application.values.ApplicationType
58
import hs.kr.entrydsm.domain.application.values.EducationalStatus
69
import hs.kr.entrydsm.domain.application.values.Gender
710
import hs.kr.entrydsm.domain.school.interfaces.QuerySchoolContract
11+
import org.slf4j.LoggerFactory
812
import org.springframework.stereotype.Component
913
import java.net.URL
1014
import java.time.LocalDate
1115
import java.util.Base64
1216

13-
/**
14-
* 지원서 정보를 PDF 템플릿용 데이터로 변환하는 Converter입니다.
15-
*
16-
* Application, Score 등의 도메인 객체를 HTML 템플릿에서 사용할 수 있는
17-
* Key-Value 형태의 데이터로 변환합니다. 누락된 도메인 정보는 더미값으로 처리하며
18-
* 향후 도메인이 추가되면 TODO 주석을 따라 연동할 수 있습니다.
19-
*/
2017
@Component
2118
class PdfDataConverter(
2219
private val querySchoolContract: QuerySchoolContract,
20+
private val amazonS3: AmazonS3,
21+
private val awsProperties: AwsProperties,
2322
) {
24-
/**
25-
* 지원서 정보를 PDF 템플릿용 데이터로 변환합니다.
26-
*
27-
* @param application 지원서 정보
28-
* @return 템플릿에 사용할 PdfData 객체
29-
*/
23+
24+
private val log by lazy { LoggerFactory.getLogger(this::class.java) }
25+
3026
fun applicationToInfo(application: Application): PdfData {
3127
val values: MutableMap<String, Any> = HashMap()
3228
setReceiptCode(application, values)
@@ -45,43 +41,48 @@ class PdfDataConverter(
4541
setAttendanceAndVolunteer(application, values)
4642
setExtraScore(application, values)
4743
setTeacherInfo(application, values)
48-
setBase64Image(application, values)
44+
setBase64Image(application, values) // ⭐️ 수정된 메서드가 호출됩니다.
4945

5046
return PdfData(values)
5147
}
5248

53-
// ... (이하 다른 메서드들은 이전과 동일)
49+
private fun setBase64Image(
50+
application: Application,
51+
values: MutableMap<String, Any>,
52+
) {
53+
val photoPath = application.photoPath
54+
if (photoPath.isNullOrBlank()) {
55+
values["base64Image"] = ""
56+
return
57+
}
58+
59+
try {
60+
val objectKey = URL(photoPath).path.substring(1)
61+
62+
val s3Object = amazonS3.getObject(GetObjectRequest(awsProperties.bucket, objectKey))
63+
val imageBytes = s3Object.objectContent.readAllBytes()
64+
65+
values["base64Image"] = Base64.getEncoder().encodeToString(imageBytes)
66+
log.info("Successfully fetched and encoded image from S3: {}", objectKey)
67+
68+
} catch (e: Exception) {
69+
log.error("Failed to get image from S3. path: {}, error: {}", photoPath, e.message)
70+
values["base64Image"] = ""
71+
}
72+
}
5473

55-
/**
56-
* 지원서의 접수번호를 설정합니다.
57-
*
58-
* @param application 지원서 정보
59-
* @param values 템플릿 데이터 맵
60-
*/
6174
private fun setReceiptCode(
6275
application: Application,
6376
values: MutableMap<String, Any>,
6477
) {
6578
values["receiptCode"] = application.receiptCode.toString()
6679
}
6780

68-
/**
69-
* 입학년도를 설정합니다. (현재 년도 + 1)
70-
*
71-
* @param values 템플릿 데이터 맵
72-
*/
7381
private fun setEntranceYear(values: MutableMap<String, Any>) {
7482
val entranceYear: Int = LocalDate.now().plusYears(1).year
7583
values["entranceYear"] = entranceYear.toString()
7684
}
7785

78-
/**
79-
* 지원자의 개인정보(이름, 성별, 주소, 생년월일 등)를 설정합니다.
80-
* 일부 정보는 도메인에 없어서 더미값을 사용합니다.
81-
*
82-
* @param application 지원서 정보
83-
* @param values 템플릿 데이터 맵
84-
*/
8586
private fun setPersonalInfo(
8687
application: Application,
8788
values: MutableMap<String, Any>,
@@ -100,7 +101,6 @@ class PdfDataConverter(
100101
values["region"] = if (application.isDaejeon == true) "대전" else "비대전"
101102
values["applicationType"] = application.applicationType.displayName
102103

103-
// 특기사항: 국가유공자자녀 또는 특례입학대상
104104
val remarks = mutableListOf<String>()
105105
if (application.nationalMeritChild == true) {
106106
remarks.add("국가유공자자녀")
@@ -111,18 +111,10 @@ class PdfDataConverter(
111111
values["applicationRemark"] = if (remarks.isEmpty()) "해당없음" else remarks.joinToString(", ")
112112
}
113113

114-
/**
115-
* 출석 및 봉사활동 정보를 설정합니다.
116-
* 현재 관련 도메인이 없어서 더미값을 사용합니다.
117-
*
118-
* @param application 지원서 정보
119-
* @param values 템플릿 데이터 맵
120-
*/
121114
private fun setAttendanceAndVolunteer(
122115
application: Application,
123116
values: MutableMap<String, Any>,
124117
) {
125-
// 실제 출석/봉사활동 데이터 사용
126118
values["absenceDayCount"] = application.absence ?: 0
127119
values["latenessCount"] = application.tardiness ?: 0
128120
values["earlyLeaveCount"] = application.earlyLeave ?: 0
@@ -152,7 +144,7 @@ class PdfDataConverter(
152144
values.putAll(emptyGraduationClassification())
153145

154146
val currentYear = LocalDate.now().year
155-
val graduationMonth = if (LocalDate.now().monthValue <= 2) 2 else 8 // 2월/8월 졸업
147+
val graduationMonth = if (LocalDate.now().monthValue <= 2) 2 else 8
156148

157149
when (application.educationalStatus) {
158150
EducationalStatus.GRADUATE -> {
@@ -198,7 +190,7 @@ class PdfDataConverter(
198190
"isProspectiveGraduate" to isProspectiveGraduate,
199191
"isDaejeon" to isDaejeon,
200192
"isNotDaejeon" to !isDaejeon,
201-
"isBasicLiving" to isSocial, // 사회통합전형인 경우 사회적배려 대상자로 추정
193+
"isBasicLiving" to isSocial,
202194
"isCommon" to isCommon,
203195
"isMeister" to (application.applicationType == ApplicationType.MEISTER),
204196
"isSocialMerit" to isSocial,
@@ -213,7 +205,6 @@ class PdfDataConverter(
213205
application: Application,
214206
values: MutableMap<String, Any>,
215207
) {
216-
// 실제 가산점 데이터 사용
217208
values["hasCompetitionPrize"] = toCircleBallotbox(application.algorithmAward ?: false)
218209
values["hasCertificate"] = toCircleBallotbox(application.infoProcessingCert ?: false)
219210
}
@@ -247,14 +238,12 @@ class PdfDataConverter(
247238
application: Application,
248239
values: MutableMap<String, Any>,
249240
) {
250-
// 실제 성적 데이터 사용
251241
val subjects = listOf("korean", "social", "history", "math", "science", "english", "techAndHome")
252242

253243
subjects.forEach { subjectPrefix ->
254244
with(values) {
255245
put("applicationCase", "기술∙가정")
256246

257-
// 졸업자인 경우 3-2학기 성적 포함
258247
if (application.educationalStatus == EducationalStatus.GRADUATE) {
259248
put("${subjectPrefix}ThirdGradeSecondSemester", getGradeDisplay(getSubjectScore(application, subjectPrefix, "3_2")))
260249
}
@@ -378,65 +367,6 @@ class PdfDataConverter(
378367
values["parentRelation"] = application.parentRelation ?: ""
379368
}
380369

381-
private fun setRecommendations(
382-
application: Application,
383-
values: MutableMap<String, Any>,
384-
) {
385-
val isDaejeon = application.isDaejeon ?: false
386-
val isMeister = application.applicationType == ApplicationType.MEISTER
387-
val isSocialMerit = application.applicationType == ApplicationType.SOCIAL
388-
389-
values["isDaejeonAndMeister"] = markIfTrue(isDaejeon && isMeister)
390-
values["isDaejeonAndSocialMerit"] = markIfTrue(isDaejeon && isSocialMerit)
391-
values["isNotDaejeonAndMeister"] = markIfTrue(!isDaejeon && isMeister)
392-
values["isNotDaejeonAndSocialMerit"] = markIfTrue(!isDaejeon && isSocialMerit)
393-
}
394-
395-
private fun setBase64Image(
396-
application: Application,
397-
values: MutableMap<String, Any>,
398-
) {
399-
val photoPath = application.photoPath
400-
if (photoPath.isNullOrBlank()) {
401-
values["base64Image"] = ""
402-
return
403-
}
404-
405-
try {
406-
val imageUrl = URL(photoPath)
407-
val imageBytes = imageUrl.readBytes()
408-
values["base64Image"] = Base64.getEncoder().encodeToString(imageBytes)
409-
} catch (e: Exception) {
410-
// URL이 잘못되었거나, 네트워크 문제 등으로 이미지를 가져올 수 없는 경우 빈 문자열로 처리
411-
values["base64Image"] = ""
412-
}
413-
}
414-
415-
private fun markIfTrue(isTrue: Boolean): String {
416-
return if (isTrue) "" else ""
417-
}
418-
419-
private fun emptySchoolInfo(): Map<String, Any> {
420-
return mapOf(
421-
"schoolCode" to "",
422-
"schoolRegion" to "",
423-
"schoolClass" to "",
424-
"schoolTel" to "",
425-
"schoolName" to "",
426-
)
427-
}
428-
429-
private fun emptyGraduationClassification(): Map<String, Any> {
430-
return mapOf(
431-
"qualificationExamPassedYear" to "20__",
432-
"qualificationExamPassedMonth" to "__",
433-
"graduateYear" to "20__",
434-
"graduateMonth" to "__",
435-
"prospectiveGraduateYear" to "20__",
436-
"prospectiveGraduateMonth" to "__",
437-
)
438-
}
439-
440370
private fun setSchoolInfo(
441371
application: Application,
442372
values: MutableMap<String, Any>,
@@ -452,20 +382,13 @@ class PdfDataConverter(
452382
values["schoolTel"] = toFormattedPhoneNumber(school.tel ?: "")
453383
values["schoolName"] = school.name
454384
values["schoolClass"] = application.studentId?.let {
455-
// studentId에서 학급 정보 추출 시도 (예: "30101" -> "1")
456385
if (it.length >= 2) it.substring(1, 2) else "3"
457386
} ?: "3"
458387
} else {
459388
values.putAll(emptySchoolInfo())
460389
}
461390
}
462391

463-
/**
464-
* 전화번호를 하이픈 포함 형태로 포맷팅합니다.
465-
*
466-
* @param phoneNumber 포맷팅할 전화번호
467-
* @return 하이픈으로 구분된 전화번호 문자열
468-
*/
469392
private fun toFormattedPhoneNumber(phoneNumber: String?): String {
470393
if (phoneNumber.isNullOrBlank()) {
471394
return ""
@@ -476,33 +399,32 @@ class PdfDataConverter(
476399
return phoneNumber.replace("(\\d{2,3})(\\d{3,4})(\\d{4})".toRegex(), "$1-$2-$3")
477400
}
478401

479-
/**
480-
* null 값을 빈 문자열로 변환합니다.
481-
*
482-
* @param input 변환할 문자열
483-
* @return 입력값이 null이면 빈 문자열, 그렇지 않으면 원래 값
484-
*/
485-
private fun setBlankIfNull(input: String?): String {
486-
return input ?: ""
487-
}
488-
489-
/**
490-
* boolean 값을 체크박스 문자(☑/☐)로 변환합니다.
491-
*
492-
* @param isTrue 변환할 boolean 값
493-
* @return true이면 "☑", false이면 "☐"
494-
*/
495402
private fun toBallotBox(isTrue: Boolean): String {
496403
return if (isTrue) "" else ""
497404
}
498405

499-
/**
500-
* boolean 값을 O/X 문자로 변환합니다.
501-
*
502-
* @param isTrue 변환할 boolean 값
503-
* @return true이면 "O", false이면 "X"
504-
*/
505406
private fun toCircleBallotbox(isTrue: Boolean): String {
506407
return if (isTrue) "O" else "X"
507408
}
409+
410+
private fun emptySchoolInfo(): Map<String, Any> {
411+
return mapOf(
412+
"schoolCode" to "",
413+
"schoolRegion" to "",
414+
"schoolClass" to "",
415+
"schoolTel" to "",
416+
"schoolName" to "",
417+
)
418+
}
419+
420+
private fun emptyGraduationClassification(): Map<String, Any> {
421+
return mapOf(
422+
"qualificationExamPassedYear" to "20__",
423+
"qualificationExamPassedMonth" to "__",
424+
"graduateYear" to "20__",
425+
"graduateMonth" to "__",
426+
"prospectiveGraduateYear" to "20__",
427+
"prospectiveGraduateMonth" to "__",
428+
)
429+
}
508430
}

0 commit comments

Comments
 (0)