package com.order.erp.job; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.order.erp.common.constant.Constant; import com.order.erp.common.utils.EmailSendUtils; import com.order.erp.common.utils.StringUtils; import com.order.erp.common.utils.TransactionHelper; import com.order.erp.domain.EmailTemplateEnum; import com.order.erp.domain.OrderEventEnum; import com.order.erp.domain.OrderStatusEnum; import com.order.erp.domain.dto.BaseDO; import com.order.erp.domain.dto.order.OrderBaseInfoDO; import com.order.erp.domain.dto.order.OrderInspectionStageDO; import com.order.erp.domain.dto.order.OrderTrackStageDO; import com.order.erp.domain.dto.order.ReceiveEmailMappingDO; import com.order.erp.domain.email.OrderProductEmailVO; import com.order.erp.domain.vo.order.OrderEventJobVO; import com.order.erp.domain.vo.order.ReceiveEmailConfigItemVO; import com.order.erp.service.order.*; import freemarker.template.TemplateException; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.Resource; import javax.mail.MessagingException; import java.io.File; import java.io.IOException; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import static com.order.erp.domain.EmailTemplateEnum.BIG_SAMPLE_TEMPLATE; /** * @author: xms * @description: TODO * @date: 2023/6/25 10:35 * @version: 1.0 */ @Slf4j @Component public class OrderOverTimeEventJob { @Resource private OrderBaseInfoService orderBaseInfoService; @Resource private OrderProfitAnalysisService profitAnalysisService; @Resource private OrderCompletionReportService reportService; @Resource private OrderTrackStageService trackStageService; @Resource private OrderInspectionStageService inspectionStageService; @Resource private TransactionHelper transactionHelper; @Resource private EmailSendUtils emailSendUtils; @Resource private ReceiveEmailMappingService receiveEmailMappingService; /** * 凌晨1点执行,一天一次 */ @Scheduled(cron = "0 0 1 * * ?") public void checkOverTimeExecute() { /*首先判断字符串。如果没有ok并且次数达到了三次(统计fail是否存在三次),就提醒。 * 如果有ok,取出ok前的日期,得到日期,那这个日期与HOD日期进行判断*/ List<OrderBaseInfoDO> orderBaseInfoList = orderBaseInfoService.list(new LambdaQueryWrapper<OrderBaseInfoDO>() .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN) .ne(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus())); Set<Long> orderList = orderBaseInfoList.stream().map(OrderBaseInfoDO::getId).collect(Collectors.toSet()); Map<Long, OrderBaseInfoDO> baseInfoDOMap = orderBaseInfoList.stream().collect(Collectors.toMap(OrderBaseInfoDO::getId, Function.identity(), (x, y) -> x)); List<OrderInspectionStageDO> orderInspectionStageList = inspectionStageService.listByIds(orderList); Map<Long, OrderInspectionStageDO> inspectionStageDOMap = orderInspectionStageList.stream().collect(Collectors.toMap(OrderInspectionStageDO::getOrderId, Function.identity(), (x, y) -> x)); List<OrderTrackStageDO> orderTrackStageList = trackStageService.listByIds(orderList); OrderProductEmailVO orderProductEmailVO = new OrderProductEmailVO(); System.out.println("1111111111111111111111111"); //只有跟单信息不为空时,才会有时间和状态。 if (CollectionUtils.isNotEmpty(orderTrackStageList)) { System.out.println("orderId" + baseInfoDOMap); System.out.println("order Base Info" + inspectionStageDOMap); orderTrackStageList.stream().forEach(x -> { System.out.println("orderId" + x.getOrderId()); System.out.println("order Base Info" + baseInfoDOMap.get(x.getOrderId())); if (StringUtils.isBlank(baseInfoDOMap.get(x.getOrderId()).getOrderHodTime())) { // return ServerResult.fail("HODTime不能为空"); } if (baseInfoDOMap.get(x.getOrderId()).getId() == x.getOrderId()) { orderProductEmailVO.setBaseInfo(baseInfoDOMap.get(x.getOrderId())); try { System.out.println("222222222222222222222"); test(EmailTemplateEnum.AITEX_SGS_TEST_TEMPLATE, x.getPpConfirmResult(), orderProductEmailVO); System.out.println("2333333333333333333333"); } catch (MessagingException e) { throw new RuntimeException(e); } catch (TemplateException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } try { test(EmailTemplateEnum.CONFIRM_SAMPLE_TEMPLATE, x.getShippmentSampleConfirmResult(), orderProductEmailVO); } catch (MessagingException e) { throw new RuntimeException(e); } catch (TemplateException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } try { test(EmailTemplateEnum.AITEX_SGS_TEST_TEMPLATE, x.getAitexTestFinishResult(), orderProductEmailVO); } catch (MessagingException e) { throw new RuntimeException(e); } catch (TemplateException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } try { test(EmailTemplateEnum.AITEX_SGS_TEST_TEMPLATE, x.getSgsTestFinishResult(), orderProductEmailVO); } catch (MessagingException e) { throw new RuntimeException(e); } catch (TemplateException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } try { test(EmailTemplateEnum.OTHER_SAMPLE_TEMPLATE, x.getEsoSampleSendTime(), orderProductEmailVO); } catch (MessagingException e) { throw new RuntimeException(e); } catch (TemplateException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } try { test(EmailTemplateEnum.BARCODE_ARRIVAL_TEMPLATE, x.getLatestArrivalTime(), orderProductEmailVO); } catch (MessagingException e) { throw new RuntimeException(e); } catch (TemplateException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } try { test(EmailTemplateEnum.LATEST_DC_TEMPLATE, x.getLatestBkTime(), orderProductEmailVO); } catch (MessagingException e) { throw new RuntimeException(e); } catch (TemplateException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } if (baseInfoDOMap.get(x.getOrderId()).getId() == x.getOrderId() && baseInfoDOMap.get(x.getOrderId()).getId() == inspectionStageDOMap.get(x.getOrderId()).getOrderId()) { orderProductEmailVO.setInspectionStageInfo(inspectionStageDOMap.get(x.getOrderId())); orderProductEmailVO.setBaseInfo(baseInfoDOMap.get(x.getOrderId())); //尾期验货日期。尾期放这里写是因为尾期验货日期需要从inspectionStageDOMap中获取。 try { test(EmailTemplateEnum.END_CHECK_DATE_TEMPLATE, inspectionStageDOMap.get(x.getOrderId()).getEndCheckApplyTime(), orderProductEmailVO); } catch (MessagingException e) { throw new RuntimeException(e); } catch (TemplateException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } /*加上中期验货报告和尾期验货报告的发送,因为他需要发送inspectionStageDOMap实体类中的数据*/ //todo } } ); } } // 写一下检测方法。 /*@param event 代表的含义,这个是对应的枚举类型。 *@param str 代表的含义,这个是状态日期。 *@param orderProductEmailVO 代表的含义,这个邮件要发送的内容。 * */ //todo 还需要判断其他时间,不能单独只判断po时间。 public void test(EmailTemplateEnum eventEnum, String str, OrderProductEmailVO orderProductEmailVO) throws MessagingException, TemplateException, IOException { //获取邮件收件人。 System.out.println("22222222222222222222--1111111111111"); List<List<String>> emails = getEmails(eventEnum, orderProductEmailVO); if (StringUtils.isNotBlank(str)) { //如果为确认样确认,或者AITEX/SGS测试判断是否存在ok。 if (eventEnum.getTitle().equals(EmailTemplateEnum.CONFIRM_SAMPLE_TEMPLATE.getTitle()) || eventEnum.getTitle().equals(EmailTemplateEnum.AITEX_SGS_TEST_TEMPLATE.getTitle()) || eventEnum.getTitle().equals(BIG_SAMPLE_TEMPLATE.getTitle())) { System.out.println("2222222222-22222222222222"); //不包含ok并且三次输入机会都为fail了 if (!str.contains("ok") && org.apache.commons.lang3.StringUtils.countMatches(str, "fail") == 3) { //直接发邮件。 for (List email : emails) { emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO); } //设置状态为1,下次不扫描。 } else if (str.contains("ok") || org.apache.commons.lang3.StringUtils.countMatches(str, "fail") < 3) { //只会有几种种情况,一种是fail,一种是fail+fail。一种是fail+ok,一种是ok,得到最后状态前的值就可以了,前面的不用管。 String[] parats = str.split("\\+"); //获取最后状态前的时间。 String time = parats[str.length() - 3]; LocalDate parse1 = LocalDate.parse(time, DateTimeFormatter.ofPattern("yyyy-M-d")); //得到订单的截止时间。 String orderHodTime = orderProductEmailVO.getBaseInfo().getOrderHodTime(); LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d")); //计算两个时间之间的天数间隔。parse2-parse1 long daysBetween = ChronoUnit.DAYS.between(parse2, parse1); if (eventEnum.getTitle().equals(EmailTemplateEnum.CONFIRM_SAMPLE_TEMPLATE.getTitle())) { if (daysBetween == 21) { //直接发邮件。 for (List email : emails) { emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO); } } } else if (eventEnum.getTitle().equals(EmailTemplateEnum.AITEX_SGS_TEST_TEMPLATE.getTitle())) { if (daysBetween == 3) { //直接发邮件。 for (List email : emails) { emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO); } } } else { if (daysBetween == 7) { //直接发邮件。 for (List email : emails) { emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO); } } } } } //没有ok或者fail状态,只通过时间来判断。 if (eventEnum.getTitle().equals(EmailTemplateEnum.OTHER_SAMPLE_TEMPLATE.getTitle())) { String orderHodTime = orderProductEmailVO.getBaseInfo().getOrderHodTime(); LocalDate parse1 = LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-M-d")); //订单的HOD截止时间。 LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d")); long daysBetween = ChronoUnit.DAYS.between(parse2, parse1); if (daysBetween == 14) { for (List email : emails) { emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO); } } } else if (eventEnum.getTitle().equals(EmailTemplateEnum.BARCODE_ARRIVAL_TEMPLATE.getTitle())) { String orderHodTime = orderProductEmailVO.getBaseInfo().getOrderHodTime(); LocalDate parse1 = LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-M-d")); //订单的HOD截止时间。 LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d")); long daysBetween = ChronoUnit.DAYS.between(parse2, parse1); if (daysBetween == 7) { for (List email : emails) { emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO); } } } else if (eventEnum.getTitle().equals(EmailTemplateEnum.LATEST_DC_TEMPLATE.getTitle())) { String orderHodTime = orderProductEmailVO.getBaseInfo().getOrderHodTime(); LocalDate parse1 = LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-M-d")); //订单的HOD截止时间。 LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d")); long daysBetween = ChronoUnit.DAYS.between(parse2, parse1); if (daysBetween == 10) { for (List email : emails) { emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO); } } } else if (eventEnum.getTitle().equals(EmailTemplateEnum.END_CHECK_DATE_TEMPLATE.getTitle())) { String orderHodTime = orderProductEmailVO.getBaseInfo().getOrderHodTime(); LocalDate parse1 = LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-M-d")); //订单的HOD截止时间。 LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d")); long daysBetween = ChronoUnit.DAYS.between(parse2, parse1); if (daysBetween == 2) { for (List email : emails) { emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO); } } } } } /*发送中期验货报告和尾期验货报告,疑问,是什么时候发送,质检信息中有中期验货字段,是否是填写了中期验货字段就发送还是说填写了跟单信息发送*/ public void send() { } /*发送生产指示书*/ public void sende(File file) { } /*返回邮箱 * 解释:根据订单的客户编码和事件类型,得到这个客户编码配置好的邮箱配置,返回邮箱*/ public List<List<String>> getEmails(EmailTemplateEnum eventEnum, OrderProductEmailVO orderProductEmailVO) { String customerCode = orderProductEmailVO.getBaseInfo().getCustomerCode(); List<ReceiveEmailMappingDO> receiveEmailMappingDOList = receiveEmailMappingService.list(new LambdaQueryWrapper<ReceiveEmailMappingDO>() .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN) .eq(ReceiveEmailMappingDO::getTypeValue, customerCode)); Set<List<String>> emailList = receiveEmailMappingDOList.stream().map(x -> { ReceiveEmailConfigItemVO receiveEmailConfigItemVO = JSON.parseObject(x.getConfigInfos(), ReceiveEmailConfigItemVO.class); if (eventEnum.getTemplateId() == OrderEventEnum.getEvent(receiveEmailConfigItemVO.getEvent()).getTemplateId()) { List<String> emailsList = receiveEmailConfigItemVO.getEmails(); return emailsList; } return null; }).collect(Collectors.toSet()); return new ArrayList<>(emailList); } /* public void a(String str, OrderProductEmailVO orderProductEmailVO) { //包含ok。 String[] parats = str.split("\\+"); //获取ok前的时间。 String time = parats[str.length() - 3]; LocalDate parse1 = LocalDate.parse(time, DateTimeFormatter.ofPattern("yyyy-M-d")); //得到订单的截止时间。 String orderHodTime = orderProductEmailVO.getBaseInfo().getOrderHodTime(); LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d")); //计算两个时间之间的天数间隔。parse2-parse1 long daysBetween = ChronoUnit.DAYS.between(parse2, parse1); if (daysBetween == 21) { //直接发邮件。 for (List email : emails) { emailSendUtils.sendEmail(eventEnum, email, orderProductEmailVO); } } }*/ @Scheduled(cron = "0 0 2 * * ?") public void checkOverTimeExecuteV2() { List<OrderEventJobVO> jobVOList = transfer2OrderEventList(null, null, null); Map<String, List<OrderEventJobVO>> map = handlerOrderEvent(jobVOList); for (Map.Entry<String, List<OrderEventJobVO>> entry : map.entrySet()) { sendEmail4OrderEvent(OrderEventEnum.getEvent(entry.getKey()), entry.getValue()); } } /** * @param eventEnum * @param eventJobVOS */ private void sendEmail4OrderEvent(OrderEventEnum eventEnum, List<OrderEventJobVO> eventJobVOS) { // todo } /** * @param orderBaseInfoList * @param orderInspectionStageList * @param orderTrackStageList * @return */ private List<OrderEventJobVO> transfer2OrderEventList(List<OrderBaseInfoDO> orderBaseInfoList, List<OrderInspectionStageDO> orderInspectionStageList, List<OrderTrackStageDO> orderTrackStageList) { // todo return null; } /** * @param orderEventJobVOList * @return */ private Map<String, List<OrderEventJobVO>> handlerOrderEvent(List<OrderEventJobVO> orderEventJobVOList) { Map<String, List<OrderEventJobVO>> map = new HashMap<>(); for (OrderEventJobVO eventJobVO : orderEventJobVOList) { Map<String, OrderEventJobVO> eventJobVOMap = groupByOrderEvent(eventJobVO); if (CollectionUtils.isNotEmpty(eventJobVOMap)) { for (Map.Entry<String, OrderEventJobVO> entry : eventJobVOMap.entrySet()) { String key = entry.getKey(); if (map.containsKey(key)) { List<OrderEventJobVO> list = map.get(key); list.add(entry.getValue()); map.put(key, list); } else { List<OrderEventJobVO> list = new ArrayList<>(); list.add(entry.getValue()); map.put(key, list); } } } } return map; } /** * @param eventJobVO * @return */ private Map<String, OrderEventJobVO> groupByOrderEvent(OrderEventJobVO eventJobVO) { Map<String, OrderEventJobVO> map = new HashMap<>(); if (filterConfirmSampleOrderEvent(eventJobVO)) { map.put(OrderEventEnum.CONFIRM_SAMPLE_EVENT.getEvent(), eventJobVO); } // todo 其他订单超期事件判断 return map; } /** * @param eventJobVO * @return */ private Boolean filterConfirmSampleOrderEvent(OrderEventJobVO eventJobVO) { // todo 判断是否未能在规定的期限内完成以下货号的确认样确认 return true; } }