zhanghl
2025-04-29 ec8cf418f6dc3958aa7b5f524a7bf8f6edf62e07
aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java
@@ -1,5 +1,6 @@
package com.aps.core.service.impl;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSONObject;
import com.aps.common.core.utils.DateUtils;
import com.aps.common.core.utils.uuid.IdUtils;
@@ -22,6 +23,7 @@
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
@@ -519,4 +521,201 @@
        return yearMonths;
    }
    @Override
    public void saveGasPipingProcessStat(){
        try {
            String batchNum = IdUtils.fastSimpleUUID();
            List<ApsGasPipingRouteStat> tempList = apsGasPipingRouteStatMapper.queryTempStat();
            Map<String, List<ApsGasPipingRouteStat>> groupByOrderNo = tempList.stream().collect(groupingBy(ApsGasPipingRouteStat::getWorkOrderNo));
            Boolean hasBefore = false;
            LocalDateTime now = LocalDateTime.now();
            for (Map.Entry<String, List<ApsGasPipingRouteStat>> entry : groupByOrderNo.entrySet()) {
                List<ApsGasPipingRouteStat> statPerOrder = entry.getValue();
                /*num 为根据完工时间排序出的序号,按此排序,可保证是按完工时间倒叙排列*/
                statPerOrder.sort((a, b)->a.getNum().compareTo(b.getNum()));
                ApsGasPipingRouteStat last=null;
                for (int i = 0; i <statPerOrder.size(); i++) {
                    ApsGasPipingRouteStat stat = statPerOrder.get(i);
                    stat.setId(IdUtils.fastSimpleUUID());
                    stat.setBatchNumber(batchNum);
                    stat.setCreateBy(SecurityUtils.getUsername());
                    stat.setWarning(false);
                    if(i==0){
                        Date orderPlanEndDay = stat.getOrderPlanEndDay();
                        LocalDateTime transLocalDateTime = transLocalDateTime(orderPlanEndDay);
                        LocalTime endOfDay = LocalTime.of(23, 59, 59);
                        LocalDateTime orderPlanEndDayLocalDateTime =  LocalDateTime.of( transLocalDateTime.toLocalDate(), endOfDay);
                        if(orderPlanEndDayLocalDateTime.isBefore(now)){
                            hasBefore = true;
                            stat.setWarning(true);
                            stat.setProcessPlanEndDay(transDate(now));
                            stat.setProcessPlanStartDay(transDate(now));
                        }else {
                            /*计划完工日=钣金计划工单完成时间*/
                            stat.setProcessPlanEndDay(transDate(orderPlanEndDayLocalDateTime));
                            /*计划开工日=钣金计划工单完成时间 -  工序总工时*/
                            long seconds = stat.getProcessTotalTime().multiply(new BigDecimal(60)).multiply(new BigDecimal(60)).longValue();
                            LocalDateTime lastPlanStartDt = orderPlanEndDayLocalDateTime.minusSeconds(seconds);
                            if(lastPlanStartDt.isBefore(now)){
                                hasBefore = true;
                                stat.setProcessPlanStartDay(transDate(now));
                            }else {
                                stat.setProcessPlanStartDay(transDate(lastPlanStartDt));
                            }
                        }
                    }
                    /*当工艺工序号 >= 工单当前工序 代表是未来工序,才进行计划开工日 和计划完工日的计算
                     * 当工艺工序号 < 工单当前工序  过去工序,不进行计算
                     * */
                    if( stat.getRouteProcessNumber().compareTo(stat.getCurrentProcessNumber())>=0){
                        /*倒排时 下一道工序存在 比当前时间小的计划时间,则当前计划开始和结束时间都是当前时间*/
                        if(hasBefore){
                            stat.setWarning(true);
                            stat.setProcessPlanEndDay(transDate(now));
                            stat.setProcessPlanStartDay(transDate(now));
                        }else{
                            /*下一道工序计划时间都正常时,*/
                            if (last != null) {
                                /*当前工序结束时间=下一道工序的开始时间*/
                                stat.setProcessPlanEndDay(last.getProcessPlanStartDay());
                                /*开始时间=结束时间-总工时*/
                                long seconds = stat.getProcessTotalTime().multiply(new BigDecimal(60)).multiply(new BigDecimal(60)).longValue();
                                LocalDateTime crtStartDt = transLocalDateTime(last.getProcessPlanStartDay()).minusSeconds(seconds);
                                /*如果开始时间小于当前时间*/
                                if(crtStartDt.isBefore(now)){
                                    hasBefore=true;
                                    stat.setWarning(true);
                                    stat.setProcessPlanStartDay(transDate(now));
                                }else {
                                    stat.setProcessPlanStartDay(transDate(crtStartDt));
                                }
                            }
                        }
                    }
                    last = stat;
                    apsGasPipingRouteStatMapper.insertApsGasPipingRouteStat(stat);
                }
                hasBefore=false;
            }
            apsGasPipingRouteStatMapper.deleteApsGasPipingRouteStatByBatchNum(batchNum);
        } catch (Exception e) {
            e.printStackTrace();
        }
    };
    private Date transDate(LocalDateTime localDateTime){
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }
    private LocalDateTime transLocalDateTime(Date date){
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }
    /**
     * 保存钣金统计数据
     */
    @Transactional
    @Override
    public void saveGasPipingRoutStateList() {
        String batchNum = IdUtils.fastSimpleUUID();
        List<ApsGasPipingRouteStat> tempList = apsGasPipingRouteStatMapper.queryTempStat();
        Map<String, List<ApsGasPipingRouteStat>> groupByOrderNo = tempList.stream().collect(groupingBy(ApsGasPipingRouteStat::getWorkOrderNo));
        LocalDateTime now = LocalDateTime.now();
        /*待保存的数据*/
        List<ApsGasPipingRouteStat> cptStateList = new ArrayList<>();
        for (Map.Entry<String, List<ApsGasPipingRouteStat>> entry : groupByOrderNo.entrySet()) {
            List<ApsGasPipingRouteStat> statPerOrder = entry.getValue();
            /*num 为根据完工时间排序出的序号,按此排序,可保证是按完工时间倒叙排列*/
            statPerOrder.sort((a, b)->a.getNum().compareTo(b.getNum()));
            ApsGasPipingRouteStat last=null;
            /*当前工序是否存在 计划开工时间 小于 当前的时间,如果存在后续设置为当前时间*/
            boolean hasBefore = false;
            for (int i = 0; i <statPerOrder.size(); i++) {
                ApsGasPipingRouteStat stat = statPerOrder.get(i);
                stat.setId(String.valueOf(IdUtil.getSnowflakeNextId()));
                stat.setBatchNumber(batchNum);
                stat.setCreateTime(DateUtils.getNowDate());
                stat.setCreateBy(SecurityUtils.getUsername());
                stat.setWarning(false);
                stat.setDelFlag("0");
                if(i==0){
                    Date orderPlanEndDay = stat.getOrderPlanEndDay();
                    LocalDateTime transLocalDateTime = transLocalDateTime(orderPlanEndDay);
                    LocalTime endOfDay = LocalTime.of(23, 59, 59);
                    LocalDateTime orderPlanEndDayLocalDateTime =  LocalDateTime.of( transLocalDateTime.toLocalDate(), endOfDay);
                    if(orderPlanEndDayLocalDateTime.isBefore(now)){
                        hasBefore = true;
                        stat.setWarning(true);
                        stat.setProcessPlanEndDay(transDate(now));
                        stat.setProcessPlanStartDay(transDate(now));
                    }else {
                        /*计划完工日=钣金计划工单完成时间*/
                        stat.setProcessPlanEndDay(transDate(orderPlanEndDayLocalDateTime));
                        /*计划开工日=钣金计划工单完成时间 -  工序总工时*/
                        long seconds = stat.getProcessTotalTime().multiply(new BigDecimal(60)).multiply(new BigDecimal(60)).longValue();
                        LocalDateTime lastPlanStartDt = orderPlanEndDayLocalDateTime.minusSeconds(seconds);
                        if(lastPlanStartDt.isBefore(now)){
                            hasBefore = true;
                            stat.setProcessPlanStartDay(transDate(now));
                        }else {
                            stat.setProcessPlanStartDay(transDate(lastPlanStartDt));
                        }
                    }
                }
                /*当工艺工序号 >= 工单当前工序 代表是未来工序,才进行计划开工日 和计划完工日的计算
                 * 当工艺工序号 < 工单当前工序  过去工序,不进行计算
                 * */
                if( stat.getRoadProcessNumber().compareTo(stat.getCurrentProcessNumber())>=0){
                    /*倒排时 下一道工序存在 比当前时间小的计划时间,则当前计划开始和结束时间都是当前时间*/
                    if(hasBefore){
                        stat.setWarning(true);
                        stat.setProcessPlanEndDay(transDate(now));
                        stat.setProcessPlanStartDay(transDate(now));
                    }else{
                        /*下一道工序计划时间都正常时,*/
                        if (last != null) {
                            /*当前工序结束时间=下一道工序的开始时间*/
                            stat.setProcessPlanEndDay(last.getProcessPlanStartDay());
                            /*开始时间=结束时间-总工时*/
                            long seconds = stat.getProcessTotalTime().multiply(new BigDecimal(60)).multiply(new BigDecimal(60)).longValue();
                            LocalDateTime crtStartDt = transLocalDateTime(last.getProcessPlanStartDay()).minusSeconds(seconds);
                            /*如果开始时间小于当前时间*/
                            if(crtStartDt.isBefore(now)){
                                hasBefore=true;
                                stat.setWarning(true);
                                stat.setProcessPlanStartDay(transDate(now));
                            }else {
                                stat.setProcessPlanStartDay(transDate(crtStartDt));
                            }
                        }
                    }
                }
               if(stat.getProcessPlanStartDay()!=null){
                   Date processPlanStartDay = stat.getProcessPlanStartDay();
                   stat.setPlanStartYear(processPlanStartDay.getYear()+"");
                   stat.setPlanStartMonth(processPlanStartDay.getMonth()+"");
                   stat.setPlanStartDay(processPlanStartDay.getDay()+"");
               }
                last = stat;
                cptStateList.add(stat);
            }
        }
        // 批量插入以提高性能
        if (!cptStateList.isEmpty()) {
            int batchSize = 500;
            int size = cptStateList.size();
            for (int i = 0; i < size; i += batchSize) {
                int end = Math.min(i + batchSize, size);
                List<ApsGasPipingRouteStat> batch = cptStateList.subList(i, end);
                apsGasPipingRouteStatMapper.insertApsGasPipingRouteStatBatch(batch);
                log.info("批量插入数据,开始位置:{},结束位置:{}", i, end);
            }
        }
        apsGasPipingRouteStatMapper.deleteApsGasPipingRouteStatByBatchNum(batchNum);
        log.info("批量插入数据完成,batchNum:"+batchNum);
    }
}