huangjiayang
2025-04-29 f176e23977ff478ba2306383ea38d91f3a24fffd
aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java
@@ -26,11 +26,12 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import static java.util.stream.Collectors.groupingBy;
/**
 * 气体管路产能负载统计Service业务层处理
@@ -144,10 +145,10 @@
            apsGasPipingPlans.forEach(apsGasPipingPlan -> {
                List<ApsProcessRoute> apsProcessRoutes = apsGasPipingPlan.getApsProcessRoutes();
                //按照工序序号升序排序
                apsProcessRoutes.sort((a, b)->a.getProcessNumber().compareTo(b.getProcessNumber()));
                apsProcessRoutes.sort((a, b)->b.getProcessNumber().compareTo(a.getProcessNumber()));
                //是否找到当前工序
                boolean isFind = false;
                ApsProcessRoute preApsProcessRoute = null;
                boolean isCurrentProcess = false;
                ApsGasPipingRouteStat preApsProcessRoute = null;
                for (int i=0;i<apsProcessRoutes.size();i++){
                    ApsProcessRoute apsProcessRoute = apsProcessRoutes.get(i);
                    ApsGasPipingRouteStat apsGasPipingRouteStat = new ApsGasPipingRouteStat();
@@ -169,8 +170,8 @@
                    apsGasPipingRouteStat.setMajor(apsGasPipingPlan.getPlanType());
                    //工序总工时 等于 标准工时*生产数量
                    apsGasPipingRouteStat.setProcessTotalTime(apsProcessRoute.getStandardTime().multiply(apsGasPipingPlan.getProductionQuantity()));
                    //计划开工日
                    if(apsGasPipingRouteStat.getCurrentProcessNumber().equals(apsGasPipingRouteStat.getRoadProcessNumber())) {
                    //计划开工日 如果是当前序
                    if(apsGasPipingRouteStat.getCurrentProcessNumber().toString().equals(apsGasPipingRouteStat.getRoadProcessNumber())) {
                        /* 对 stat.getProcessPlanStartDay() 和当前日期 进行对比,只对比到日,不用管十分秒*/
                        LocalDate startLocalDate = LocalDate.ofInstant(apsProcessRoute.getProcessPlanStartDay().toInstant(), ZoneId.systemDefault());
                        LocalDate nowLocalDate = LocalDate.now();
@@ -179,17 +180,23 @@
                        }else{
                            apsGasPipingRouteStat.setProcessPlanStartDay(apsProcessRoute.getProcessPlanStartDay());
                        }
                        isFind = true;
                    }
                    if(!isFind){
                        continue;
                    }
                    // 上一道工序的结束时间 = 上一道工序的开始时间 + 上一道工序的总工时
                    if(apsGasPipingRouteStat.getProcessPlanStartDay()==null){
                        LocalDateTime previousProcessPlanStartDay = preApsProcessRoute.getProcessPlanStartDay().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                        long seconds = preApsProcessRoute.getStandardTime().multiply(apsGasPipingPlan.getProductionQuantity()).multiply(new BigDecimal(60)).multiply(new BigDecimal(60)).longValue();
                        LocalDateTime currentProcessPlanStartDay = previousProcessPlanStartDay.plusSeconds(seconds);
                        apsGasPipingRouteStat.setProcessPlanStartDay(Date.from(currentProcessPlanStartDay.atZone(ZoneId.systemDefault()).toInstant()));
                        apsGasPipingRouteStat.setProcessPlanEndDay(apsProcessRoute.getProcessPlanEndDay());
                        isCurrentProcess = true;
                    }else{
                        // 上一道工序的结束时间 = 上一道工序的开始时间 + 上一道工序的总工时
                        if(i==0){
                            apsGasPipingRouteStat.setProcessPlanEndDay(apsGasPipingPlan.getPlanEndDay());
                            LocalDateTime planEndDay = apsGasPipingPlan.getPlanEndDay().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                            long seconds = apsProcessRoute.getStandardTime().multiply(apsGasPipingPlan.getProductionQuantity()).multiply(new BigDecimal(60)).multiply(new BigDecimal(60)).longValue();
                            LocalDateTime planStartDay = planEndDay.plusSeconds(-seconds);
                            apsGasPipingRouteStat.setProcessPlanStartDay(Date.from(planStartDay.atZone(ZoneId.systemDefault()).toInstant()));
                        }else{
                            apsGasPipingRouteStat.setProcessPlanEndDay(preApsProcessRoute.getProcessPlanEndDay());
                            LocalDateTime planEndDay = apsGasPipingPlan.getPlanEndDay().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                            long seconds = apsProcessRoute.getStandardTime().multiply(apsGasPipingPlan.getProductionQuantity()).multiply(new BigDecimal(60)).multiply(new BigDecimal(60)).longValue();
                            LocalDateTime planStartDay = planEndDay.plusSeconds(-seconds);
                            apsGasPipingRouteStat.setProcessPlanStartDay(Date.from(planStartDay.atZone(ZoneId.systemDefault()).toInstant()));
                        }
                    }
                    //插入 年 月 日
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
@@ -211,7 +218,10 @@
                    apsGasPipingRouteStat.setBatchNumber(batchNum);
                    apsGasPipingRouteStat.setId(IdUtils.fastSimpleUUID());
                    apsGasPipingRouteStatList.add(apsGasPipingRouteStat);
                    preApsProcessRoute = apsProcessRoute;
                    preApsProcessRoute = apsGasPipingRouteStat;
                    if(isCurrentProcess){
                        break;
                    }
                }
            });
            List<ApsGasPipingRouteStat> tempInsertList = new ArrayList<>();
