Skip to content

Commit a1cab45

Browse files
authored
feat: 메일 발송 기능 구현 (#49)
* feat: google API 기능 추가 * feat: google API 기능 추가 * feat: 메일 발송 기능 구현 * fix: 이메일 전송 관련 ErrorCode 수정 * feat: 서류 지원결과와 최종 합격 결과 API 나누기 * fix: 서류 지원결과와 최종 합격 결과 API 하나의 메소드에서 지원되게 수정 MailType 열거형 추가 * fix: ApplicantServiceImpl의 sendEmailsToApplicants 메소드 ApplicantStatus 수정 완료 * test: ApplicantServiceImpl의 sendEmailsToApplicants 메소드 테스트 케이스 작성 및 EmailServiceTest 작성 * fix: EmailServiceTest에 들어가는 from의 value가 외부 환경변수를 인식하지 못하는 문제 발생 추후 테스트용 환경변수 파일 작성 예정 * feat: EmailServiceTest 추가 * feat: 발송 이메일 템플릿 추가 * fix: 발송 이메일 템플릿 수정
1 parent 6c6e3f9 commit a1cab45

File tree

5 files changed

+130
-55
lines changed

5 files changed

+130
-55
lines changed

src/main/java/dmu/dasom/api/domain/email/service/EmailService.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,36 @@ public void sendEmail(String to, String name, MailType mailType) throws Messagin
2828
}
2929
// 메일 제목 및 템플릿 설정
3030
String subject;
31-
String templateName = switch (mailType) {
31+
String emailContent;
32+
String buttonUrl = "#";
33+
String buttonText;
34+
switch (mailType) {
3235
case DOCUMENT_RESULT -> {
33-
subject = "서류 합격 안내";
34-
yield "document-pass-template";
36+
subject = "동양미래대학교 컴퓨터소프트웨어공학과 전공 동아리 DASOM 서류 결과 안내";
37+
emailContent = "먼저 다솜 34기에 많은 관심을 갖고 지원해 주셔서 감사드리며,<br>" +
38+
"내부 서류 평가 결과 및 추후 일정에 관해 안내드리고자 이메일을 발송하게 되었습니다.<br>" +
39+
"모집 폼 합/불합 결과는 아래 버튼 혹은 홈페이지를 통해 확인이 가능합니다.";
40+
buttonText = "서류 결과 확인하기";
3541
}
3642
case FINAL_RESULT -> {
37-
subject = "최종 합격 안내";
38-
yield "final-pass-template";
43+
subject = "동양미래대학교 컴퓨터소프트웨어공학과 전공 동아리 DASOM 최종 합격 안내";
44+
emailContent = "먼저 다솜 34기에 많은 관심을 갖고 지원해 주셔서 감사드리며,<br>" +
45+
"최종 면접 결과 및 추후 일정에 관해 안내드리고자 이메일을 발송하게 되었습니다.<br>" +
46+
"모집 폼 합/불합 결과는 아래 버튼 혹은 홈페이지를 통해 확인이 가능합니다.";
47+
buttonText = "최종 결과 확인하기";
3948
}
4049
default -> throw new IllegalStateException("Unexpected value: " + mailType);
41-
};
50+
}
4251

4352
// HTML 템플릿에 전달할 데이터 설정
4453
Context context = new Context();
4554
context.setVariable("name", name); // 지원자 이름 전달
55+
context.setVariable("emailContent", emailContent); // 이메일 내용 전달
56+
context.setVariable("buttonUrl", buttonUrl); // 버튼 링크 전달
57+
context.setVariable("buttonText", buttonText);
4658

4759
// HTML 템플릿 처리
48-
String htmlBody = templateEngine.process(templateName, context);
60+
String htmlBody = templateEngine.process("email-template", context);
4961

5062
// 이메일 생성 및 전송
5163
MimeMessage message = javaMailSender.createMimeMessage();

src/main/java/dmu/dasom/api/global/admin/controller/AdminController.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import dmu.dasom.api.domain.recruit.service.RecruitService;
99
import dmu.dasom.api.domain.email.enums.MailType;
1010
import dmu.dasom.api.global.dto.PageResponse;
11+
1112
import io.swagger.v3.oas.annotations.Operation;
1213
import io.swagger.v3.oas.annotations.Parameter;
1314
import io.swagger.v3.oas.annotations.media.Content;

src/main/resources/template/email-template.html

