Commit 9820c96f681311c33d0f7b6a6810cb00871bbe03

Authored by chenhang4442024
1 parent 43458e11

定时检测超时任务

src/main/java/com/order/erp/job/OrderOverTimeEventJob.java
1 1 package com.order.erp.job;
2 2 import cn.hutool.core.bean.BeanUtil;
3   -import com.alibaba.fastjson.JSON;
4   -import com.alibaba.fastjson.TypeReference;
  3 +import com.alibaba.fastjson.*;
5 4 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
6 5 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
7 6 import com.order.erp.common.constant.Constant;
8   -import com.order.erp.common.utils.EmailSendUtils;
9   -import com.order.erp.common.utils.RedisUtils;
10   -import com.order.erp.common.utils.StringUtils;
11   -import com.order.erp.common.utils.TransactionHelper;
  7 +import com.order.erp.common.utils.*;
12 8 import com.order.erp.domain.EmailTemplateEnum;
13 9 import com.order.erp.domain.OrderEventEnum;
14 10 import com.order.erp.domain.dto.order.OrderBaseInfoDO;
... ... @@ -25,10 +21,13 @@ import javax.annotation.Resource;
25 21 import javax.mail.MessagingException;
26 22 import java.io.IOException;
27 23 import java.time.LocalDate;
  24 +import java.time.LocalDateTime;
28 25 import java.time.format.DateTimeFormatter;
29 26 import java.time.temporal.ChronoUnit;
30 27 import java.util.*;
31 28 import java.util.function.Function;
  29 +import java.util.regex.Matcher;
  30 +import java.util.regex.Pattern;