@@ -265,13 +275,11 @@
                YearMonth start = YearMonth.of(Integer.parseInt(apsGasPipingRouteStat.getSearchStartDate().split("-")[0]), Integer.parseInt(apsGasPipingRouteStat.getSearchStartDate().split("-")[1]));
                YearMonth end = YearMonth.of(Integer.parseInt(apsGasPipingRouteStat.getSearchEndDate().split("-")[0]), Integer.parseInt(apsGasPipingRouteStat.getSearchEndDate().split("-")[1]));
                List<String> yearMonths = getYearMonthsInRange(start, end);
                for (String yearMonthStr : yearMonths) {
                    startPlanTimeSet.add(yearMonthStr);
                }
                startPlanTimeSet.addAll(yearMonths);
            }
            List<ApsGasPipelineCapacityPlan> apsGasPipelineCapacityPlanList = apsGasPipelineCapacityPlanMapper.selectApsGasPipelineCapacityPlanList(searchCapacityPlan);
            apsGasPipelineCapacityPlanList.forEach(apsGasPipelineCapacityPlan -> {
                apsGasPipingPlanMap.put(apsGasPipelineCapacityPlan.getProcessName(),apsGasPipelineCapacityPlan);
                apsGasPipingPlanMap.put(apsGasPipelineCapacityPlan.getProcessName()+"-"+apsGasPipelineCapacityPlan.getYear()+"-"+(Integer.parseInt(apsGasPipelineCapacityPlan.getMonth())<10?"0"+apsGasPipelineCapacityPlan.getMonth():apsGasPipelineCapacityPlan.getMonth()),apsGasPipelineCapacityPlan);
            });
            //计算日产能数据
            DateTimeFormatter formatter = null;
