OrderJob.java 22 KB
package com.order.erp.job;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.order.erp.common.constant.Constant;
import com.order.erp.common.utils.DateUtils;
import com.order.erp.common.utils.StringUtils;
import com.order.erp.common.utils.TransactionHelper;
import com.order.erp.domain.ApplyStatusEnum;
import com.order.erp.domain.OrderStatusEnum;
import com.order.erp.domain.dto.BaseDO;
import com.order.erp.domain.dto.order.*;
import com.order.erp.domain.vo.order.OrderInfoResultVO;
import com.order.erp.mapper.order.OrderBaseInfoMapper;
import com.order.erp.service.order.*;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: xms
 * @description: TODO
 * @date: 2023/6/25 10:35
 * @version: 1.0
 */
@Slf4j
@Component
public class OrderJob {

    @Resource
    private OrderBaseInfoService orderBaseInfoService;

    @Resource
    private OrderProfitAnalysisService profitAnalysisService;

    @Resource
    private OrderCompletionReportService reportService;

    @Resource
    private OrderTrackStageService trackStageService;

    @Resource
    private OrderInspectionStageService inspectionStageService;

    @Resource
    private TransactionHelper transactionHelper;

    /**
     * 每隔5分执行一次
     */
    @Scheduled(cron = "0 */10 * * * ?")
//    @Scheduled(cron = "*/5 * * * * ?")
    public void checkCompleteExecute() {
        log.info("执行开始时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
        LambdaQueryWrapper<OrderBaseInfoDO> queryWrapper = new LambdaQueryWrapper<OrderBaseInfoDO>()
                .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
                .ge(OrderBaseInfoDO::getCreateTime, DateUtils.format(DateTime.now().minusMonths(Constant.ONE).toDate(), DateUtils.DATE_TIME))
                .le(OrderBaseInfoDO::getCreateTime, DateUtils.format(DateTime.now().toDate(), DateUtils.DATE_TIME))
                .ne(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
        List<OrderBaseInfoDO> ordersDOS = orderBaseInfoService.list(queryWrapper);
        List<OrderInfoResultVO> orderInfoResultVOS = orderBaseInfoService.wrapperOrderResultList(false, ordersDOS);
        //遍历一下这个集合的数据,如果尾期尾期验货结果为PASS,pass 2ND,PASS 3ND,FAIL RELEASE就为订单完成。
        Set<String> validResults = new HashSet<>(Arrays.asList("PASS", "PASS 2ND", "PASS 3RD", "FAIL RELEASE"));
        //没有进行innerNo与customerCode联合排查。
        List<OrderInfoResultVO> filteredOrders = orderInfoResultVOS.stream()
                .filter(order -> order.getInspectionStageInfo() != null &&
                        validResults.contains(order.getInspectionStageInfo().getEndCheckResult()))
                .collect(Collectors.toList());
        //获取订单的innerNo和customerCode。
        Set<String> uniqueCombination = filteredOrders.stream().map(order -> order.getProjectNo() + "-" + order.getInnerNo()).collect(Collectors.toSet());

        List<OrderInfoResultVO> finishStatusOrderBaseInfoResultVO = orderInfoResultVOS.stream().filter(order -> {
            String combination = order.getProjectNo() + "-" + order.getInnerNo();
            return uniqueCombination.contains(combination);
        }).collect(Collectors.toList());
        Set<Long> finishStatusOrderIds = finishStatusOrderBaseInfoResultVO.stream().map(order -> order.getId()).collect(Collectors.toSet());
        if (CollectionUtils.isNotEmpty(finishStatusOrderIds)) {
            //不再使用上述的方式,而是采用内部编号与项目编号进行排查。
            if (CollectionUtils.isNotEmpty(finishStatusOrderIds)) {
                LambdaUpdateWrapper<OrderBaseInfoDO> orderBaseUpdateWrapper = new LambdaUpdateWrapper<OrderBaseInfoDO>()
                        .in(OrderBaseInfoDO::getId, finishStatusOrderIds).set(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());

                LambdaUpdateWrapper<OrderCompletionReportDO> reportUpdateWrapper = new LambdaUpdateWrapper<OrderCompletionReportDO>()
                        .in(OrderCompletionReportDO::getOrderId, finishStatusOrderIds).set(OrderCompletionReportDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());

                LambdaUpdateWrapper<OrderProfitAnalysisDO> profitUpdateWrapper = new LambdaUpdateWrapper<OrderProfitAnalysisDO>()
                        .in(OrderProfitAnalysisDO::getOrderId, finishStatusOrderIds).set(OrderProfitAnalysisDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());

                LambdaUpdateWrapper<OrderTrackStageDO> trackUpdateWrapper = new LambdaUpdateWrapper<OrderTrackStageDO>()
                        .in(OrderTrackStageDO::getOrderId, finishStatusOrderIds).set(OrderTrackStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());

                LambdaUpdateWrapper<OrderInspectionStageDO> inspectUpdateWrapper = new LambdaUpdateWrapper<OrderInspectionStageDO>()
                        .in(OrderInspectionStageDO::getOrderId, finishStatusOrderIds).set(OrderInspectionStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());

                transactionHelper.run(() -> {
                    orderBaseInfoService.update(orderBaseUpdateWrapper);
                    reportService.update(reportUpdateWrapper);
                    profitAnalysisService.update(profitUpdateWrapper);
                    trackStageService.update(trackUpdateWrapper);
                    inspectionStageService.update(inspectUpdateWrapper);
                });
            }
        }
        log.info("执行结束时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * 每隔5分执行一次
     */

//    @Scheduled(cron = "*/5 * * * * ?")
    public void checkChargeOrderCount() {
        log.info("执行开始时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
//        orderBaseInfoService.checkChargeOrderCount(null);
        log.info("执行结束时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
    }


    //  以下两个定时任务都是一次性的。

    //写一个扫描全部订单。只要有一栏填写了数据,就相当于完成了。 只扫描一次。             每五分钟扫描一次,只要有一栏填写了数据,就相当于完成了。    在填充接口中,设置只要填充了一栏就算上订单完成。

//    @Scheduled(cron = "0 3 3 4 1 ?", zone = "Asia/Shanghai")
    //这里扫描全部未完成的订单。重新设置订单完成的状态。
    public void checkFinish() {
        log.info("执行开始时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
        LambdaQueryWrapper<OrderBaseInfoDO> queryWrapper = new LambdaQueryWrapper<OrderBaseInfoDO>()
                .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
                .ne(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
        List<OrderBaseInfoDO> ordersDOS = orderBaseInfoService.list(queryWrapper);

        List<OrderInfoResultVO> orderInfoResultVOS = orderBaseInfoService.wrapperOrderResultList(false, ordersDOS);
        if (CollectionUtils.isNotEmpty(orderInfoResultVOS)) {
            //这里设置为>=的目的是,填充五个的话,就为5,填充4的的话就为4,除4,要么为1要么为1.25。这种情况都算订单完成。
            Set<Long> orderIds = orderInfoResultVOS.stream().filter(x -> Objects.nonNull(x.getSchedule()) && Constant.ONE <= x.getSchedule()).map(OrderInfoResultVO::getId).collect(Collectors.toSet());
            if (CollectionUtils.isNotEmpty(orderIds)) {
                LambdaUpdateWrapper<OrderBaseInfoDO> orderBaseUpdateWrapper = new LambdaUpdateWrapper<OrderBaseInfoDO>()
                        .in(OrderBaseInfoDO::getId, orderIds).set(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());

                LambdaUpdateWrapper<OrderCompletionReportDO> reportUpdateWrapper = new LambdaUpdateWrapper<OrderCompletionReportDO>()
                        .in(OrderCompletionReportDO::getOrderId, orderIds).set(OrderCompletionReportDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());

                LambdaUpdateWrapper<OrderProfitAnalysisDO> profitUpdateWrapper = new LambdaUpdateWrapper<OrderProfitAnalysisDO>()
                        .in(OrderProfitAnalysisDO::getOrderId, orderIds).set(OrderProfitAnalysisDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());

                LambdaUpdateWrapper<OrderTrackStageDO> trackUpdateWrapper = new LambdaUpdateWrapper<OrderTrackStageDO>()
                        .in(OrderTrackStageDO::getOrderId, orderIds).set(OrderTrackStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());

                LambdaUpdateWrapper<OrderInspectionStageDO> inspectUpdateWrapper = new LambdaUpdateWrapper<OrderInspectionStageDO>()
                        .in(OrderInspectionStageDO::getOrderId, orderIds).set(OrderInspectionStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());

                transactionHelper.run(() -> {
                    orderBaseInfoService.update(orderBaseUpdateWrapper);
                    reportService.update(reportUpdateWrapper);
                    profitAnalysisService.update(profitUpdateWrapper);
                    trackStageService.update(trackUpdateWrapper);
                    inspectionStageService.update(inspectUpdateWrapper);
                });
            }
        }
        log.info("执行结束时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
    }


    //处理跟单和质检中的状态。

//    @Scheduled(cron = "0 3 4 4 1 ?", zone = "Asia/Shanghai")
    public void checkTrackInfoAndInspectionInfoStatus() {
        log.info("执行开始时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
        List<OrderTrackStageDO> orderTrackStageDOS = trackStageService.list(new LambdaQueryWrapper<OrderTrackStageDO>().eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN).ne(OrderTrackStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus()));
        List<OrderInspectionStageDO> orderInspectionStageDOS = inspectionStageService.list(new LambdaQueryWrapper<OrderInspectionStageDO>().eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN).ne(OrderInspectionStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus()));
        Set<Long> trackOrderIds = orderTrackStageDOS.stream()
                .map(OrderTrackStageDO::getOrderId)
                .filter(orderId -> orderId != null)  // 防止 orderId 为空
                .collect(Collectors.toSet());

        Set<Long> inspectionOrderIds = orderInspectionStageDOS.stream()
                .map(OrderInspectionStageDO::getOrderId)
                .filter(orderId -> orderId != null)  // 防止 orderId 为空
                .collect(Collectors.toSet());
//得到交集。
        Set<Long> commonOrderIds = trackOrderIds.stream()
                .filter(inspectionOrderIds::contains)
                .collect(Collectors.toSet());

        Map<Long,OrderTrackStageDO> orderTrackStageMap = orderTrackStageDOS.stream()
                .filter(order -> order.getOrderId() != null)
                .collect(Collectors.toMap(
                        OrderTrackStageDO::getOrderId,
                        order-> order,
                        (existing, replacement) -> existing // 处理 key 冲突时,保留现有值
                ));

        Map<Long, OrderInspectionStageDO> orderInspectionStageMap = orderInspectionStageDOS.stream()
                .filter(order -> order.getOrderId() != null)
                .collect(Collectors.toMap(
                        OrderInspectionStageDO::getOrderId,
                        order ->order,
                        (existing, replacement) -> existing // 处理 key 冲突时,保留现有值
                ));
        List<OrderInspectionStageDO> orderInspectionList = commonOrderIds.stream().map(order -> {
            OrderInspectionStageDO inspectionStageDO = orderInspectionStageMap.get(order);
            OrderTrackStageDO trackStageDO = orderTrackStageMap.get(order);
            if (Objects.nonNull(inspectionStageDO) && Objects.nonNull(trackStageDO)) {
                Integer trackStageDOOrderStatus = trackStageDO.getOrderStatus();
                Integer inspectionStageDOOrderStatus = inspectionStageDO.getOrderStatus();
                if (Objects.nonNull(trackStageDOOrderStatus) && Objects.nonNull(inspectionStageDOOrderStatus)
                        && OrderStatusEnum.TRACK_ING.getStatus().equals(trackStageDOOrderStatus)
                        && OrderStatusEnum.INSPECT_ING.getStatus().equals(inspectionStageDOOrderStatus)) {
                    //由于跟单和质检,一个订单你操作了跟单或者质检后,然后在操作一次质检或者跟单,在首页统计中跟单和质检就会计算两次,相当于多计算了一次,重复了。所以这里需要去重。
                    inspectionStageDO.setOrderStatus(OrderStatusEnum.INSPECT_PASS.getStatus());
                    return inspectionStageDO;
                }
            }
            return null;
        }).filter(Objects::nonNull).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(orderInspectionList)){
            inspectionStageService.updateBatchById(orderInspectionList);
        }
        log.info("执行结束时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
    }


//重新扫描一遍,扫描规则为:不扫描所有表,只扫描25年的数据,如果尾期验货为PASS,PASS 2DN,PASS 3ND,或者为FAIL RELEASE,那么它就设置为订单完成状态。并且,如果这个订单设置为订单完成状态。去看看这些订单是否存在相同的
    //project_no和inner_no,如果存在就进行也设置为订单完成。





    //这里需要改成某个时间段只执行一次。
//@Scheduled(cron = "0 */5 * * * ?")
public void orderStatusFinishCheck() {
        LocalDate localDate = LocalDate.of(2023, 10, 1);
        //查询2023年末之后的基础订单订单。
        List<OrderBaseInfoDO> orderBaseInfoDOS = orderBaseInfoService.list(new LambdaQueryWrapper<OrderBaseInfoDO>().eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
                .ge(OrderBaseInfoDO::getCreateTime, localDate));
        List<Long> orderIds = orderBaseInfoDOS.stream().map(orderBaseInfoDO -> orderBaseInfoDO.getId()).collect(Collectors.toList());
        //先把状态设置为跟单中。(因为现在很多虚假的订单完成状态,所以现在把这些订单设置为跟单中,然后重新扫描过滤。)
        orderBaseInfoDOS.forEach(orderBaseInfoDO ->
                orderBaseInfoDO.setOrderStatus(OrderStatusEnum.TRACK_ING.getStatus()));
        orderBaseInfoService.updateBatchById(orderBaseInfoDOS);


       //查询质检信息。
        List<OrderInspectionStageDO> inspectionStageDOList = inspectionStageService.list(new LambdaQueryWrapper<OrderInspectionStageDO>().eq(BaseDO::getEnableFlag,Constant.ENABLE_TEN).in(OrderInspectionStageDO::getOrderId,orderIds));

        Set<String> validResults = new HashSet<>(Arrays.asList("PASS", "PASS 2ND", "PASS 3RD", "FAIL RELEASE"));

        List<OrderInspectionStageDO> filteredList = inspectionStageDOList.stream()
                .filter(order -> order.getEndCheckResult() != null && validResults.contains(order.getEndCheckResult()))
                .collect(Collectors.toList());
        List<OrderBaseInfoDO> orderBaseInfoDOList = orderBaseInfoService.listByIds(filteredList.stream().map(OrderInspectionStageDO::getOrderId).collect(Collectors.toList()));

        Set<String> uniqueCombinations=orderBaseInfoDOList.stream().map(order -> order.getProjectNo()+"-"+order.getInnerNo()).collect(Collectors.toSet());

        List<OrderBaseInfoDO> finishStatusOrderBaseinfoList = orderBaseInfoDOS.stream().filter(order -> {
                    String combination = order.getProjectNo() + "-" + order.getInnerNo();
                    return uniqueCombinations.contains(combination);
                })
                .collect(Collectors.toList());
        finishStatusOrderBaseinfoList.forEach(orderBaseInfoDO -> orderBaseInfoDO.setOrderStatus(OrderStatusEnum.ORDER_FINISH.getStatus()));
        orderBaseInfoService.updateBatchById(finishStatusOrderBaseinfoList);
   }

   //查询一下所有的信息,对于质检信息中尾期验货为PASS,PASS 2ND,PASS 3RD,或者为FAIL RELEASE,那么它就设置为订单完成状态,设置为订单完成之后,再去查看已经为订单完成的订单,对于相同的innerNo和customerCode就也进行设置为质检信息。
   //模仿上面的每十分钟扫描一次的方法,找到这些订单后,还需要对这些订单的跟单,质检等也设置为订单完成状态。
//   @Scheduled(cron = "0 0 4 16 4 ?", zone = "Asia/Shanghai")
   public void checkChargeOrderCount1() {
        List<OrderBaseInfoDO> orderBaseInfoDOS = orderBaseInfoService.list(new LambdaQueryWrapper<OrderBaseInfoDO>().eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN).ne(OrderBaseInfoDO::getOrderStatus,OrderStatusEnum.ORDER_FINISH.getStatus()));
        //转化为map集合。
        Map<Long, OrderBaseInfoDO> orderBaseInfoDOMap = orderBaseInfoDOS.stream().collect(Collectors.toMap(OrderBaseInfoDO::getId,OrderBaseInfoDO -> OrderBaseInfoDO,(existing,replacement) -> existing));
        List<Long> orderIds = orderBaseInfoDOS.stream().map(orderBaseInfoDO -> orderBaseInfoDO.getId()).collect(Collectors.toList());

        List<OrderInspectionStageDO> inspectionStageDOList = inspectionStageService.list(new LambdaQueryWrapper<OrderInspectionStageDO>().eq(BaseDO::getEnableFlag,Constant.ENABLE_TEN).in(OrderInspectionStageDO::getOrderId,orderIds));
        //转化为map集合。
        Map<Long, OrderInspectionStageDO> inspectionStageDOMap = inspectionStageDOList.stream().collect(Collectors.toMap(OrderInspectionStageDO::getOrderId,OrderInspectionStageDO -> OrderInspectionStageDO,(existing,replacement) -> existing));
        //获取所有尾期验货为PASS,PASS 2ND,PASS 3RD,或者为FAIL RELEASE的订单。返回的订单代表订单通过。
        List<Long> finishOrderIdList = inspectionStageDOList.stream()
                .filter(orderInspectionStageDO ->
                        Objects.nonNull(orderInspectionStageDO) &&
                                StringUtils.isNotBlank(orderInspectionStageDO.getEndCheckResult()) &&
                                (orderInspectionStageDO.getEndCheckResult().equals("PASS") ||
                                        orderInspectionStageDO.getEndCheckResult().equals("PASS 2ND") ||
                                        orderInspectionStageDO.getEndCheckResult().equals("PASS 3RD") ||
                                        orderInspectionStageDO.getEndCheckResult().equals("FAIL RELEASE"))
                )
                .map(orderInspectionStageDO -> orderInspectionStageDO.getOrderId())
                .filter(Objects::nonNull) // 确保 orderId 不为 null
                .collect(Collectors.toList());

        Map<Long, OrderBaseInfoDO> finishOrderBaseInfoMap = orderBaseInfoDOMap.entrySet().stream()
                .filter(entry -> finishOrderIdList.contains(entry.getKey()))
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue
                ));
        //取出map中的value。    这些都为订单完成的。
        List<OrderBaseInfoDO> finishOrderBaseInfoList = finishOrderBaseInfoMap.values().stream().collect(Collectors.toList());
        //获取相同的innerNo和CustomerCode。
        Set<String> uniqueCombinations=finishOrderBaseInfoList.stream().map(order -> order.getProjectNo()+"-"+order.getInnerNo()).collect(Collectors.toSet());

        List<OrderBaseInfoDO> finishStatusOrderBaseinfoList = orderBaseInfoDOS.stream().filter(order -> {
                    String combination = order.getProjectNo() + "-" + order.getInnerNo();
                    return uniqueCombinations.contains(combination);
                })
                .collect(Collectors.toList());
        finishStatusOrderBaseinfoList.forEach(orderBaseInfoDO -> orderBaseInfoDO.setOrderStatus(OrderStatusEnum.ORDER_FINISH.getStatus()));
        List<Long> allFinishOrderIdList = finishStatusOrderBaseinfoList.stream().map(orderBaseInfoDO -> orderBaseInfoDO.getId()).collect(Collectors.toList());
        //保存

        //对于质检和跟单也进行设置状态为订单完成。
        Map<Long, OrderInspectionStageDO> allFinishInspectMap = inspectionStageDOMap.entrySet().stream()
                .filter(entry -> allFinishOrderIdList.contains(entry.getKey()))
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue
                ));
        List<OrderInspectionStageDO> allInspectionStageDOList = allFinishInspectMap.values().stream().collect(Collectors.toList());
        LambdaUpdateWrapper<OrderTrackStageDO> trackUpdateWrapper = new LambdaUpdateWrapper<OrderTrackStageDO>().in(OrderTrackStageDO::getOrderId, allFinishOrderIdList).set(OrderTrackStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
        LambdaUpdateWrapper<OrderCompletionReportDO> reportUpdateWrapper = new LambdaUpdateWrapper<OrderCompletionReportDO>().in(OrderCompletionReportDO::getOrderId, allFinishOrderIdList).set(OrderCompletionReportDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
        LambdaUpdateWrapper<OrderProfitAnalysisDO> profitUpdateWrapper = new LambdaUpdateWrapper<OrderProfitAnalysisDO>().in(OrderProfitAnalysisDO::getOrderId, allFinishOrderIdList).set(OrderProfitAnalysisDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());

        transactionHelper.run(() ->{
            trackStageService.update(trackUpdateWrapper);
            reportService.update(reportUpdateWrapper);
            profitAnalysisService.update(profitUpdateWrapper);
            inspectionStageService.updateBatchById(allInspectionStageDOList);
            orderBaseInfoService.updateBatchById(finishStatusOrderBaseinfoList);
        });
    }
}