package com.iailab.module.system.service.mail; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.mail.MailAccount; import cn.hutool.extra.mail.MailUtil; import com.iailab.framework.common.enums.CommonStatusEnum; import com.iailab.framework.common.enums.UserTypeEnum; import com.iailab.module.system.dal.dataobject.mail.MailAccountDO; import com.iailab.module.system.dal.dataobject.mail.MailTemplateDO; import com.iailab.module.system.dal.dataobject.user.AdminUserDO; import com.iailab.module.system.mq.message.mail.MailSendMessage; import com.iailab.module.system.mq.producer.mail.MailProducer; import com.iailab.module.system.service.member.MemberService; import com.iailab.module.system.service.user.AdminUserService; import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.Map; import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.iailab.module.system.enums.ErrorCodeConstants.*; /** * 邮箱å‘é€ Service 实现类 * * @author wangjingyi * @since 2022-03-21 */ @Service @Validated @Slf4j public class MailSendServiceImpl implements MailSendService { @Resource private AdminUserService adminUserService; @Resource private MemberService memberService; @Resource private MailAccountService mailAccountService; @Resource private MailTemplateService mailTemplateService; @Resource private MailLogService mailLogService; @Resource private MailProducer mailProducer; @Override public Long sendSingleMailToAdmin(String mail, Long userId, String templateCode, Map<String, Object> templateParams) { // 如果 mail ä¸ºç©ºï¼Œåˆ™åŠ è½½ç”¨æˆ·ç¼–å·å¯¹åº”的邮箱 if (StrUtil.isEmpty(mail)) { AdminUserDO user = adminUserService.getUser(userId); if (user != null) { mail = user.getEmail(); } } // 执行å‘é€ return sendSingleMail(mail, userId, UserTypeEnum.ADMIN.getValue(), templateCode, templateParams); } @Override public Long sendSingleMailToMember(String mail, Long userId, String templateCode, Map<String, Object> templateParams) { // 如果 mail ä¸ºç©ºï¼Œåˆ™åŠ è½½ç”¨æˆ·ç¼–å·å¯¹åº”的邮箱 if (StrUtil.isEmpty(mail)) { mail = memberService.getMemberUserEmail(userId); } // 执行å‘é€ return sendSingleMail(mail, userId, UserTypeEnum.MEMBER.getValue(), templateCode, templateParams); } @Override public Long sendSingleMail(String mail, Long userId, Integer userType, String templateCode, Map<String, Object> templateParams) { // æ ¡éªŒé‚®ç®±æ¨¡ç‰ˆæ˜¯å¦åˆæ³• MailTemplateDO template = validateMailTemplate(templateCode); // æ ¡éªŒé‚®ç®±è´¦å·æ˜¯å¦åˆæ³• MailAccountDO account = validateMailAccount(template.getAccountId()); // æ ¡éªŒé‚®ç®±æ˜¯å¦å˜åœ¨ mail = validateMail(mail); validateTemplateParams(template, templateParams); // 创建å‘é€æ—¥å¿—。如果模æ¿è¢«ç¦ç”¨ï¼Œåˆ™ä¸å‘é€çŸä¿¡ï¼Œåªè®°å½•æ—¥å¿— Boolean isSend = CommonStatusEnum.ENABLE.getStatus().equals(template.getStatus()); String title = mailTemplateService.formatMailTemplateContent(template.getTitle(), templateParams); String content = mailTemplateService.formatMailTemplateContent(template.getContent(), templateParams); Long sendLogId = mailLogService.createMailLog(userId, userType, mail, account, template, content, templateParams, isSend); // å‘é€ MQ 消æ¯ï¼Œå¼‚æ¥æ‰§è¡Œå‘é€çŸä¿¡ if (isSend) { mailProducer.sendMailSendMessage(sendLogId, mail, account.getId(), template.getNickname(), title, content); } return sendLogId; } @Override public void doSendMail(MailSendMessage message) { // 1. 创建å‘é€è´¦å· MailAccountDO account = validateMailAccount(message.getAccountId()); MailAccount mailAccount = buildMailAccount(account, message.getNickname()); // 2. å‘é€é‚®ä»¶ try { String messageId = MailUtil.send(mailAccount, message.getMail(), message.getTitle(), message.getContent(), true); // 3. 更新结果(æˆåŠŸï¼‰ mailLogService.updateMailSendResult(message.getLogId(), messageId, null); } catch (Exception e) { // 3. 更新结果(异常) mailLogService.updateMailSendResult(message.getLogId(), null, e); } } private MailAccount buildMailAccount(MailAccountDO account, String nickname) { String from = StrUtil.isNotEmpty(nickname) ? nickname + " <" + account.getMail() + ">" : account.getMail(); return new MailAccount().setFrom(from).setAuth(true) .setUser(account.getUsername()).setPass(account.getPassword()) .setHost(account.getHost()).setPort(account.getPort()) .setSslEnable(account.getSslEnable()).setStarttlsEnable(account.getStarttlsEnable()); } @VisibleForTesting MailTemplateDO validateMailTemplate(String templateCode) { // 获得邮件模æ¿ã€‚考虑到效率,从缓å˜ä¸èŽ·å– MailTemplateDO template = mailTemplateService.getMailTemplateByCodeFromCache(templateCode); // 邮件模æ¿ä¸å˜åœ¨ if (template == null) { throw exception(MAIL_TEMPLATE_NOT_EXISTS); } return template; } @VisibleForTesting MailAccountDO validateMailAccount(Long accountId) { // 获得邮箱账å·ã€‚考虑到效率,从缓å˜ä¸èŽ·å– MailAccountDO account = mailAccountService.getMailAccountFromCache(accountId); // 邮箱账å·ä¸å˜åœ¨ if (account == null) { throw exception(MAIL_ACCOUNT_NOT_EXISTS); } return account; } @VisibleForTesting String validateMail(String mail) { if (StrUtil.isEmpty(mail)) { throw exception(MAIL_SEND_MAIL_NOT_EXISTS); } return mail; } /** * æ ¡éªŒé‚®ä»¶å‚数是å¦ç¡®å®ž * * @param template é‚®ç®±æ¨¡æ¿ * @param templateParams å‚数列表 */ @VisibleForTesting void validateTemplateParams(MailTemplateDO template, Map<String, Object> templateParams) { template.getParams().forEach(key -> { Object value = templateParams.get(key); if (value == null) { throw exception(MAIL_SEND_TEMPLATE_PARAM_MISS, key); } }); } }