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 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 apsGasPipingPlans = apsGasPipingPlanMapper.selectApsGasPipingPlanWithProcess(new ApsGasPipingPlan()); List apsGasPipingRouteStatList = new ArrayList<>(); /*本次计算批次号*/ String batchNum = IdUtils.fastSimpleUUID(); try { apsGasPipingPlans.forEach(apsGasPipingPlan -> { List apsProcessRoutes = apsGasPipingPlan.getApsProcessRoutes(); //按照工序序号升序排序 apsProcessRoutes.sort((a, b)->a.getProcessNumber().compareTo(b.getProcessNumber())); //是否找到当前工序 boolean isFind = false; for (int i=0;i 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 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 startPlanTimeSet = new HashSet<>(); JSONArray processData = new JSONArray(); try { //获取工序计划产能数据 HashMap apsGasPipingPlanMap = new HashMap<>(); List apsGasPipelineCapacityPlanList = apsGasPipelineCapacityPlanMapper.selectApsGasPipelineCapacityPlanList(new ApsGasPipelineCapacityPlan()); apsGasPipelineCapacityPlanList.forEach(apsGasPipelineCapacityPlan -> { apsGasPipingPlanMap.put(apsGasPipelineCapacityPlan.getProcessName(),apsGasPipelineCapacityPlan); }); //计算日产能数据 DateTimeFormatter formatter = null; List 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> processMap = new HashMap<>(); List>> 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 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 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 tempList = new ArrayList<>(); dayMap.forEach((key, value) -> { tempList.add(value); }); // processMap.put(processName, tempList); HashMap> temp = new HashMap<>(); temp.put(processName, tempList); processList.add(temp); }); // for (String key : processMap.keySet()) { // HashMap> temp = new HashMap<>(); // temp.put(key, processMap.get(key)); // processList.add(temp); // } //排序时间标题 List 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 styles = createStyles(wb); CellStyle title = styles.get("title"); try { JSONObject stat = getCapacityPlanData(apsGasPipingRouteStat); List days = (List) stat.get("planTitle"); List>> table= (List>>) 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> resourceList = table.get(i); /*创建数据行*/ SXSSFRow dataRow = sheet.createRow(i+2); for( Map.Entry> entry : resourceList.entrySet()){ String resourceName = entry.getKey(); List 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 createStyles(SXSSFWorkbook wb) { Map 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; } }