zhanghl
2025-04-27 01bec5540f87a68ae881295f9fe06283e00f1ed2
aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,430 @@
package com.aps.core.service.impl;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.aps.common.core.utils.DateUtils;
import com.aps.common.core.utils.uuid.IdUtils;
import com.aps.common.security.utils.SecurityUtils;
import com.aps.core.domain.*;
import com.aps.core.mapper.ApsGasPipelineCapacityPlanMapper;
import com.aps.core.mapper.ApsGasPipingPlanMapper;
import com.aps.core.mapper.ApsGasPipingRouteStatMapper;
import com.aps.core.service.IApsGasMaterialUsageService;
import com.aps.core.service.IApsGasPipingRouteStatService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
 * æ°”体管路产能负载统计Service业务层处理
 *
 * @author hjy
 * @date 2025-04-24
 */
@Slf4j
@Service
public class ApsGasPipingRouteStatServiceImpl implements IApsGasPipingRouteStatService
{
    @Autowired
    private ApsGasPipingRouteStatMapper apsGasPipingRouteStatMapper;
    @Autowired
    private ApsGasPipingPlanMapper apsGasPipingPlanMapper;
    @Autowired
    private ApsGasPipelineCapacityPlanMapper apsGasPipelineCapacityPlanMapper;
    @Autowired
    private IApsGasMaterialUsageService apsGasMaterialUsageService;
    /**
     * æŸ¥è¯¢æ°”体管路产能负载统计
     *
     * @param id æ°”体管路产能负载统计主键
     * @return æ°”体管路产能负载统计
     */
    @Override
    public ApsGasPipingRouteStat selectApsGasPipingRouteStatById(String id)
    {
        return apsGasPipingRouteStatMapper.selectApsGasPipingRouteStatById(id);
    }
    /**
     * æŸ¥è¯¢æ°”体管路产能负载统计列表
     *
     * @param apsGasPipingRouteStat æ°”体管路产能负载统计
     * @return æ°”体管路产能负载统计
     */
    @Override
    public List<ApsGasPipingRouteStat> selectApsGasPipingRouteStatList(ApsGasPipingRouteStat apsGasPipingRouteStat)
    {
        return apsGasPipingRouteStatMapper.selectApsGasPipingRouteStatList(apsGasPipingRouteStat);
    }
    /**
     * æ–°å¢žæ°”体管路产能负载统计
     *
     * @param apsGasPipingRouteStat æ°”体管路产能负载统计
     * @return ç»“æžœ
     */
    @Override
    public int insertApsGasPipingRouteStat(ApsGasPipingRouteStat apsGasPipingRouteStat)
    {
        apsGasPipingRouteStat.setCreateTime(DateUtils.getNowDate());
        apsGasPipingRouteStat.setCreateBy(SecurityUtils.getUsername());
        return apsGasPipingRouteStatMapper.insertApsGasPipingRouteStat(apsGasPipingRouteStat);
    }
    /**
     * ä¿®æ”¹æ°”体管路产能负载统计
     *
     * @param apsGasPipingRouteStat æ°”体管路产能负载统计
     * @return ç»“æžœ
     */
    @Override
    public int updateApsGasPipingRouteStat(ApsGasPipingRouteStat apsGasPipingRouteStat)
    {
        apsGasPipingRouteStat.setUpdateBy(SecurityUtils.getUsername());
        apsGasPipingRouteStat.setUpdateTime(DateUtils.getNowDate());
        return apsGasPipingRouteStatMapper.updateApsGasPipingRouteStat(apsGasPipingRouteStat);
    }
    /**
     * æ‰¹é‡åˆ é™¤æ°”体管路产能负载统计
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ°”体管路产能负载统计主键
     * @return ç»“æžœ
     */
    @Override
    public int deleteApsGasPipingRouteStatByIds(String[] ids)
    {
        return apsGasPipingRouteStatMapper.deleteApsGasPipingRouteStatByIds(ids);
    }
    /**
     * åˆ é™¤æ°”体管路产能负载统计信息
     *
     * @param id æ°”体管路产能负载统计主键
     * @return ç»“æžœ
     */
    @Override
    public int deleteApsGasPipingRouteStatById(String id)
    {
        return apsGasPipingRouteStatMapper.deleteApsGasPipingRouteStatById(id);
    }
    @Override
    public boolean computeCapacity() {
//        PageHelper.startPage(1, 500);
        List<ApsGasPipingPlan> apsGasPipingPlans = apsGasPipingPlanMapper.selectApsGasPipingPlanWithProcess(new ApsGasPipingPlan());
        List<ApsGasPipingRouteStat> apsGasPipingRouteStatList = new ArrayList<>();
        /*本次计算批次号*/
        String batchNum = IdUtils.fastSimpleUUID();
        try {
            apsGasPipingPlans.forEach(apsGasPipingPlan -> {
                List<ApsProcessRoute> apsProcessRoutes = apsGasPipingPlan.getApsProcessRoutes();
                //按照工序序号升序排序
                apsProcessRoutes.sort((a, b)->a.getProcessNumber().compareTo(b.getProcessNumber()));
                //是否找到当前工序
                boolean isFind = false;
                for (int i=0;i<apsProcessRoutes.size();i++){
                    ApsProcessRoute apsProcessRoute = apsProcessRoutes.get(i);
                    ApsGasPipingRouteStat apsGasPipingRouteStat = new ApsGasPipingRouteStat();
                    //工单号
                    apsGasPipingRouteStat.setWorkOrderNo(apsGasPipingPlan.getDocumentNumber());
                    //料号
                    apsGasPipingRouteStat.setItemNumber(apsGasPipingPlan.getItemNumber());
                    //当前工序号
                    apsGasPipingRouteStat.setCurrentProcessNumber(apsGasPipingPlan.getProcessNumber());
                    //生产数量
                    apsGasPipingRouteStat.setProductionQuantity(apsGasPipingPlan.getProductionQuantity());
                    //工序名称
                    apsGasPipingRouteStat.setProcessName(apsProcessRoute.getProcessName());
                    //工序号
                    apsGasPipingRouteStat.setRoadProcessNumber(apsProcessRoute.getProcessNumber());
                    //标准工时
                    apsGasPipingRouteStat.setStandardTime(apsProcessRoute.getStandardTime());
                    //专业
                    apsGasPipingRouteStat.setMajor(apsGasPipingPlan.getPlanType());
                    //工序总工时 ç­‰äºŽ æ ‡å‡†å·¥æ—¶*生产数量
                    apsGasPipingRouteStat.setProcessTotalTime(apsProcessRoute.getStandardTime().multiply(apsGasPipingPlan.getProductionQuantity()));
                    //计划开工日
                    if(apsGasPipingRouteStat.getCurrentProcessNumber().equals(apsGasPipingRouteStat.getRoadProcessNumber())) {
                        /* å¯¹ stat.getProcessPlanStartDay() å’Œå½“前日期 è¿›è¡Œå¯¹æ¯”,只对比到日,不用管十分秒*/
                        LocalDate startLocalDate = LocalDate.ofInstant(apsProcessRoute.getProcessPlanStartDay().toInstant(), ZoneId.systemDefault());
                        LocalDate nowLocalDate = LocalDate.now();
                        if (startLocalDate.isBefore(nowLocalDate)) {
                            apsGasPipingRouteStat.setProcessPlanStartDay(new Date());
                        }else{
                            apsGasPipingRouteStat.setProcessPlanStartDay(apsProcessRoute.getProcessPlanStartDay());
                        }
                        isFind = true;
                    }
                    if(!isFind){
                        continue;
                    }
                    // ä¸Šä¸€é“工序的结束时间 = ä¸Šä¸€é“工序的开始时间 + ä¸Šä¸€é“工序的总工时
                    if(apsGasPipingRouteStat.getProcessPlanStartDay()==null){
                        LocalDateTime previousProcessPlanStartDay = apsProcessRoutes.get(i - 1).getProcessPlanStartDay().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                        long previousProcessTotalTime = apsGasPipingRouteStatList.get(i - 1).getProcessTotalTime().longValue();
                        LocalDateTime currentProcessPlanStartDay = previousProcessPlanStartDay.plusHours(previousProcessTotalTime);
                        apsGasPipingRouteStat.setProcessPlanStartDay(Date.from(Timestamp.valueOf(currentProcessPlanStartDay.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).toInstant()));
                    }
                    //插入 å¹´ æœˆ æ—¥
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    String formattedDate = sdf.format(apsGasPipingRouteStat.getProcessPlanStartDay());
                    String[] dateParts = formattedDate.split("-");
                    apsGasPipingRouteStat.setPlanStartYear(String.valueOf(Integer.parseInt(dateParts[0])));
                    apsGasPipingRouteStat.setPlanStartMonth(String.valueOf(Integer.parseInt(dateParts[1])));
                    apsGasPipingRouteStat.setPlanStartDay(String.valueOf(Integer.parseInt(dateParts[2])));
                    //标准用量 æŸ¥è¯¢ç‰©æ–™ç”¨é‡è¡¨
//                    ApsGasMaterialUsage apsGasMaterialUsage = new ApsGasMaterialUsage();
//                    apsGasMaterialUsage.setItemNumber(apsGasPipingPlan.getItemNumber());
//                    apsGasMaterialUsage.setProcessName(apsProcessRoute.getProcessName());
//                    List<ApsGasMaterialUsage> apsGasMaterialUsageList = apsGasMaterialUsageService.selectApsGasMaterialUsageList(apsGasMaterialUsage);
                    apsGasPipingRouteStat.setStandardDosage(apsProcessRoute.getStandardTime().multiply(apsGasPipingPlan.getProductionQuantity()));
                    //工序总用量 = æ ‡å‡†ç”¨é‡*生产数量
                    apsGasPipingRouteStat.setProcessTotalDosage(apsGasPipingRouteStat.getStandardDosage().multiply(apsGasPipingPlan.getProductionQuantity()));
                    apsGasPipingRouteStat.setCreateTime(DateUtils.getNowDate());
                    apsGasPipingRouteStat.setCreateBy("auto");
                    apsGasPipingRouteStat.setBatchNumber(batchNum);
                    apsGasPipingRouteStat.setId(IdUtils.fastSimpleUUID());
                    apsGasPipingRouteStatList.add(apsGasPipingRouteStat);
                }
            });
            List<ApsGasPipingRouteStat> tempInsertList = new ArrayList<>();
            for (int i = 0; i < apsGasPipingRouteStatList.size(); i++) {
                tempInsertList.add(apsGasPipingRouteStatList.get(i));
                if(tempInsertList.size()==500){
                    apsGasPipingRouteStatMapper.insertApsGasPipingRouteStatBatch(tempInsertList);
                    tempInsertList = new ArrayList<>();
                }else if(i==apsGasPipingRouteStatList.size()-1){
                    apsGasPipingRouteStatMapper.insertApsGasPipingRouteStatBatch(tempInsertList);
                }
            }
            apsGasPipingRouteStatMapper.deleteApsGasPipingRouteStatByBatchNum(batchNum);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    @Override
    public JSONObject getCapacityPlanData(ApsGasPipingRouteStat apsGasPipingRouteStat) {
        JSONObject result = new JSONObject();
        HashSet<String> startPlanTimeSet = new HashSet<>();
        JSONArray processData = new JSONArray();
        try {
            //获取工序计划产能数据
            HashMap<String, ApsGasPipelineCapacityPlan> apsGasPipingPlanMap = new HashMap<>();
            List<ApsGasPipelineCapacityPlan> apsGasPipelineCapacityPlanList = apsGasPipelineCapacityPlanMapper.selectApsGasPipelineCapacityPlanList(new ApsGasPipelineCapacityPlan());
            apsGasPipelineCapacityPlanList.forEach(apsGasPipelineCapacityPlan -> {
                apsGasPipingPlanMap.put(apsGasPipelineCapacityPlan.getProcessName(),apsGasPipelineCapacityPlan);
            });
            //计算日产能数据
            DateTimeFormatter formatter = null;
            List<ApsGasPipingRouteStat> apsGasPipingRouteStats;
            SimpleDateFormat simpleDateFormat = null;
            YearMonth yearMonth = YearMonth.parse(apsGasPipingRouteStat.getSearchEndDate());
            int daysInMonth = yearMonth.lengthOfMonth();
            apsGasPipingRouteStat.setSearchStartDate(apsGasPipingRouteStat.getSearchStartDate()+"-01 00:00:00");
            apsGasPipingRouteStat.setSearchEndDate(apsGasPipingRouteStat.getSearchEndDate()+"-"+ daysInMonth +" 23:59:59");
            if("day".equals(apsGasPipingRouteStat.getSearchType())){
                formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            }else if("month".equals(apsGasPipingRouteStat.getSearchType())){
                formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                simpleDateFormat = new SimpleDateFormat("yyyy-MM");
            }
            apsGasPipingRouteStats = apsGasPipingRouteStatMapper.selectApsGasPipingRouteStatList(apsGasPipingRouteStat);
            //根据开工日进行升序排序
            apsGasPipingRouteStats.sort((a, b)->a.getProcessPlanStartDay().compareTo(b.getProcessPlanStartDay()));
            //工序分组统计
            HashMap<String, List<ApsResourceDateStat>> processMap = new HashMap<>();
            List<HashMap<String, List<ApsResourceDateStat>>> processList = new ArrayList<>();
            //工序开工日期
            String planStartDate = "";
            //统计所有工序对应的开工时间
            for (ApsGasPipingRouteStat apsGasPipingRouteStatTemp : apsGasPipingRouteStats) {
                planStartDate = simpleDateFormat.format(apsGasPipingRouteStatTemp.getProcessPlanStartDay());
                if("month".equals(apsGasPipingRouteStat.getSearchType())){
                    planStartDate = planStartDate+"-01";
                }
                ApsResourceDateStat apsResourceDateStat = new ApsResourceDateStat();
                apsResourceDateStat.setPlanDay(LocalDate.parse(planStartDate, formatter));
                apsResourceDateStat.setResourceName(apsGasPipingRouteStatTemp.getProcessName());
                //查询气柜管路产能规划表
                apsResourceDateStat.setDesignTimes(apsGasPipingPlanMap.get(apsGasPipingRouteStatTemp.getProcessName())!=null?apsGasPipingPlanMap.get(apsGasPipingRouteStatTemp.getProcessName()).getDayProduceAllNum().intValue():0);
                //查询料号工序产能表
                apsResourceDateStat.setRequireTimes(apsGasPipingRouteStatTemp.getProcessTotalTime().intValue());
                if(apsResourceDateStat.getDesignTimes()!=0){
                    apsResourceDateStat.setCapacityLoad(BigDecimal.valueOf(apsResourceDateStat.getRequireTimes()/apsResourceDateStat.getDesignTimes()* 100L));
                }else{
                    apsResourceDateStat.setCapacityLoad(BigDecimal.valueOf(0));
                }
                List<ApsResourceDateStat> apsResourceDateStatList = new ArrayList<>();
                if(processMap.containsKey(apsGasPipingRouteStatTemp.getProcessName())){
                    apsResourceDateStatList = processMap.get(apsGasPipingRouteStatTemp.getProcessName());
                }
                apsResourceDateStatList.add(apsResourceDateStat);
                processMap.put(apsGasPipingRouteStatTemp.getProcessName(), apsResourceDateStatList);
            }
            //聚合每道工序的开工时间和产能
            processMap.forEach((processName, apsResourceDateStatList) -> {
                LinkedHashMap<String, ApsResourceDateStat> dayMap = new LinkedHashMap<>();
                apsResourceDateStatList.forEach(apsResourceDateStat -> {
                    startPlanTimeSet.add(apsResourceDateStat.getPlanDay().toString());
                    if(dayMap.containsKey(apsResourceDateStat.getPlanDay().toString())){
                        ApsResourceDateStat apsResourceDateStatTemp = dayMap.get(apsResourceDateStat.getPlanDay().toString());
                        apsResourceDateStatTemp.setDesignTimes(apsGasPipingPlanMap.get(processName)!=null?apsGasPipingPlanMap.get(processName).getMonthProduceAllNum().intValue():0);
                        apsResourceDateStatTemp.setRequireTimes(apsResourceDateStatTemp.getRequireTimes()+apsResourceDateStat.getRequireTimes());
                        if(apsResourceDateStatTemp.getDesignTimes()!=0){
                            apsResourceDateStatTemp.setCapacityLoad(BigDecimal.valueOf(apsResourceDateStatTemp.getRequireTimes()/apsResourceDateStatTemp.getDesignTimes()* 100L));
                        }else{
                            apsResourceDateStatTemp.setCapacityLoad(BigDecimal.valueOf(0));
                        }
                        apsResourceDateStatTemp.setResourceGroupName(processName);
                        apsResourceDateStatTemp.setPlanDay(apsResourceDateStat.getPlanDay());
                        dayMap.put(apsResourceDateStat.getPlanDay().toString(), apsResourceDateStatTemp);
                    }else{
                        dayMap.put(apsResourceDateStat.getPlanDay().toString(), apsResourceDateStat);
                    }
                });
                List<ApsResourceDateStat> tempList = new ArrayList<>();
                dayMap.forEach((key, value) -> {
                    tempList.add(value);
                });
//                processMap.put(processName, tempList);
                HashMap<String, List<ApsResourceDateStat>> temp = new HashMap<>();
                temp.put(processName, tempList);
                processList.add(temp);
            });
//            for (String key : processMap.keySet()) {
//                HashMap<String, List<ApsResourceDateStat>> temp = new HashMap<>();
//                temp.put(key, processMap.get(key));
//                processList.add(temp);
//            }
            //排序时间标题
            List<String> sortedStartPlanTimeList = new ArrayList<>(startPlanTimeSet);
            Collections.sort(sortedStartPlanTimeList);
            result.put("planTable", processList);
            result.put("planTitle", sortedStartPlanTimeList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    @Override
    public void exportExcel(HttpServletResponse response, ApsGasPipingRouteStat apsGasPipingRouteStat) {
        SXSSFWorkbook wb = new SXSSFWorkbook(500);
        wb.createSheet();
        wb.setSheetName(0, "气柜管路产能负载统计表");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        Map<String, CellStyle> styles = createStyles(wb);
        CellStyle title = styles.get("title");
        try
        {
            JSONObject stat = getCapacityPlanData(apsGasPipingRouteStat);
            List<String> days = (List<String>) stat.get("planTitle");
            List<HashMap<String, List<ApsResourceDateStat>>> table= (List<HashMap<String, List<ApsResourceDateStat>>>) stat.get("planTable");
            SXSSFSheet sheet = wb.getSheetAt(0);
            /*填写日期列 å’Œ å·¥æ—¶åˆ—*/
            SXSSFRow rowDay = sheet.createRow(0);
            SXSSFRow rowTitle = sheet.createRow(1);
            SXSSFCell daytitle = rowDay.createCell(0);
            daytitle.setCellValue("日期");
            daytitle.setCellStyle(title);
            SXSSFCell titleCell = rowTitle.createCell(0);
            titleCell.setCellValue("工序");
            titleCell.setCellStyle(title);
            for (int i = 0; i < days.size(); i++) {
                SXSSFCell dateCell = rowDay.createCell(i * 3 + 1);
                SXSSFCell designHoursCell = rowTitle.createCell(i * 3 + 1);
                SXSSFCell requireHoursCell = rowTitle.createCell(i * 3 + 2);
                SXSSFCell loadCell = rowTitle.createCell(i * 3 + 3);
                dateCell.setCellValue(days.get(i));
                designHoursCell.setCellValue("设计工时");
                requireHoursCell.setCellValue("需求工时");
                loadCell.setCellValue("产能负荷");
                /*set cell style*/
                dateCell.setCellStyle(title);
                designHoursCell.setCellStyle(title);
                requireHoursCell.setCellStyle(title);
                loadCell.setCellStyle(title);
                /*合并日期单元格*/
                sheet.addMergedRegion( new CellRangeAddress(0, 0, i*3+1, i*3+3));
            }
            for (int i = 0; i < table.size(); i++) {
                Map<String, List<ApsResourceDateStat>> resourceList = table.get(i);
                /*创建数据行*/
                SXSSFRow dataRow  = sheet.createRow(i+2);
                for( Map.Entry<String, List<ApsResourceDateStat>> entry : resourceList.entrySet()){
                    String resourceName = entry.getKey();
                    List<ApsResourceDateStat> resourceDateStats = entry.getValue();
                    dataRow.createCell(0).setCellValue(resourceName);
                    for (int j = 0; j < resourceDateStats.size(); j++) {
                        ApsResourceDateStat apsResourceDateStat = resourceDateStats.get(j);
                        dataRow.createCell(j*3+1).setCellValue(apsResourceDateStat.getDesignTimes());
                        dataRow.createCell(j*3+2).setCellValue(apsResourceDateStat.getRequireTimes());
                        if(apsResourceDateStat.getCapacityLoad()!=null){
                            dataRow.createCell(j*3+3).setCellValue(apsResourceDateStat.getCapacityLoad().doubleValue()+"%");
                        }else{
                            dataRow.createCell(j*3+3).setCellValue("%");
                        }
                    }
                }
            }
            wb.write(response.getOutputStream());
        }
        catch (Exception e)
        {
            log.error("导出Excel异常{}", e.getMessage());
        }
        finally
        {
            IOUtils.closeQuietly(wb);
        }
    }
    private Map<String,CellStyle> createStyles(SXSSFWorkbook wb)
    {
        Map<String,CellStyle> styles=new HashMap<>();
        CellStyle style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        Font titleFont = wb.createFont();
        titleFont.setFontName("Arial");
        titleFont.setFontHeightInPoints((short) 12);
        titleFont.setBold(true);
        style.setFont(titleFont);
        DataFormat dataFormat = wb.createDataFormat();
        style.setDataFormat(dataFormat.getFormat("@"));
        styles.put("title", style);
        return styles;
    }
}