Lines changed: 108 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,76 +3,138 @@
33
<head>
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>지원 결과 확인</title>
6+
<title>이메일 안내</title>
7+
<link rel="stylesheet" as="style" crossorigin href="https://cdn.jsdelivr.net/gh/orioncactus/[email protected]/dist/web/static/pretendard.css" />
78
<style>
89
body {
9-
font-family: Arial, sans-serif;
10-
background-color: #1a1a1a;
11-
color: #ffffff;
10+
background-color: #17171B;
11+
color: white;
12+
font-family: 'Pretendard', sans-serif;
13+
display: flex;
14+
justify-content: center;
15+
align-items: center;
16+
height: 100vh;
1217
margin: 0;
13-
padding: 0;
1418
}
15-
.container {
16-
max-width: 600px;
17-
margin: 0 auto;
18-
padding: 20px;
19-
background-color: #1a1a1a;
20-
border-radius: 8px;
21-
text-align: center;
19+
20+
.email-container {
21+
width: 740px;
22+
height: 680px;
23+
background: #17171B;
24+
padding: 30px;
25+
position: relative;
2226
}
23-
.header {
24-
font-size: 24px;
25-
font-weight: bold;
26-
color: #00B493;
27+
28+
.logo {
29+
display: flex;
30+
justify-content: center;
31+
position: relative;
2732
margin-bottom: 20px;
2833
}
29-
.sub-header {
30-
font-size: 16px;
31-
background-color: #00B493;
32-
padding: 10px;
33-
border-radius: 5px;
34-
margin-bottom: 20px;
34+
35+
.logo img {
36+
width: 21px;
37+
height: 24px;
38+
border-radius: 3px;
3539
}
36-
.content {
37-
font-size: 14px;
38-
line-height: 1.8;
40+
41+
.divider {
42+
width: 100%;
43+
display: flex;
44+
justify-content: space-between;
45+
align-items: center;
3946
}
40-
.content p {
41-
margin-bottom: 10px;
47+
48+
.divider .line {
49+
flex: 1;
50+
border-top: 1px solid #00B493;
51+
margin: 0 10px;
4252
}
43-
.highlight {
53+
54+
.title {
55+
font-size: 48px;
56+
font-weight: 900;
4457
color: #00B493;
58+
margin-bottom: 30px;
59+
}
60+
61+
.greeting {
62+
font-size: 20px;
63+
font-weight: 600;
64+
margin-bottom: 40px;
65+
}
66+
67+
.content {
68+
font-size: 16px;
69+
font-weight: 400;
70+
line-height: 2.5;
71+
text-align: right;
72+
margin-bottom: 40px;
4573
}
74+
75+
.contact {
76+
font-size: 16px;
77+
font-weight: 400;
78+
line-height: 1.5;
79+
}
80+
81+
.button-container {
82+
display: flex;
83+
justify-content: flex-end;
84+
margin-bottom: 40px;
85+
}
86+
4687
.button {
47-
display: inline-block;
48-
background-color: #00B493;
49-
color: #ffffff;
50-
padding: 12px 24px;
88+
background: #00B493;
89+
color: white;
90+
font-size: 16px;
91+
font-weight: 400;
92+
padding: 10px 20px;
5193
border-radius: 5px;
94+
display: flex;
95+
align-items: center;
5296
text-decoration: none;
53-
font-size: 16px;
5497
}
98+
5599
.button:hover {
56-
background-color: #00B493;
100+
background: #00987A;
101+
}
102+
103+
.button .arrow {
104+
border: solid white;
105+
border-width: 0 2px 2px 0;
106+
display: inline-block;
107+
padding: 5px;
108+
transform: rotate(-45deg);
109+
margin-left: 10px;
57110
}
58111
</style>
59112
</head>
60113
<body>
61-
<div class="container">
62-
<!-- Header Section -->
63-
<div class="header">DASOM</div>
114+
<div class="email-container">
115+
<div class="logo">
116+
<div class="divider">
117+
<div class="line"></div>
118+
<img src="logo.png" alt="로고">
119+
<div class="line"></div>
120+
</div>
121+
</div>
64122

65-
<!-- Sub-header Section -->
66-
<div class="sub-header">컴퓨터소프트웨어공학과 전공동아리 다솜<br>34기 서류 합격자 조회</div>
123+
<div class="title">DASOM</div>
124+
<div class="greeting" th:text="${name} + '님 안녕하세요.'"></div>
125+
<div>컴퓨터공학부 전공동아리 다솜입니다.</div>
67126

68-
<!-- Content Section -->
69-
<div class="content">
70-
<p>안녕하세요, <span class="highlight" th:text="${name}"></span>님.</p>
71-
<p>학번 마지막 <span class="highlight">4자리</span> + 전화번호 마지막 <span class="highlight">4자리</span>를 입력하여<br>지원 결과를 확인할 수 있습니다.</p>
72-
<p>예시) <span class="highlight">08470542</span></p>
127+
<div class="content" th:utext="${emailContent}"></div>
128+
129+
<div class="button-container">
130+
<a th:href="${buttonUrl}" class="button">
131+
<span th:text="${buttonText}"></span> <span class="arrow"></span>
132+
</a>
133+
</div>
73134

74-
<!-- Button -->
75-
<a href="https://example.com/result" class="button">결과 확인하기</a>
135+
<div class="contact">
136+
또한, 문의 사항은 본 메일에 회신 또는 아래 번호로 편하게 연락 부탁드립니다.<br>
137+
010-6361-3481
76138
</div>
77139
</div>
78140
</body>
5.61 KB
Loading

src/test/java/dmu/dasom/api/domain/email/EmailServiceTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void sendEmail_documentResult() throws MessagingException {
5252
String name = "지원자";
5353
MailType mailType = MailType.DOCUMENT_RESULT;
5454

55-
String expectedTemplate = "document-pass-template";
55+
String expectedTemplate = "email-template";
5656
String expectedHtmlBody = "<html><body>Document Pass</body></html>";
5757
when(templateEngine.process(eq(expectedTemplate), any(Context.class))).thenReturn(expectedHtmlBody);
5858

@@ -76,7 +76,7 @@ void sendEmail_finalResult() throws MessagingException {
7676
String name = "지원자";
7777
MailType mailType = MailType.FINAL_RESULT;
7878

79-
String expectedTemplate = "final-pass-template";
79+
String expectedTemplate = "email-template";
8080
String expectedHtmlBody = "<html><body>Final Pass</body></html>";
8181
when(templateEngine.process(eq(expectedTemplate), any(Context.class))).thenReturn(expectedHtmlBody);
8282

0 commit comments

Comments
 (0)