32 31 import java.util.stream.Collectors;
33 32  
34 33  
... ... @@ -70,22 +69,29 @@ public class OrderOverTimeEventJob {
70 69 @Resource
71 70 private RedisUtils redisUtils;
72 71  
  72 + String dateFormatDay= com.order.erp.common.excel4j.utils.DateUtils.DATE_FORMAT_DAY;
  73 + String dateFormatSEC= com.order.erp.common.excel4j.utils.DateUtils.DATE_FORMAT_SEC;
  74 +
73 75 /**
74 76 * 凌晨1点执行,一天一次
75 77 */
76   - @Scheduled(cron = "0 0 2 * * ?")
  78 + @Scheduled(cron = "0 0 1 * * ?")
  79 + //存储的日期都必须为yyyy-MM-dd HH:mm:ss。
77 80 public void checkOverTimeExecuteV2() throws MessagingException, TemplateException, IOException {
78 81 List<OrderBaseInfoDO> orderBaseInfoDOList = orderBaseInfoService.getEventList();
79   - Set<Long> orderIds = orderBaseInfoDOList.stream().map(OrderBaseInfoDO::getId).collect(Collectors.toSet());
80   - List<OrderInspectionStageDO> orderInspectionStageDOList = inspectionStageService.list(new LambdaQueryWrapper<OrderInspectionStageDO>()
81   - .in(OrderInspectionStageDO::getOrderId, orderIds));
82   - List<OrderTrackStageDO> orderTrackStageDOList = trackStageService.list(new LambdaQueryWrapper<OrderTrackStageDO>()
83   - .in(OrderTrackStageDO::getOrderId, orderIds));
84   - List<OrderEventJobVO> jobVOList = transfer2OrderEventList(orderBaseInfoDOList, orderInspectionStageDOList, orderTrackStageDOList);
85   - Map<String, List<OrderEventJobVO>> map = handlerOrderEvent(jobVOList);
86   - for (Map.Entry<String, List<OrderEventJobVO>> entry : map.entrySet()) {
87   - sendEmail4OrderEvent(OrderEventEnum.getEvent(entry.getKey()), entry.getValue());
  82 + if(CollectionUtils.isNotEmpty(orderBaseInfoDOList)){
  83 + Set<Long> orderIds = orderBaseInfoDOList.stream().map(OrderBaseInfoDO::getId).collect(Collectors.toSet());
  84 + List<OrderInspectionStageDO> orderInspectionStageDOList = inspectionStageService.list(new LambdaQueryWrapper<OrderInspectionStageDO>()
  85 + .in(OrderInspectionStageDO::getOrderId, orderIds));
  86 + List<OrderTrackStageDO> orderTrackStageDOList = trackStageService.list(new LambdaQueryWrapper<OrderTrackStageDO>()
  87 + .in(OrderTrackStageDO::getOrderId, orderIds));
  88 + List<OrderEventJobVO> jobVOList = transfer2OrderEventList(orderBaseInfoDOList, orderInspectionStageDOList, orderTrackStageDOList);
  89 + Map<String, List<OrderEventJobVO>> map = handlerOrderEvent(jobVOList);
  90 + for (Map.Entry<String, List<OrderEventJobVO>> entry : map.entrySet()) {
  91 + sendEmail4OrderEvent(OrderEventEnum.getEvent(entry.getKey()), entry.getValue());
  92 + }
88 93 }
  94 +
89 95 }
90 96  
91 97 /**
... ... @@ -94,28 +100,28 @@ public class OrderOverTimeEventJob {
94 100 */
95 101 //发送邮件。
96 102 private void sendEmail4OrderEvent(OrderEventEnum eventEnum, List<OrderEventJobVO> eventJobVOS) throws MessagingException, TemplateException, IOException {
97   - HashSet<String> strings = new HashSet<>();
  103 + List<ReceiveEmailMappingDO> allMappings = receiveEmailMappingService.list();
  104 + //存储 customerCode
  105 + Set<String> customerCodes = new HashSet<>();
  106 + // 遍历 eventJobVOS,添加不在 Redis 中的 customerCode
98 107 for (OrderEventJobVO orderEventJob : eventJobVOS) {
99   - if (!redisUtils.hasKey(EmailTemplateEnum.byTemplate(
100   - eventEnum.getTemplateId()) + Constant.POINT_BAR_CHARACTER + orderEventJob.getBaseInfo().getId())){
101   - strings.add(orderEventJob.getBaseInfo().getCustomerCode());
  108 + String cacheKey = EmailTemplateEnum.byTemplate(eventEnum.getTemplateId())
  109 + + Constant.CROSS_BAR_CHARACTER
  110 + + orderEventJob.getBaseInfo().getId();
  111 + if (!redisUtils.hasKey(cacheKey)) {
  112 + customerCodes.add(orderEventJob.getBaseInfo().getCustomerCode());
102 113 }
103 114 }
104   - LambdaQueryWrapper<ReceiveEmailMappingDO> queryWrapper = new LambdaQueryWrapper<>();
105   - queryWrapper.eq(ReceiveEmailMappingDO::getEnableFlag, Constant.ENABLE_TEN);
106   - if (strings == null || strings.isEmpty()) {
107   - queryWrapper.eq(ReceiveEmailMappingDO::getTypeValue, " ");
108   - } else {
109   - queryWrapper.in(ReceiveEmailMappingDO::getTypeValue, strings);
110   - }
111   - queryWrapper.apply("JSON_CONTAINS(JSON_EXTRACT(config_infos, '$[*].event'), JSON_QUOTE({0}), '$')", eventEnum.getEvent());
112   - List<ReceiveEmailMappingDO> receiveEmailMappingDOList = receiveEmailMappingService.list(queryWrapper);
113 115  
114   - /* List<ReceiveEmailMappingDO> receiveEmailMappingDOList = receiveEmailMappingService.list(
115   - new LambdaQueryWrapper<ReceiveEmailMappingDO>()
116   - .eq(ReceiveEmailMappingDO::getEnableFlag, Constant.ENABLE_TEN)
117   - .in(CollectionUtils.isNotEmpty(strings),ReceiveEmailMappingDO::getTypeValue, strings)
118   - .apply("JSON_CONTAINS(JSON_EXTRACT(config_infos, '$[*].event'), JSON_QUOTE({0}), '$')", eventEnum.getEvent()));*/
  116 + // 过滤 ReceiveEmailMappingDO
  117 + List<ReceiveEmailMappingDO> receiveEmailMappingDOList = allMappings.stream()
  118 + .filter(mapping -> customerCodes.isEmpty() || customerCodes.contains(mapping.getTypeValue()))
  119 + .filter(mapping -> {
  120 + // 检查 config_infos 是否包含 eventEnum.getEvent()
  121 + String configInfos = mapping.getConfigInfos();
  122 + return configInfos != null && configInfos.contains(eventEnum.getEvent());
  123 + })
  124 + .collect(Collectors.toList());
119 125  
120 126 Set<Map<String, List<String>>> set = receiveEmailMappingDOList.stream().map(x -> {
121 127 Map<String, List<String>> map = new HashMap<>();
... ... @@ -138,11 +144,10 @@ public class OrderOverTimeEventJob {
138 144 emailSendUtils.sendEmail(EmailTemplateEnum.byTemplate(eventEnum.getTemplateId()),
139 145 map.get(map.keySet().iterator().next()), orderEventJob);
140 146 redisUtils.set(EmailTemplateEnum.byTemplate(
141   - eventEnum.getTemplateId()) + Constant.POINT_BAR_CHARACTER + orderEventJob.getBaseInfo().getId(),
  147 + eventEnum.getTemplateId()) + Constant.CROSS_BAR_CHARACTER + orderEventJob.getBaseInfo().getId(),
142 148 orderEventJob);
143 149 }
144 150 }
145   -
146 151 }
147 152 }
148 153  
... ... @@ -159,8 +164,7 @@ public class OrderOverTimeEventJob {
159 164 Map<Long, OrderTrackStageDO> OrderTrackStageMap = orderTrackStageList.stream().collect(Collectors.toMap(OrderTrackStageDO::getOrderId, Function.identity(), (x, y) -> x));
160 165 List<OrderEventJobVO> orderEventJobVOList = orderBaseInfoList.stream().map(x -> {
161 166 OrderEventJobVO orderEventJobVO = new OrderEventJobVO();
162   - if (x.getId() == OrderInspectionStageMap.get(x.getId()).getOrderId() &&
163   - x.getId() == OrderTrackStageMap.get(x.getId()).getOrderId()) {
  167 + if (OrderInspectionStageMap.containsKey(x.getId()) && OrderTrackStageMap.containsKey(x.getId())) {
164 168 OrderBaseInfoVO orderBaseInfoVO = new OrderBaseInfoVO();
165 169 OrderTrackStageVO orderTrackStageVO = new OrderTrackStageVO();
166 170 OrderInspectionStageVO orderInspectionStageVO = new OrderInspectionStageVO();
... ... @@ -171,8 +175,10 @@ public class OrderOverTimeEventJob {
171 175 orderEventJobVO.setInspectionStageInfo(orderInspectionStageVO);
172 176 orderEventJobVO.setBaseInfo(orderBaseInfoVO);
173 177 orderEventJobVO.setTrackStageInfo(orderTrackStageVO);
  178 + return orderEventJobVO;
  179 + }else{
  180 + return null;
174 181 }
175   - return orderEventJobVO;
176 182 }).filter(Objects::nonNull)
177 183 .collect(Collectors.toList());
178 184 return orderEventJobVOList;
... ... @@ -248,13 +254,15 @@ public class OrderOverTimeEventJob {
248 254 if (!ppConfirmResult.contains("ok") && org.apache.commons.lang3.StringUtils.countMatches(ppConfirmResult, "fail") == 3) {
249 255 return true;
250 256 } else if (ppConfirmResult.contains("ok") || org.apache.commons.lang3.StringUtils.countMatches(ppConfirmResult, "fail") < 3) {
251   - String[] parats = ppConfirmResult.split("\\+");
252   - String lastTime = parats[parats.length - 3];
253   - LocalDate parse1 = LocalDate.parse(lastTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
254   - LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
  257 + LocalDate parse1 = findLatestDateBeforeOk(ppConfirmResult);
  258 + //把订单中的Hod时间yyyy-mm-dd HH:mm:ss改成yyyy-mm-dd。
  259 + String[] hodTime = orderHodTime.split(" ");
  260 + String orderhodTime = hodTime[0];
  261 + LocalDate parse2 = DateUtils.parseDate(orderhodTime, dateFormatDay);
255 262 long daysBetween = ChronoUnit.DAYS.between(parse1, parse2);
256 263 if (daysBetween == 21) {
257 264 return true;
  265 +
258 266 }
259 267 }
260 268 }
... ... @@ -265,8 +273,13 @@ public class OrderOverTimeEventJob {
265 273 String orderHodTime = eventJobVO.getBaseInfo().getOrderHodTime();
266 274 String esoSampleSendTime = eventJobVO.getTrackStageInfo().getEsoSampleSendTime();
267 275 if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(esoSampleSendTime)) {
268   - LocalDate parse1 = LocalDate.parse(esoSampleSendTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
269   - LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
  276 + //把订单中的Hod时间yyyy-mm-dd HH:mm:ss改成yyyy-mm-dd。
  277 + String[] hodTime = orderHodTime.split(" ");
  278 + String orderhodTime = hodTime[0];
  279 + LocalDate parse2 = DateUtils.parseDate(orderhodTime, dateFormatDay);
  280 + LocalDateTime dateTime=LocalDateTime.parse(esoSampleSendTime, DateTimeFormatter.ofPattern(dateFormatSEC));
  281 + String parse=dateTime.format(DateTimeFormatter.ofPattern(dateFormatDay));
  282 + LocalDate parse1=DateUtils.parseDate(parse,dateFormatDay);
270 283 if (ChronoUnit.DAYS.between(parse1, parse2) == 7) {
271 284 return true;
272 285 }
... ... @@ -281,10 +294,11 @@ public class OrderOverTimeEventJob {
281 294 if (!shippmentSampleConfirmResult.contains("ok") && org.apache.commons.lang3.StringUtils.countMatches(shippmentSampleConfirmResult, "fail") == 3) {
282 295 return true;
283 296 } else if (shippmentSampleConfirmResult.contains("ok") || org.apache.commons.lang3.StringUtils.countMatches(shippmentSampleConfirmResult, "fail") < 3) {
284   - String[] parats = shippmentSampleConfirmResult.split("\\+");
285   - String lastTime = parats[parats.length - 3];
286   - LocalDate parse1 = LocalDate.parse(lastTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
287   - LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
  297 + //把订单中的Hod时间yyyy-mm-dd HH:mm:ss改成yyyy-mm-dd。
  298 + String[] hodTime = orderHodTime.split(" ");
  299 + String orderhodTime = hodTime[0];
  300 + LocalDate parse2 = DateUtils.parseDate(orderhodTime, dateFormatDay);
  301 + LocalDate parse1 = findLatestDateBeforeOk(shippmentSampleConfirmResult);
288 302 long daysBetween = ChronoUnit.DAYS.between(parse1, parse2);
289 303 if (daysBetween == 7) {
290 304 return true;
... ... @@ -306,13 +320,11 @@ public class OrderOverTimeEventJob {
306 320 return true;
307 321 } else if ((shippmentSampleConfirmResult.contains("ok") || org.apache.commons.lang3.StringUtils.countMatches(shippmentSampleConfirmResult, "fail") < 3) ||
308 322 (sgsTestFinishResult.contains("ok") || org.apache.commons.lang3.StringUtils.countMatches(sgsTestFinishResult, "fail") < 3)) {
309   - String[] parats = shippmentSampleConfirmResult.split("\\+");
310   - String lastTime = parats[parats.length - 3];
311   - String[] parats1 = sgsTestFinishResult.split("\\+");
312   - String lastTime1 = parats1[parats1.length - 3];
313   - LocalDate parse1 = LocalDate.parse(lastTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
314   - LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
315   - LocalDate parse3 = LocalDate.parse(lastTime1, DateTimeFormatter.ofPattern("yyyy-M-d"));
  323 + String[] hodTime = orderHodTime.split(" ");
  324 + String orderhodTime=hodTime[0];
  325 + LocalDate parse1 = findLatestDateBeforeOk(shippmentSampleConfirmResult);
  326 + LocalDate parse2 = DateUtils.parseDate(orderhodTime, dateFormatDay);
  327 + LocalDate parse3 = findLatestDateBeforeOk(sgsTestFinishResult);
316 328 long daysBetween = ChronoUnit.DAYS.between(parse1, parse2);
317 329 long daysBetween1 = ChronoUnit.DAYS.between(parse3, parse2);
318 330 if (daysBetween == 3 || daysBetween1 == 3) {
... ... @@ -328,8 +340,12 @@ public class OrderOverTimeEventJob {
328 340 String orderHodTime = eventJobVO.getBaseInfo().getOrderHodTime();
329 341 String lastArrivalTime = eventJobVO.getTrackStageInfo().getLatestArrivalTime();
330 342 if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(lastArrivalTime)) {
331   - LocalDate parse1 = LocalDate.parse(lastArrivalTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
332   - LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
  343 + String[] hodTime = orderHodTime.split(" ");
  344 + String orderhodTime=hodTime[0];
  345 + LocalDate parse2 = DateUtils.parseDate(orderhodTime, dateFormatDay);
  346 + LocalDateTime dateTime=LocalDateTime.parse(lastArrivalTime, DateTimeFormatter.ofPattern(dateFormatSEC));
  347 + String parse=dateTime.format(DateTimeFormatter.ofPattern(dateFormatDay));
  348 + LocalDate parse1=DateUtils.parseDate(parse,dateFormatDay);
333 349 if (ChronoUnit.DAYS.between(parse1, parse2) == 7) {
334 350 return true;
335 351 }
... ... @@ -341,8 +357,12 @@ public class OrderOverTimeEventJob {
341 357 String orderHodTime = eventJobVO.getBaseInfo().getOrderHodTime();
342 358 String latestBkTime = eventJobVO.getTrackStageInfo().getLatestBkTime();
343 359 if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(latestBkTime)) {
344   - LocalDate parse1 = LocalDate.parse(latestBkTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
345   - LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
  360 + String[] hodTime = orderHodTime.split(" ");
  361 + String orderhodTime=hodTime[0];
  362 + LocalDate parse2 = DateUtils.parseDate(orderhodTime, dateFormatDay);
  363 + LocalDateTime dateTime=LocalDateTime.parse(latestBkTime, DateTimeFormatter.ofPattern(dateFormatSEC));
  364 + String parse=dateTime.format(DateTimeFormatter.ofPattern(dateFormatDay));
  365 + LocalDate parse1=DateUtils.parseDate(parse,dateFormatDay);
346 366 if (ChronoUnit.DAYS.between(parse1, parse2) == 10) {
347 367 return true;
348 368 }
... ... @@ -354,12 +374,39 @@ public class OrderOverTimeEventJob {
354 374 String orderHodTime = eventJobVO.getBaseInfo().getOrderHodTime();
355 375 String endCheckApplyTime = eventJobVO.getInspectionStageInfo().getEndCheckApplyTime();
356 376 if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(endCheckApplyTime)) {
357   - LocalDate parse1 = LocalDate.parse(endCheckApplyTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
358   - LocalDate parse2 = LocalDate.parse(orderHodTime, DateTimeFormatter.ofPattern("yyyy-M-d"));
  377 + String[] hodTime = orderHodTime.split(" ");
  378 + String orderhodTime=hodTime[0];
  379 + LocalDate parse2 = DateUtils.parseDate(orderhodTime, dateFormatDay);
  380 + LocalDateTime dateTime=LocalDateTime.parse(endCheckApplyTime, DateTimeFormatter.ofPattern(dateFormatSEC));
  381 + String parse=dateTime.format(DateTimeFormatter.ofPattern(dateFormatDay));
  382 + LocalDate parse1=DateUtils.parseDate(parse,dateFormatDay);
359 383 if (ChronoUnit.DAYS.between(parse1, parse2) == 2) {
360 384 return true;
361 385 }
362 386 }
363 387 return false;
364 388 }
  389 +
  390 + public LocalDate findLatestDateBeforeOk(String data){
  391 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormatSEC);
  392 + LocalDateTime latestDateBeforeOk = null;
  393 + // 正则表达式提取日期和状态
  394 + Pattern pattern = Pattern.compile("(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2})\\s+(.*?)(?=\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}|$)");
  395 + Matcher matcher = pattern.matcher(data);
  396 + while (matcher.find()) {
  397 + LocalDateTime eventDate = LocalDateTime.parse(matcher.group(1), formatter);
  398 + String status = matcher.group(2);
  399 + // 查找 "ok" 的位置
  400 + int okIndex = data.indexOf("ok");
  401 + if (okIndex != -1 && matcher.start() < okIndex) {
  402 + // 更新 latestDateBeforeOk 为当前事件的日期,如果当前日期晚于已知的日期
  403 + if (latestDateBeforeOk == null || eventDate.isAfter(latestDateBeforeOk)) {
  404 + latestDateBeforeOk = eventDate;
  405 + }
  406 + }
  407 + }
  408 + // 转换为 LocalDate,去掉时分秒
  409 + return (latestDateBeforeOk != null) ? latestDateBeforeOk.toLocalDate() : null;
  410 + }
  411 +
365 412 }
... ...