Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨기능 추가: Campaign -> campaignSendFlag 추가 #295

Merged
merged 11 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
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 @@ -26,28 +26,54 @@ public EmailService(StringRedisTemplate stringRedisTemplate, JavaMailSender mail

private final long VERIFICATION_CODE_TTL = 5; // 5분

// 인증 코드 발송 메소드
public void sendVerificationEmail(String email) {
log.info("start sending verification email");
log.info("Start sending verification email");
String verificationCode = generateVerificationCode();

SimpleMailMessage message = new SimpleMailMessage();
message.setTo(email);
message.setSubject("[LearnsMate] 이메일 인증 코드 안내");
message.setText("안녕하세요,\n\n"
String subject = "[LearnsMate] 이메일 인증 코드 안내";
String content = "안녕하세요,\n\n"
+ "LearnsMate를 이용해 주셔서 진심으로 감사드립니다.\n"
+ "아래의 인증 코드를 입력하여 이메일 인증을 완료해 주시기 바랍니다.\n\n"
+ "인증 코드: " + verificationCode + "\n\n"
+ "※ 인증 코드는 발송 후 5분간만 유효합니다.\n\n"
+ "본 이메일은 LearnsMate 서비스 이용과 관련하여 발송되었습니다. "
+ "궁금하신 사항이 있으시면 LearnsMate 고객 지원팀으로 언제든 문의해 주시기 바랍니다.\n\n"
+ "감사합니다.\n\n"
+ "LearnsMate 드림");

mailSender.send(message);
+ "LearnsMate 드림";

sendEmail(email, subject, content);
saveVerificationCode(email, verificationCode);
}

// 캠페인 이메일 발송 메소드 추가
public void sendCampaignEmail(String email, String campaignTitle, String campaignContents) {
log.info("Start sending campaign email to: " + email);

String subject = "[LearnsMate]: " + campaignTitle;
String content = campaignContents + "\n\n"
+ "더 자세한 사항은 LearnsMate 홈페이지를 방문해 주세요.\n\n"
+ "감사합니다.\n\n"
+ "LearnsMate 드림";

sendEmail(email, subject, content);
}

// 이메일 발송 공통 메소드
private void sendEmail(String to, String subject, String content) {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(subject);
message.setText(content);

try {
mailSender.send(message);
log.info("Email sent successfully to: " + to);
} catch (Exception e) {
log.error("Failed to send email to: " + to + ", error: " + e.getMessage());
}
}

//필기. 해당 이메일의 코드가 일치하는지 확인하는 코드
public boolean verifyCode(String email, String code) {
String savedCode = stringRedisTemplate.opsForValue().get(email); //필기. Redis에서 코드 가져오기
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class Campaign {
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm")
private LocalDateTime campaignSendDate;

@Column(name="campaign_send_flag" , nullable = true)
private Boolean campaignSendFlag;

@Column(name = "created_at")
@CreationTimestamp
Expand All @@ -47,4 +49,15 @@ public class Campaign {
@JoinColumn(name = "admin_code", nullable = false)
private Admin admin;

// 엔티티가 처음 저장되기 전에 실행되어 기본값을 설정해 줌
@PrePersist
public void prePersist() {
if (campaignSendFlag == null) {
campaignSendFlag = false; // 기본값 설정
}
}

public void updateSendFlag() {
this.campaignSendFlag = true;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package intbyte4.learnsmate.campaign.repository;

import intbyte4.learnsmate.campaign.domain.entity.Campaign;
import intbyte4.learnsmate.campaign.domain.entity.CampaignTypeEnum;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
Expand All @@ -13,5 +14,6 @@
@Primary
public interface CampaignRepository extends JpaRepository<Campaign, Long>, CampaignRepositoryCustom {

List<Campaign> findByCampaignSendDateLessThanEqual(LocalDateTime currentTime);
// campaign_type이 RESERVATION 이고 lessthan이고 flag가 false인 것들에 한해서
List<Campaign> findByCampaignSendDateLessThanEqualAndCampaignSendFlagFalseAndCampaignType(LocalDateTime currentTime, CampaignTypeEnum campaignTypeEnum);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ CampaignDTO editCampaign(CampaignDTO requestCampaign
(CampaignFilterDTO request, int page, int size);
List<FindAllCampaignsDTO> findCampaignListByConditionWithExcel(CampaignFilterDTO filterDTO);
List<FindAllCampaignsDTO> findAllCampaignListWithExcel();

void updateCampaignSendFlag(Long campaignCode);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import intbyte4.learnsmate.admin.domain.entity.Admin;
import intbyte4.learnsmate.admin.mapper.AdminMapper;
import intbyte4.learnsmate.admin.service.AdminService;
import intbyte4.learnsmate.admin.service.EmailService;
import intbyte4.learnsmate.campaign.batch.CampaignIssueCouponReader;
import intbyte4.learnsmate.campaign.domain.dto.*;
import intbyte4.learnsmate.campaign.domain.entity.Campaign;
Expand Down Expand Up @@ -55,6 +56,7 @@ public class CampaignServiceImpl implements CampaignService {
private final MemberService memberService;
private final CouponService couponService;
private final IssueCouponService issueCouponService;
private final EmailService emailService;
private final CampaignMapper campaignMapper;
private final AdminMapper adminMapper;
private final JobLauncher jobLauncher;
Expand Down Expand Up @@ -114,8 +116,11 @@ else if (foundCoupon.getTutorCode() != null) {
if (Objects.equals(requestCampaign.getCampaignType(), CampaignTypeEnum.INSTANT.getType())) {
// 즉시 발송
issueCouponService.issueCouponsToStudents(studentCodes, couponCodes);
requestStudentList.forEach(memberDTO -> {
emailService.sendCampaignEmail(memberDTO.getMemberEmail(), campaign.getCampaignTitle(), campaign.getCampaignContents());
});
} else {
// 예약 발송은 스케줄러에 등록 아직
// 예약 발송은 스케줄러에 등록
registerScheduledCampaign(requestStudentList, requestCouponList, savedCampaignDTO.getCampaignSendDate());
}

Expand Down Expand Up @@ -149,7 +154,8 @@ public void registerScheduledCampaign(List<MemberDTO> studentList, List<CouponDT
@Transactional
public List<CampaignDTO> getReadyCampaigns(LocalDateTime currentTime) {
// 예약 시간이 현재 시간보다 이전이면서 아직 발송되지 않은 캠페인 조회
List<Campaign> readyCampaigns = campaignRepository.findByCampaignSendDateLessThanEqual(currentTime);
List<Campaign> readyCampaigns = campaignRepository
.findByCampaignSendDateLessThanEqualAndCampaignSendFlagFalseAndCampaignType(currentTime, CampaignTypeEnum.RESERVATION);
return readyCampaigns.stream()
.map(campaignMapper::toDTO)
.toList();
Expand All @@ -169,9 +175,9 @@ public CampaignDTO editCampaign(CampaignDTO requestCampaign

AdminDTO adminDTO = adminService.findByAdminCode(requestCampaign.getAdminCode());
Admin admin = adminMapper.toEntity(adminDTO);
log.info("서비스에서 조회하는 adminDTO: {}", adminDTO);

Campaign updatedCampaign = campaignMapper.toEntity(requestCampaign, admin);
log.info("서비스에서 조회하는 toEntity(requestCampaign,admin): {}", updatedCampaign);

campaignRepository.save(updatedCampaign);
editStudent(requestCampaign, requestStudentList, updatedCampaign);

Expand Down Expand Up @@ -209,9 +215,7 @@ private void editCoupon(CampaignDTO requestCampaign
private void editStudent(CampaignDTO requestCampaign
, List<MemberDTO> requestStudentList
, Campaign updatedCampaign) {
log.info("editStuden메서드의 requestCampaign: {}", requestCampaign);
log.info("editStuden메서드의 requestStudentList: {}", requestStudentList);
log.info("editStuden메서드의 updatedCampaign: {}", updatedCampaign);

List<UserPerCampaignDTO> existingStudentList = userPerCampaignService
.findByCampaignCode(updatedCampaign);

Expand Down Expand Up @@ -329,4 +333,15 @@ public List<FindAllCampaignsDTO> findAllCampaignListWithExcel() {

return findAllCampaignsDTOList;
}

@Override
public void updateCampaignSendFlag(Long campaignCode) {
Campaign campaign = campaignRepository.findById(campaignCode)
.orElseThrow(() -> new CommonException(StatusEnum.CAMPAIGN_NOT_FOUND));

campaign.updateSendFlag();

campaignRepository.save(campaign);
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package intbyte4.learnsmate.common.config;

import intbyte4.learnsmate.admin.service.EmailService;
import intbyte4.learnsmate.campaign.domain.dto.CampaignDTO;
import intbyte4.learnsmate.campaign.service.CampaignService;
import intbyte4.learnsmate.member.domain.MemberType;
import intbyte4.learnsmate.member.domain.dto.MemberDTO;
import intbyte4.learnsmate.member.service.MemberService;
import intbyte4.learnsmate.userpercampaign.domain.dto.UserPerCampaignDTO;
import intbyte4.learnsmate.userpercampaign.service.UserPerCampaignService;
import intbyte4.learnsmate.voc.service.VOCAiService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
Expand All @@ -17,18 +24,25 @@

@Configuration
@EnableScheduling
@Slf4j
public class SchedulerConfig {

private final VOCAiService vocAiService;
private final CampaignService campaignService;
private final JobLauncher jobLauncher;
private final Job campaignJob;
private final MemberService memberService;
private final EmailService emailService;
private final UserPerCampaignService userPerCampaignService;

public SchedulerConfig(VOCAiService vocAiService, CampaignService campaignService, JobLauncher jobLauncher, Job campaignJob) {
public SchedulerConfig(VOCAiService vocAiService, CampaignService campaignService, JobLauncher jobLauncher, Job campaignJob, MemberService memberService, EmailService emailService , UserPerCampaignService userPerCampaignService) {
this.vocAiService = vocAiService;
this.campaignService = campaignService;
this.jobLauncher = jobLauncher;
this.campaignJob = campaignJob;
this.memberService = memberService;
this.emailService = emailService;
this.userPerCampaignService = userPerCampaignService;
}

@Scheduled(cron = "0 0 9 * * MON")
Expand All @@ -46,6 +60,15 @@ public void scheduleCampaigns() {
.addDate("startTime", new Date())
.toJobParameters();
jobLauncher.run(campaignJob, jobParameters);

List<UserPerCampaignDTO> userPerCampaignDTOList = userPerCampaignService.findUserByCampaignCode(campaign.getCampaignCode());
for (UserPerCampaignDTO userPerCampaignDTO : userPerCampaignDTOList) {
MemberDTO member = memberService.findMemberByMemberCode(userPerCampaignDTO.getStudentCode(), MemberType.STUDENT);
if (member != null) {
emailService.sendCampaignEmail(member.getMemberEmail(), campaign.getCampaignTitle(), campaign.getCampaignContents());
}
}
campaignService.updateCampaignSendFlag(campaign.getCampaignCode());
} catch (Exception e) {
System.err.println("Failed to launch campaign job: " + e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package intbyte4.learnsmate.userpercampaign.repository;

import intbyte4.learnsmate.campaign.domain.entity.Campaign;
import intbyte4.learnsmate.userpercampaign.domain.dto.UserPerCampaignDTO;
import intbyte4.learnsmate.userpercampaign.domain.entity.UserPerCampaign;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
Expand All @@ -12,4 +15,8 @@ public interface UserPerCampaignRepository extends JpaRepository<UserPerCampaign
List<UserPerCampaign> findByCampaign(Campaign campaign);

void deleteByCampaign_CampaignCode(Long campaignCode);

@Query("SELECT new intbyte4.learnsmate.userpercampaign.domain.dto.UserPerCampaignDTO(u.userPerCampaignCode, u.campaign.campaignCode, u.student.memberCode) " +
"FROM userPerCampaign u WHERE u.campaign.campaignCode = :campaignCode")
List<UserPerCampaignDTO> findStudentsByCampaignCode(@Param("campaignCode") Long campaignCode);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ public interface UserPerCampaignService {
List<UserPerCampaignDTO> findByCampaignCode(Campaign campaign);
void removeUserPerCampaign(Long userPerCampaignCode);
void removeByCampaignCode(Long campaignCode);
List<UserPerCampaignDTO> findUserByCampaignCode(Long campaignCode);
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,9 @@ public void removeUserPerCampaign(Long userPerCampaignCode) {
public void removeByCampaignCode(Long campaignCode) {
userPerCampaignRepository.deleteByCampaign_CampaignCode(campaignCode);
}

@Override
public List<UserPerCampaignDTO> findUserByCampaignCode(Long campaignCode) {
return userPerCampaignRepository.findStudentsByCampaignCode(campaignCode);
}
}