@@ -301,7 +309,7 @@
                apsResourceDateStat.setPlanDay(LocalDate.parse(planStartDate, formatter));
                apsResourceDateStat.setResourceName(apsGasPipingRouteStatTemp.getProcessName());
                //查询气柜管路产能规划表
                apsResourceDateStat.setDesignTimes(apsGasPipingPlanMap.get(apsGasPipingRouteStatTemp.getProcessName())!=null?apsGasPipingPlanMap.get(apsGasPipingRouteStatTemp.getProcessName()).getDayProduceAllNum():new BigDecimal(0));
                apsResourceDateStat.setDesignTimes(apsGasPipingPlanMap.get(apsGasPipingRouteStatTemp.getProcessName()+"-"+planStartDate.substring(0, 7))!=null?apsGasPipingPlanMap.get(apsGasPipingRouteStatTemp.getProcessName()+"-"+planStartDate.substring(0, 7)).getDayProduceAllNum():new BigDecimal(0));
                //查询料号工序产能表
                apsResourceDateStat.setRequireTimes(apsGasPipingRouteStatTemp.getProcessTotalTime());
                if(apsResourceDateStat.getDesignTimes().compareTo(BigDecimal.ZERO)>0){
@@ -326,9 +334,9 @@
                    if(dayMap.containsKey(apsResourceDateStat.getPlanDay().toString())){
                        ApsResourceDateStat apsResourceDateStatTemp = dayMap.get(apsResourceDateStat.getPlanDay().toString());
                        if("month".equals(apsGasPipingRouteStat.getSearchType())){
                            apsResourceDateStatTemp.setDesignTimes(apsGasPipingPlanMap.get(processName)!=null?apsGasPipingPlanMap.get(processName).getMonthProduceAllNum():new BigDecimal(0));
                            apsResourceDateStatTemp.setDesignTimes(apsGasPipingPlanMap.get(processName+"-"+apsResourceDateStat.getPlanDay().toString().substring(0,7))!=null?apsGasPipingPlanMap.get(processName+"-"+apsResourceDateStat.getPlanDay().toString().substring(0,7)).getMonthProduceAllNum():new BigDecimal(0));
                        }else{
                            apsResourceDateStatTemp.setDesignTimes(apsGasPipingPlanMap.get(processName)!=null?apsGasPipingPlanMap.get(processName).getDayProduceAllNum():new BigDecimal(0));
                            apsResourceDateStatTemp.setDesignTimes(apsGasPipingPlanMap.get(processName+"-"+apsResourceDateStat.getPlanDay().toString().substring(0,7))!=null?apsGasPipingPlanMap.get(processName+"-"+apsResourceDateStat.getPlanDay().toString().substring(0,7)).getDayProduceAllNum():new BigDecimal(0));
                        }
                        apsResourceDateStatTemp.setRequireTimes(apsResourceDateStatTemp.getRequireTimes().add(apsResourceDateStat.getRequireTimes()));
                        if(apsResourceDateStatTemp.getDesignTimes().compareTo(BigDecimal.ZERO) > 0){
@@ -375,9 +383,9 @@
                            ApsResourceDateStat apsResourceDateStat = new ApsResourceDateStat();
                            apsResourceDateStat.setPlanDay(LocalDate.parse(tempTime, formatter));
                            if ("month".equals(apsGasPipingRouteStat.getSearchType())) {
                                apsResourceDateStat.setDesignTimes(apsGasPipingPlanMap.get(entry.getKey()) != null ? apsGasPipingPlanMap.get(entry.getKey()).getMonthProduceAllNum() : new BigDecimal(0));
                                apsResourceDateStat.setDesignTimes(apsGasPipingPlanMap.get(entry.getKey()+"-"+tempTime.substring(0,7)) != null ? apsGasPipingPlanMap.get(entry.getKey()+"-"+tempTime.substring(0,7)).getMonthProduceAllNum() : new BigDecimal(0));
                            } else {
                                apsResourceDateStat.setDesignTimes(apsGasPipingPlanMap.get(entry.getKey()) != null ? apsGasPipingPlanMap.get(entry.getKey()).getDayProduceAllNum() : new BigDecimal(0));
                                apsResourceDateStat.setDesignTimes(apsGasPipingPlanMap.get(entry.getKey()+"-"+tempTime.substring(0,7)) != null ? apsGasPipingPlanMap.get(entry.getKey()+"-"+tempTime.substring(0,7)).getDayProduceAllNum() : new BigDecimal(0));
                            }
                            apsResourceDateStat.setRequireTimes(new BigDecimal(0));
                            apsResourceDateStat.setCapacityLoad(new BigDecimal(0));
@@ -503,96 +511,5 @@
        }
        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());
    }
}