zelong.shao

task|预警邮件提醒

Showing 19 changed files with 554 additions and 39 deletions
...@@ -29,13 +29,15 @@ public interface ParamConfigConstants { ...@@ -29,13 +29,15 @@ public interface ParamConfigConstants {
29 String PUSH_IMP001_RETRY_NUMBER = "push_imp001_retry_number"; 29 String PUSH_IMP001_RETRY_NUMBER = "push_imp001_retry_number";
30 //推送进口文件定时任务处理数量 30 //推送进口文件定时任务处理数量
31 String PUSH_CON_NUMBER = "push_con_number"; 31 String PUSH_CON_NUMBER = "push_con_number";
32 - //通知发件人定时任务处理数量
33 - String NOTIFICATION_SENDER_NUMBER = "notification_sender_number";
34 //通知发件人邮件定时任务处理数量 32 //通知发件人邮件定时任务处理数量
35 String NOTIFICATION_SENDER_EMAIL_NUMBER = "notification_sender_email_number"; 33 String NOTIFICATION_SENDER_EMAIL_NUMBER = "notification_sender_email_number";
36 //邮件发送进口文件时间间隔key 34 //邮件发送进口文件时间间隔key
37 String PUSH_CON_EMAIL_INTERVAL = "push_con_email_interval"; 35 String PUSH_CON_EMAIL_INTERVAL = "push_con_email_interval";
38 //通知发件人时间间隔 36 //通知发件人时间间隔
39 String NOTIFICATION_SENDER_EMAIL_INTERVAL = "notification_sender_email_interval"; 37 String NOTIFICATION_SENDER_EMAIL_INTERVAL = "notification_sender_email_interval";
38 + //预警邮件任务时间间隔
39 + String SEND_FAIL_ALERT_INTERVAL = "send_fail_alert_interval";
40 + //错误邮件预警任务显示运单数量
41 + String FAILED_EMAIL_CON_NUMBER = "failed_email_con_number";
40 } 42 }
41 } 43 }
......
1 package com.fedex.connect.common.dependencies.enums.biz; 1 package com.fedex.connect.common.dependencies.enums.biz;
2 2
3 +import java.util.Arrays;
4 +import java.util.List;
5 +
3 /** 6 /**
4 * @Author mt 7 * @Author mt
5 * @Description 邮件推送类型 8 * @Description 邮件推送类型
6 * @Date 2024/11/19 9 * @Date 2024/11/19
7 */ 10 */
8 public enum EmailTypeEnum { 11 public enum EmailTypeEnum {
9 - PUSH_CON_FILE("emailType_01","pushConFile","推送预清关文件"), 12 + PUSH_CON_FILE("emailType_01","Push Pre-Customs Clearance Files","推送预清关文件"),
10 NOTIFICATION_SENDER("emailType_02","notificationSender","提醒发件人"), 13 NOTIFICATION_SENDER("emailType_02","notificationSender","提醒发件人"),
14 + SEND_FAILED_EMAIL("emailType_03","sendFailedEmail","错误邮件预警"),
11 15
12 ; 16 ;
13 17
...@@ -21,6 +25,21 @@ public enum EmailTypeEnum { ...@@ -21,6 +25,21 @@ public enum EmailTypeEnum {
21 this.msg = msg; 25 this.msg = msg;
22 } 26 }
23 27
28 + // 获取所有需要错误预警的code
29 + public static List<String> getFailedAlertCodes() {
30 + return Arrays.asList(PUSH_CON_FILE.getCode(),NOTIFICATION_SENDER.getCode());
31 + }
32 +
33 + // 获取 enMsg 根据 code
34 + public static String getEnMsgByCode(String code) {
35 + for (EmailTypeEnum emailType : EmailTypeEnum.values()) {
36 + if (emailType.code.equals(code)) {
37 + return emailType.enMsg;
38 + }
39 + }
40 + return null; // 如果找不到对应的 code,返回 null
41 + }
42 +
24 public String getCode() { 43 public String getCode() {
25 return code; 44 return code;
26 } 45 }
......
...@@ -13,7 +13,13 @@ public class ClearanceEmailTemplate implements EmailTemplate { ...@@ -13,7 +13,13 @@ public class ClearanceEmailTemplate implements EmailTemplate {
13 public String getTitle(Object ... arguments) { 13 public String getTitle(Object ... arguments) {
14 return MessageFormat.format(CLEARANCE_TITLE.TITLE,arguments); 14 return MessageFormat.format(CLEARANCE_TITLE.TITLE,arguments);
15 } 15 }
16 - 16 + /**
17 + * 邮件说明
18 + */
19 + @Override
20 + public String getDescription(Object... arguments) {
21 + return null;
22 + }
17 /** 23 /**
18 * 模板内容 24 * 模板内容
19 */ 25 */
......
...@@ -3,4 +3,5 @@ package com.fedex.connect.common.dependencies.template.clearanceEmail; ...@@ -3,4 +3,5 @@ package com.fedex.connect.common.dependencies.template.clearanceEmail;
3 public interface EmailTemplate { 3 public interface EmailTemplate {
4 String getTitle(Object ... arguments); 4 String getTitle(Object ... arguments);
5 String getBody(Object ... arguments); 5 String getBody(Object ... arguments);
6 + String getDescription(Object... arguments);
6 } 7 }
......
1 +package com.fedex.connect.common.dependencies.template.clearanceEmail;
2 +
3 +import org.springframework.stereotype.Component;
4 +
5 +import java.text.MessageFormat;
6 +
7 +@Component
8 +public class SendFailedEmailTemplate implements EmailTemplate {
9 + /**
10 + * 模板标题格式化返回内容
11 + */
12 + @Override
13 + public String getTitle(Object ... arguments) {
14 + return MessageFormat.format(FAILED_EMAIL_TITLE.TITLE,arguments);
15 + }
16 +
17 + /**
18 + * 模板内容
19 + */
20 + @Override
21 + public String getBody(Object ... arguments) {
22 + return FAILED_EMAIL_BODY.TABLE;
23 + }
24 +
25 + /**
26 + * 邮件说明
27 + */
28 + @Override
29 + public String getDescription(Object... arguments) {
30 + return MessageFormat.format(FAILED_EMAIL_BODY.DESCRIPTION,arguments);
31 + }
32 +
33 +
34 + interface FAILED_EMAIL_TITLE{
35 + String TITLE = "失败预警";
36 + }
37 +
38 + interface FAILED_EMAIL_BODY{
39 + String DESCRIPTION = "<p>1.【文件推送】任务,系统启动后每{0}分钟轮巡一次。</p>\n" +
40 + " <p>2.【推送预清关文件】任务,系统启动后每{1}分钟轮巡一次。</p>\n" +
41 + " <p>3.【提醒发件人】任务,系统启动后每{2}分钟轮巡一次。</p>\n" +
42 + " <p>备注:邮件发送机制:</p>\n" +
43 + " <p>该预警邮件任务,系统启动后每{3}分钟执行一次,当日上述3个定时任务,有任何一个任务的最终判定为失败的记录数量大于{4},则自动发送邮件通知FedEX IT,每个接口显示最新{5}条失败运单号、当日调用总次数、当日调用失败总次数。</p>\n" +
44 + " <p style=\"font-size:10px;\">(注:所有任务相关的数字均可以在系统配置界面调整)</p>";
45 +
46 + String TABLE = "<table style=\"width: 100%;table-layout: fixed;padding: 20px;width: 100%;border-collapse: collapse;\">\n" +
47 + "<tr>\n" +
48 + "<td style=\"border: 0px;text-align: left;padding: 8px;\">\n" +
49 + "<div style=\"margin: auto;padding: 20px;\">\n" +
50 + "<h2 style=\"text-align: center;\">接口调用失败详情</h2>\n" +
51 + "<table style=\"width: 100%;border-collapse: collapse;\">\n" +
52 + "<tr>\n" +
53 + "<th style=\"border: 1px solid #dddddd;text-align: left;padding: 8px;background-color: #593BB7;color: white;\">任务名称</th>\n" +
54 + "<th style=\"border: 1px solid #dddddd;text-align: left;padding: 8px;background-color: #593BB7;color: white;\">失败的运单号</th>\n" +
55 + "<th style=\"border: 1px solid #dddddd;text-align: left;padding: 8px;background-color: #593BB7;color: white;\">总数</th>\n" +
56 + "<th style=\"border: 1px solid #dddddd;text-align: left;padding: 8px;background-color: #593BB7;color: white;\">失败数量</th>\n" +
57 + "</tr>\n" +
58 + "{0}\n" +
59 + "</table>\n" +
60 + "<div style=\"color:#808080;font-style:Arial;font-size:14px;margin: auto;margin-bottom: 5px;\">\n" +
61 + "{1}\n" +
62 + "</div>\n" +
63 + "</div>\n" +
64 + "</td>\n" +
65 + "</tr>\n" +
66 + "</table>";
67 + }
68 +}
1 +package com.fedex.connect.task.data.dto;
2 +
3 +import lombok.Data;
4 +
5 +import java.util.List;
6 +/**
7 + * @Author Szl
8 + * @Description 类说明 发送预警邮件dto
9 + * @Date 2024/11/21
10 + */
11 +@Data
12 +public class SendFailedEmailDto {
13 + private String typeCode;
14 + private long statusCodeCount;
15 + private List<String> bizCodes;
16 + private long totalCount;
17 +
18 + public SendFailedEmailDto(String typeCode, long statusCodeCount, List<String> latestBizCodes, long totalCount) {
19 + this.typeCode = typeCode;
20 + this.statusCodeCount = statusCodeCount;
21 + this.bizCodes = latestBizCodes;
22 + this.totalCount = totalCount;
23 + }
24 +}
...@@ -3,25 +3,55 @@ package com.fedex.connect.task.job; ...@@ -3,25 +3,55 @@ package com.fedex.connect.task.job;
3 import com.fedex.connect.common.dependencies.contants.ParamConfigConstants; 3 import com.fedex.connect.common.dependencies.contants.ParamConfigConstants;
4 import com.fedex.connect.task.annotation.ProcessingInterval; 4 import com.fedex.connect.task.annotation.ProcessingInterval;
5 import com.fedex.connect.task.service.biz.IDuplicateConsignmentEmailService; 5 import com.fedex.connect.task.service.biz.IDuplicateConsignmentEmailService;
6 +import com.fedex.connect.task.service.biz.IPushConsignmentFileService;
7 +import com.fedex.connect.task.service.sys.ISendFailedEmailAlertService;
6 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.beans.factory.annotation.Autowired;
7 import org.springframework.scheduling.annotation.Scheduled; 9 import org.springframework.scheduling.annotation.Scheduled;
8 import org.springframework.stereotype.Component; 10 import org.springframework.stereotype.Component;
9 11
10 -/**
11 - * @Author Szl
12 - * @Description 类说明 发邮件通知到该运单所属用户,告知运单已被其他用户创建上传
13 - * @Date 2024/11/20
14 - */
15 @Component 12 @Component
16 -public class DuplicateConsignmentEmailJob { 13 +public class EmailJob {
17 -
18 @Autowired 14 @Autowired
19 private IDuplicateConsignmentEmailService duplicateConsignmentEmailService; 15 private IDuplicateConsignmentEmailService duplicateConsignmentEmailService;
16 + @Autowired
17 + private IPushConsignmentFileService pushConsignmentFileService;
18 + @Autowired
19 + private ISendFailedEmailAlertService sendWarningEmail;
20 20
21 + /**
22 + * @Author Szl
23 + * @Description 功能说明 提醒发件人
24 + * @Date 2024/11/21
25 + * @param
26 + * @return void
27 + */
21 @ProcessingInterval(paramCode = ParamConfigConstants.TASK_PARAM_KEYS.NOTIFICATION_SENDER_EMAIL_INTERVAL) 28 @ProcessingInterval(paramCode = ParamConfigConstants.TASK_PARAM_KEYS.NOTIFICATION_SENDER_EMAIL_INTERVAL)
22 @Scheduled(cron = "${export.task.allocation.sendOb}") 29 @Scheduled(cron = "${export.task.allocation.sendOb}")
23 - public void pushConsignmentFileTask() { 30 + public void notificationSenderTask() {
24 duplicateConsignmentEmailService.duplicateConsignmentEmail(); 31 duplicateConsignmentEmailService.duplicateConsignmentEmail();
25 } 32 }
26 33
34 + /**
35 + * @Author Szl
36 + * @Description 功能说明 推送清关文件
37 + * @Date 2024/11/21
38 + * @param
39 + * @return void
40 + */
41 + @ProcessingInterval(paramCode = ParamConfigConstants.TASK_PARAM_KEYS.PUSH_CON_EMAIL_INTERVAL)
42 + @Scheduled(cron = "${export.task.allocation.sendOb}")
43 + public void pushConsignmentFileTask() {
44 + pushConsignmentFileService.pushConsignmentFileTask();
45 + }
46 +
47 + /**
48 + * 发送失败邮件提醒
49 + */
50 + @ProcessingInterval(paramCode = ParamConfigConstants.TASK_PARAM_KEYS.SEND_FAIL_ALERT_INTERVAL)
51 + @Scheduled(cron = "${export.task.allocation.warningEmail}")
52 + public void sendingFailedEmailAlert() {
53 + sendWarningEmail.sendFailedEmail();
54 + }
55 +
56 +
27 } 57 }
......
1 -package com.fedex.connect.task.job;
2 -
3 -import com.fedex.connect.common.dependencies.contants.ParamConfigConstants;
4 -import com.fedex.connect.task.annotation.ProcessingInterval;
5 -import com.fedex.connect.task.service.biz.IPushConsignmentFileService;
6 -import org.springframework.beans.factory.annotation.Autowired;
7 -import org.springframework.scheduling.annotation.Scheduled;
8 -import org.springframework.stereotype.Component;
9 -
10 -/**
11 - * @Author Szl
12 - * @Description 类说明 异步任务发送邮件到预清关组
13 - * @Date 2024/11/7
14 - */
15 -@Component
16 -public class PushConsignmentFileEmailJob {
17 -
18 - @Autowired
19 - private IPushConsignmentFileService pushConsignmentFileService;
20 -
21 - @ProcessingInterval(paramCode = ParamConfigConstants.TASK_PARAM_KEYS.PUSH_CON_EMAIL_INTERVAL)
22 - @Scheduled(cron = "${export.task.allocation.sendOb}")
23 - public void pushConsignmentFileTask() {
24 - pushConsignmentFileService.pushConsignmentFileTask();
25 - }
26 -}
...@@ -36,5 +36,7 @@ public class AbstractDaoRepository { ...@@ -36,5 +36,7 @@ public class AbstractDaoRepository {
36 @Autowired 36 @Autowired
37 protected ParamConfigMapper paramConfigMapper; 37 protected ParamConfigMapper paramConfigMapper;
38 @Autowired 38 @Autowired
39 + protected ParamConfigExtMapper paramConfigExtMapper;
40 + @Autowired
39 protected ConsignmentMapper consignmentMapper; 41 protected ConsignmentMapper consignmentMapper;
40 } 42 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -4,6 +4,7 @@ import com.fedex.connect.common.model.biz.Email; ...@@ -4,6 +4,7 @@ import com.fedex.connect.common.model.biz.Email;
4 import org.apache.ibatis.annotations.Delete; 4 import org.apache.ibatis.annotations.Delete;
5 import org.apache.ibatis.annotations.Mapper; 5 import org.apache.ibatis.annotations.Mapper;
6 import org.apache.ibatis.annotations.Param; 6 import org.apache.ibatis.annotations.Param;
7 +import org.apache.ibatis.annotations.Select;
7 8
8 import java.util.List; 9 import java.util.List;
9 10
...@@ -13,4 +14,12 @@ public interface EmailExtMapper { ...@@ -13,4 +14,12 @@ public interface EmailExtMapper {
13 14
14 @Delete("DELETE FROM T_BIZ_EMAIL WHERE ID = #{id}") 15 @Delete("DELETE FROM T_BIZ_EMAIL WHERE ID = #{id}")
15 void deleteById(@Param("id") Long id); 16 void deleteById(@Param("id") Long id);
17 +
18 + @Select("<script>" +
19 + "SELECT * " +
20 + "FROM T_BIZ_EMAIL " +
21 + "WHERE MODIFY_TIME &gt;= #{modifyTime}" +
22 + "</script>")
23 + List<Email> findEmailsByModifyTime(@Param("modifyTime") String modifyTime);
24 +
16 } 25 }
......
...@@ -25,4 +25,11 @@ public interface PushObMapperExt { ...@@ -25,4 +25,11 @@ public interface PushObMapperExt {
25 "AND TRUNC(CREATE_TIME) = TRUNC(TO_DATE(#{date,jdbcType=VARCHAR}, 'YYYY-MM-DD'))" + 25 "AND TRUNC(CREATE_TIME) = TRUNC(TO_DATE(#{date,jdbcType=VARCHAR}, 'YYYY-MM-DD'))" +
26 "</script>") 26 "</script>")
27 Integer findErrPushForEmail(@Param("pushNum") Long pushNum, @Param("statusCode") String statusCode, @Param("date") String date); 27 Integer findErrPushForEmail(@Param("pushNum") Long pushNum, @Param("statusCode") String statusCode, @Param("date") String date);
28 +
29 + @Select("<script>" +
30 + "SELECT * " +
31 + "FROM T_BIZ_EMAIL " +
32 + "WHERE MODIFY_TIME &gt;= #{modifyTime}" +
33 + "</script>")
34 + List<PushOb> findPushObByModifyTime(@Param("modifyTime") String modifyTime);
28 } 35 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -10,4 +10,6 @@ public interface IEmailRepository { ...@@ -10,4 +10,6 @@ public interface IEmailRepository {
10 void deleteById(Long id); 10 void deleteById(Long id);
11 11
12 void saveOrUpdate(Email entity); 12 void saveOrUpdate(Email entity);
13 +
14 + List<Email> findEmailsByModifyTime(String modifyTime);
13 } 15 }
......
1 package com.fedex.connect.task.repository.repo.biz; 1 package com.fedex.connect.task.repository.repo.biz;
2 2
3 import com.fedex.connect.common.model.biz.PushOb; 3 import com.fedex.connect.common.model.biz.PushOb;
4 +
4 import java.util.List; 5 import java.util.List;
5 6
6 public interface IPushObRepository { 7 public interface IPushObRepository {
...@@ -45,4 +46,6 @@ public interface IPushObRepository { ...@@ -45,4 +46,6 @@ public interface IPushObRepository {
45 List<PushOb> findErrPushOb(Long pushNum,String statusCode,Long rownum); 46 List<PushOb> findErrPushOb(Long pushNum,String statusCode,Long rownum);
46 47
47 Integer findErrPushForEmail(Long pushNum,String statusCode,String date); 48 Integer findErrPushForEmail(Long pushNum,String statusCode,String date);
49 +
50 + List<PushOb> findPushObByModifyTime(String modifyTime);
48 } 51 }
......
...@@ -34,4 +34,9 @@ public class EmailRepositoryImpl extends AbstractDaoRepository implements IEmail ...@@ -34,4 +34,9 @@ public class EmailRepositoryImpl extends AbstractDaoRepository implements IEmail
34 } 34 }
35 } 35 }
36 36
37 + @Override
38 + public List<Email> findEmailsByModifyTime(String modifyTime) {
39 + return emailExtMapper.findEmailsByModifyTime(modifyTime);
40 + }
41 +
37 } 42 }
......
...@@ -62,4 +62,9 @@ public class PushObRepositoryImpl extends AbstractDaoRepository implements IPush ...@@ -62,4 +62,9 @@ public class PushObRepositoryImpl extends AbstractDaoRepository implements IPush
62 public Integer findErrPushForEmail(Long pushNum, String statusCode, String date) { 62 public Integer findErrPushForEmail(Long pushNum, String statusCode, String date) {
63 return pushObMapperExt.findErrPushForEmail(pushNum,statusCode,date); 63 return pushObMapperExt.findErrPushForEmail(pushNum,statusCode,date);
64 } 64 }
65 +
66 + @Override
67 + public List<PushOb> findPushObByModifyTime(String modifyTime) {
68 + return pushObMapperExt.findPushObByModifyTime(modifyTime);
69 + }
65 } 70 }
......
...@@ -37,7 +37,7 @@ public class DuplicateConsignmentEmailServiceImpl extends BaseService implements ...@@ -37,7 +37,7 @@ public class DuplicateConsignmentEmailServiceImpl extends BaseService implements
37 /** 37 /**
38 * 查询邮件发送日志表中状态为待推送且类型为“提醒发件人”的数据 38 * 查询邮件发送日志表中状态为待推送且类型为“提醒发件人”的数据
39 */ 39 */
40 - List<Email> emails = iEmailExtRepository.findEmailsByDic(cacheSystem.getDicEmailType(EmailTypeEnum.NOTIFICATION_SENDER.getEnMsg()).getCode(), 40 + List<Email> emails = iEmailExtRepository.findEmailsByDic(cacheSystem.getDicEmailType(EmailTypeEnum.NOTIFICATION_SENDER.getCode()).getCode(),
41 cacheSystem.getDicEmailStatus(EmailStatusEnum.PENDING.getEnMsg()).getCode(), ParamConfigConstants.TASK_PARAM_KEYS.NOTIFICATION_SENDER_EMAIL_NUMBER); 41 cacheSystem.getDicEmailStatus(EmailStatusEnum.PENDING.getEnMsg()).getCode(), ParamConfigConstants.TASK_PARAM_KEYS.NOTIFICATION_SENDER_EMAIL_NUMBER);
42 /** 42 /**
43 * 发送邮件 43 * 发送邮件
......
1 +package com.fedex.connect.task.service.sys;
2 +
3 +public interface ISendFailedEmailAlertService {
4 + void sendFailedEmail();
5 +}
1 +package com.fedex.connect.task.service.sys.impl;
2 +
3 +import com.fedex.connect.common.dependencies.util.DateUtil;
4 +import com.fedex.connect.common.model.biz.Email;
5 +import com.fedex.connect.common.model.biz.PushOb;
6 +import com.fedex.connect.common.model.sys.ParamConfig;
7 +import com.fedex.connect.task.data.dto.MailConfigDto;
8 +import com.fedex.connect.task.data.dto.SendFailedEmailDto;
9 +import com.fedex.connect.task.service.base.BaseService;
10 +import com.fedex.connect.task.service.sys.ISendFailedEmailAlertService;
11 +import com.fedex.connect.task.utils.sys.EmailUtil;
12 +import com.fedex.connect.task.utils.sys.SendFailedEmailUtil;
13 +import lombok.extern.slf4j.Slf4j;
14 +import org.springframework.beans.factory.annotation.Autowired;
15 +import org.springframework.stereotype.Service;
16 +
17 +import java.util.Date;
18 +import java.util.List;
19 +import java.util.Map;
20 +
21 +@Service
22 +@Slf4j
23 +public class SendFailedEmailAlertServiceImpl extends BaseService implements ISendFailedEmailAlertService {
24 +
25 + @Autowired
26 + private SendFailedEmailUtil sendFailedEmailUtil;
27 +
28 + @Autowired
29 + private EmailUtil emailUtil;
30 +
31 + /**
32 + * @Author Szl
33 + * @Description 功能说明 推送错误预警邮件
34 + * @Date 2024/11/21
35 + * @param
36 + * @return void
37 + */
38 + @Override
39 + public void sendFailedEmail() {
40 + /**
41 + * 获取配置信息
42 + */
43 + Map<String, ParamConfig> paramConfigMap = sendFailedEmailUtil.getParam();
44 + /**
45 + * 查询需要发送邮件的记录
46 + */
47 + String date = DateUtil.format(new Date());
48 + List<Email> emails = sendFailedEmailUtil.getEmails(date);
49 + /**
50 + * 查询推送文件集合
51 + */
52 + List<PushOb> obs= sendFailedEmailUtil.getOb(date);
53 + /**
54 + * 处理邮件集合,过滤需要发送邮件的数据
55 + */
56 + List<SendFailedEmailDto> sendFailedEmailDto = sendFailedEmailUtil.createSendFailedEmailDto(emails,obs,paramConfigMap);
57 + /**
58 + * 构建邮件内容
59 + */
60 + String emailBody = sendFailedEmailUtil.createEmailBody(sendFailedEmailDto,paramConfigMap);
61 + /**
62 + * 构建发送邮件dto
63 + */
64 + MailConfigDto mailConfigDto = sendFailedEmailUtil.createMailConfigDto(emailBody);
65 + /**
66 + * 发送邮件
67 + */
68 + boolean result = emailUtil.sendMail(mailConfigDto);
69 + try {
70 + /**
71 + * 保存邮件记录
72 + */
73 + sendFailedEmailUtil.saveEmail(result,mailConfigDto);
74 + }catch (Exception e){
75 + log.error("保存邮件记录失败",e);
76 + }
77 + }
78 +}
1 +package com.fedex.connect.task.utils.sys;
2 +
3 +import com.fedex.connect.common.dependencies.contants.DigitConstants;
4 +import com.fedex.connect.common.dependencies.contants.ParamConfigConstants;
5 +import com.fedex.connect.common.dependencies.enums.biz.EmailStatusEnum;
6 +import com.fedex.connect.common.dependencies.enums.biz.EmailTypeEnum;
7 +import com.fedex.connect.common.dependencies.enums.biz.PushObStatusEnum;
8 +import com.fedex.connect.common.dependencies.template.clearanceEmail.SendFailedEmailTemplate;
9 +import com.fedex.connect.common.dependencies.util.AssignmentFieldUtils;
10 +import com.fedex.connect.common.model.biz.Email;
11 +import com.fedex.connect.common.model.biz.PushOb;
12 +import com.fedex.connect.common.model.log.EmailHistory;
13 +import com.fedex.connect.common.model.sys.ParamConfig;
14 +import com.fedex.connect.task.data.dto.MailConfigDto;
15 +import com.fedex.connect.task.data.dto.SendFailedEmailDto;
16 +import com.fedex.connect.task.repository.repo.biz.IEmailRepository;
17 +import com.fedex.connect.task.repository.repo.biz.IPushObRepository;
18 +import com.fedex.connect.task.repository.repo.log.IEmailHistoryRepository;
19 +import com.fedex.connect.task.repository.repo.sys.IParamConfigRepository;
20 +import org.springframework.beans.factory.annotation.Autowired;
21 +import org.springframework.stereotype.Component;
22 +import org.springframework.util.CollectionUtils;
23 +
24 +import java.util.*;
25 +import java.util.stream.Collectors;
26 +
27 +@Component
28 +public class SendFailedEmailUtil {
29 +
30 + @Autowired
31 + private IEmailRepository emailRepository;
32 + @Autowired
33 + private SendFailedEmailTemplate sendFailedEmailTemplate;
34 + @Autowired
35 + protected IParamConfigRepository paramConfigRepository;
36 + @Autowired
37 + protected IEmailHistoryRepository emailHistoryRepository;
38 + @Autowired
39 + protected IPushObRepository pushObRepository;
40 + /**
41 + * @Author Szl
42 + * @Description 功能说明 查询当日Email
43 + * @Date 2024/11/21
44 + * @param
45 + * @return java.util.List<com.fedex.connect.common.model.biz.Email>
46 + */
47 + public List<Email> getEmails(String date){
48 + return emailRepository.findEmailsByModifyTime(date);
49 + }
50 +
51 + /**
52 + * 查询当日ob记录
53 + * @param date
54 + * @return
55 + */
56 + public List<PushOb> getOb(String date){
57 + return pushObRepository.findPushObByModifyTime(date);
58 + }
59 +
60 + /**
61 + * @Author Szl
62 + * @Description 功能说明 统计每种类型的邮件总数与错误总数
63 + * @Date 2024/11/21
64 + * @param emails
65 + * @return java.util.List<com.fedex.connect.task.data.dto.SendFailedEmailDto>
66 + */
67 + public List<SendFailedEmailDto> createSendFailedEmailDto(List<Email> emails,List<PushOb> obs,Map<String, ParamConfig> paramConfig){
68 + List<SendFailedEmailDto> emailDto = this.getEmailDto(emails,paramConfig.get(ParamConfigConstants.TASK_PARAM_KEYS.FAILED_EMAIL_CON_NUMBER).getValue());
69 + if (!CollectionUtils.isEmpty(obs)){
70 + SendFailedEmailDto obDto = this.getObDto(obs,paramConfig.get(ParamConfigConstants.TASK_PARAM_KEYS.FAILED_EMAIL_CON_NUMBER).getValue());
71 + emailDto.add(obDto);
72 + }
73 + return emailDto;
74 + }
75 +
76 + private SendFailedEmailDto getObDto(List<PushOb> obs,String size){
77 + // 获取总数
78 + long totalCount = obs.size();
79 +
80 + // 获取 STATUS_CODE 为 pushObStatus_03 的数量
81 + long statusCodeCount = obs.stream()
82 + .filter(pushOb -> PushObStatusEnum.PUSH_FAILED.getCode().equals(pushOb.getStatusCode()))
83 + .count();
84 +
85 + // 获取前 10 条 CONSIGNMENT_CODE
86 + List<String> latestConsignmentCodes = obs.stream()
87 + .sorted(Comparator.comparing(PushOb::getModifyTime).reversed()) // 按 MODIFY_TIME 降序排序
88 + .limit(Long.parseLong(size)) // 取前 10 条
89 + .map(PushOb::getConsignmentCode) // 获取 CONSIGNMENT_CODE
90 + .collect(Collectors.toList());
91 + return new SendFailedEmailDto("ob",statusCodeCount,latestConsignmentCodes,totalCount);
92 + }
93 +
94 + /**
95 + * @Author Szl
96 + * @Description 功能说明 获取Email的失败数量dto
97 + * @Date 2024/11/21
98 + * @param emails
99 + * @return java.util.List<com.fedex.connect.task.data.dto.SendFailedEmailDto>
100 + */
101 + private List<SendFailedEmailDto> getEmailDto(List<Email> emails,String size){
102 + // 定义所有可能的 TYPE_CODE
103 + List<String> allTypeCodes = EmailTypeEnum.getFailedAlertCodes();
104 +
105 + // 按 TYPE_CODE 分组
106 + Map<String, List<Email>> groupedEmails = emails.stream()
107 + .collect(Collectors.groupingBy(Email::getTypeCode));
108 +
109 + // 处理每个 TYPE_CODE
110 + List<SendFailedEmailDto> results = allTypeCodes.stream()
111 + .map(typeCode -> {
112 + List<Email> emailList = groupedEmails.getOrDefault(typeCode, Collections.emptyList());
113 +
114 + // 1. 统计 STATUS_CODE 为 FAILED 的数量
115 + long statusCodeCount = emailList.stream()
116 + .filter(email -> EmailStatusEnum.FAILED.getCode().equals(email.getStatusCode()))
117 + .count();
118 +
119 + // 2. 获取 MODIFY_TIME 最晚的 10 个 BIZ_CODE
120 + List<String> latestBizCodes = emailList.stream()
121 + .sorted(Comparator.comparing(Email::getModifyTime).reversed())
122 + .limit(Long.parseLong(size))
123 + .map(Email::getBizCode)
124 + .collect(Collectors.toList());
125 +
126 + // 3. 统计 TYPE_CODE 的总数量
127 + long totalCount = emailList.size();
128 +
129 + return new SendFailedEmailDto(typeCode, statusCodeCount, latestBizCodes, totalCount);
130 + })
131 + .collect(Collectors.toList());
132 + return results;
133 + }
134 +
135 +
136 + /**
137 + * @Author Szl
138 + * @Description 功能说明 构建邮件内容
139 + * @Date 2024/11/21
140 + * @param sendFailedEmailDto
141 + * @return java.lang.String
142 + */
143 + public String createEmailBody(List<SendFailedEmailDto> sendFailedEmailDto,Map<String, ParamConfig> paramConfig){
144 + /**
145 + * 邮件内容
146 + */
147 + StringBuilder tableRows = new StringBuilder();
148 + this.getTableRows(sendFailedEmailDto, tableRows);
149 + /**
150 + * 邮件备注
151 + */
152 + StringBuffer remarks = new StringBuffer();
153 + this.buildBottom(remarks,paramConfig);
154 + /**
155 + * 添加模板
156 + */
157 + String body = sendFailedEmailTemplate.getBody(tableRows, remarks);
158 + return body;
159 + }
160 +
161 + /**
162 + * @Author Szl
163 + * @Description 功能说明 构造表格行内容
164 + * @Date 2024/11/21
165 + * @param sendFailedEmailDto
166 + * @param tableRows
167 + * @return java.lang.StringBuilder
168 + */
169 + private StringBuilder getTableRows(List<SendFailedEmailDto> sendFailedEmailDto,StringBuilder tableRows){
170 + for (SendFailedEmailDto failedEmailDto : sendFailedEmailDto) {
171 + tableRows.append("<tr>" +
172 + "<td style=\"border: 1px solid #dddddd;text-align: left;padding: 8px;\">"+EmailTypeEnum.getEnMsgByCode(failedEmailDto.getTypeCode())+"</td>" +
173 + "<td style=\"border: 1px solid #dddddd;text-align: left;padding: 8px;\">"+ failedEmailDto.getBizCodes() +"</td>" +
174 + "<td style=\"border: 1px solid #dddddd;text-align: left;padding: 8px;\">"+ failedEmailDto.getTotalCount() +"</td>" +
175 + "<td style=\"border: 1px solid #dddddd;text-align: left;padding: 8px;\">"+ failedEmailDto.getStatusCodeCount() +"</td>" +
176 + "</tr>");
177 + }
178 + return tableRows;
179 + }
180 +
181 + /**
182 + * @Author Szl
183 + * @Description 功能说明 构建底部备注
184 + * @Date 2024/11/21
185 + * @param remarks
186 + * @return void
187 + */
188 + private void buildBottom(StringBuffer remarks,Map<String, ParamConfig> paramConfig){
189 +
190 +
191 + remarks.append(sendFailedEmailTemplate.getDescription(
192 + paramConfig.get(ParamConfigConstants.TASK_PARAM_KEYS.PUSH_IMP001_INTERVAL).getValue(),
193 + paramConfig.get(ParamConfigConstants.TASK_PARAM_KEYS.PUSH_CON_EMAIL_INTERVAL).getValue(),
194 + paramConfig.get(ParamConfigConstants.TASK_PARAM_KEYS.NOTIFICATION_SENDER_EMAIL_INTERVAL).getValue(),
195 + paramConfig.get(ParamConfigConstants.TASK_PARAM_KEYS.SEND_FAIL_ALERT_INTERVAL).getValue(),
196 + 5,
197 + paramConfig.get(ParamConfigConstants.TASK_PARAM_KEYS.FAILED_EMAIL_CON_NUMBER).getValue())
198 + );
199 + }
200 +
201 + /**
202 + * @Author Szl
203 + * @Description 功能说明 构建邮件DTO
204 + * @Date 2024/11/21
205 + * @param body
206 + * @return com.fedex.connect.task.data.dto.MailConfigDto
207 + */
208 + public MailConfigDto createMailConfigDto(String body){
209 + MailConfigDto mailConfigDto = new MailConfigDto();
210 + mailConfigDto.setHost("");
211 + mailConfigDto.setPort("");
212 + mailConfigDto.setAuth("");
213 + //设置代理
214 + mailConfigDto.setProxyStartFlag("");
215 + mailConfigDto.setProxyHost("");
216 + mailConfigDto.setProxyPort("");
217 + //发件人
218 + mailConfigDto.setFrom("");
219 + //发件人密码
220 + mailConfigDto.setPassword("");
221 + //ce接收人
222 + mailConfigDto.setTo("");
223 + //设置邮件标题
224 + mailConfigDto.setSubject("");
225 + //设置邮件内容
226 + mailConfigDto.setContent(body);
227 + return mailConfigDto;
228 + }
229 +
230 + /**
231 + * @Author Szl
232 + * @Description 功能说明 保存邮件记录
233 + * @Date 2024/11/21
234 + * @param result
235 + * @param mailConfigDto
236 + * @return void
237 + */
238 + public void saveEmail(boolean result,MailConfigDto mailConfigDto) throws Exception{
239 + EmailHistory email = new EmailHistory();
240 + email.setToAddress(mailConfigDto.getTo());
241 + email.setCcAddress(mailConfigDto.getCc());
242 + email.setSubject(mailConfigDto.getSubject());
243 + email.setBody(mailConfigDto.getContent());
244 + email.setTypeCode(EmailTypeEnum.SEND_FAILED_EMAIL.getCode());
245 + email.setTypeName(EmailTypeEnum.SEND_FAILED_EMAIL.getMsg());
246 + if (result){
247 + email.setStatusCode(EmailStatusEnum.SUCCESS.getCode());
248 + email.setStatusName(EmailStatusEnum.SUCCESS.getMsg());
249 + }else {
250 + email.setStatusCode(EmailStatusEnum.FAILED.getCode());
251 + email.setStatusName(EmailStatusEnum.FAILED.getMsg());
252 + }
253 + email.setSendNum(DigitConstants.DIGIT_ONE_LONG);
254 + email.setSendTime(new Date());
255 + AssignmentFieldUtils.assignmentTableBaseField(email);
256 +
257 + emailHistoryRepository.saveOrUpdate(email);
258 + }
259 +
260 + /**
261 + * 获取配置信息
262 + * @return
263 + */
264 + public Map<String, ParamConfig> getParam(){
265 + /**
266 + * 获取任务间隔信息
267 + */
268 + return paramConfigRepository.findValueByCodes(ParamConfigConstants.TASK_PARAM_KEYS.PUSH_IMP001_INTERVAL,
269 + ParamConfigConstants.TASK_PARAM_KEYS.PUSH_CON_EMAIL_INTERVAL,
270 + ParamConfigConstants.TASK_PARAM_KEYS.NOTIFICATION_SENDER_EMAIL_INTERVAL,
271 + ParamConfigConstants.TASK_PARAM_KEYS.SEND_FAIL_ALERT_INTERVAL,
272 + ParamConfigConstants.TASK_PARAM_KEYS.FAILED_EMAIL_CON_NUMBER);
273 + }
274 +
275 +}