aps-common/aps-common-core/src/main/java/com/aps/common/core/utils/poi/ExcelUtil.java
@@ -688,7 +688,7 @@ * @param wb å·¥ä½è对象 * @return æ ·å¼å表 */ private Map<String, CellStyle> createStyles(Workbook wb) public Map<String, CellStyle> createStyles(Workbook wb) { // åå ¥åæ¡è®°å½,æ¯æ¡è®°å½å¯¹åºexcel表ä¸çä¸è¡ Map<String, CellStyle> styles = new HashMap<String, CellStyle>(); aps-modules/aps-core/src/main/java/com/aps/core/controller/ApsPartRouteStatController.java
@@ -80,7 +80,6 @@ { return toAjax(apsPartRouteStatService.insertApsPartRouteStat(apsPartRouteStat)); } /** * ä¿®æ¹é¶ä»¶ç»è®¡è¡¨ */ @@ -91,7 +90,6 @@ { return toAjax(apsPartRouteStatService.updateApsPartRouteStat(apsPartRouteStat)); } /** * å é¤é¶ä»¶ç»è®¡è¡¨ */ @@ -102,4 +100,30 @@ { return toAjax(apsPartRouteStatService.deleteApsPartRouteStatByIds(ids)); } /** * 1.æ ¹æ®ç°æé¶ä»¶è®¡å åå·¥èºè·¯çº¿ãèµæºæ± ä¿¡æ¯ æ´æ°ç»è®¡è¡¨ * */ @PostMapping("/updateStat") public AjaxResult updateStat() { apsPartRouteStatService.updatePartRoutPlanDate(); return success(); } /*** * 2. æ ¹æ®æ¥æãå·¥èºè·¯çº¿ãèµæºæ± ä¿¡æ¯ æ¥è¯¢ç»è®¡è¡¨ * */ @GetMapping("/query") public AjaxResult query() { return apsPartRouteStatService.selectResourceDateStat(); } @GetMapping("/exportExcel") public void exportExcel(HttpServletResponse response) { apsPartRouteStatService.exportExcel(response); } } aps-modules/aps-core/src/main/java/com/aps/core/controller/basicData/ApsResourceGroupController.java
@@ -129,9 +129,9 @@ */ @PostMapping("/confirmData") public AjaxResult confirmData(@RequestBody ApsResourceGroupTemp temp) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime localDateTime = LocalDateTime.parse(temp.getParams().get("requestDate").toString(), formatter); apsResourceGroupService.confirmData(temp.getBatchNumber(),localDateTime); // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // LocalDateTime localDateTime = LocalDateTime.parse(temp.getParams().get("requestDate").toString(), formatter); apsResourceGroupService.confirmData(temp.getBatchNumber(),temp.getRequestDate()); return AjaxResult.success("确认æåï¼"); } } aps-modules/aps-core/src/main/java/com/aps/core/controller/basicData/ApsResourceGroupTempController.java
@@ -34,7 +34,7 @@ @GetMapping("/list") public TableDataInfo list(ApsResourceGroupTemp apsResourceGroupTemp) { startPage(); //startPage(); List<ApsResourceGroupTemp> list = apsResourceGroupTempService.selectApsResourceGroupTempList(apsResourceGroupTemp); return getDataTable(list); } aps-modules/aps-core/src/main/java/com/aps/core/domain/ApsPartRouteStat.java
@@ -25,6 +25,8 @@ @Excel(name = "å·¥åå·") private String workOrderNo; private String resourceGroupName; /** å·¥åºå· */ @Excel(name = "å·¥åºå·") private BigDecimal roadProcessNumber; @@ -170,6 +172,14 @@ return batchNumber; } public String getResourceGroupName() { return resourceGroupName; } public void setResourceGroupName(String resourceGroupName) { this.resourceGroupName = resourceGroupName; } @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) aps-modules/aps-core/src/main/java/com/aps/core/domain/ApsResourceDateStat.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,66 @@ package com.aps.core.domain; import java.math.BigDecimal; import java.time.LocalDate; /* * ç¨äºç»è®¡èµæºç»æ¥è®¡åæ°æ® * */ public class ApsResourceDateStat { public LocalDate getPlanDay() { return planDay; } public void setPlanDay(LocalDate planDay) { this.planDay = planDay; } public Integer getDesignTimes() { return designTimes; } public void setDesignTimes(Integer designTimes) { this.designTimes = designTimes; } public String getResourceName() { return resourceName; } public void setResourceName(String resourceName) { this.resourceName = resourceName; } public Integer getRequireTimes() { return requireTimes; } public void setRequireTimes(Integer requireTimes) { this.requireTimes = requireTimes; } public BigDecimal getCapacityLoad() { return capacityLoad; } public void setCapacityLoad(BigDecimal capacityLoad) { this.capacityLoad = capacityLoad; } public String getResourceGroupName() { return resourceGroupName; } public void setResourceGroupName(String resourceGroupName) { this.resourceGroupName = resourceGroupName; } private LocalDate planDay; private String resourceName; private Integer requireTimes; private Integer designTimes; private BigDecimal capacityLoad; private String resourceGroupName; } aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPartRouteStatMapper.java
@@ -2,6 +2,7 @@ import java.util.List; import com.aps.core.domain.ApsPartRouteStat; import com.aps.core.domain.ApsResourceDateStat; import org.apache.ibatis.annotations.Mapper; /** @@ -71,4 +72,5 @@ * */ int deleteLastBatch(String batchNumber); List<ApsResourceDateStat> selectResourceDateStat(); } aps-modules/aps-core/src/main/java/com/aps/core/service/IApsPartRouteStatService.java
@@ -1,7 +1,10 @@ package com.aps.core.service; import java.util.List; import com.aps.common.core.web.domain.AjaxResult; import com.aps.core.domain.ApsPartRouteStat; import jakarta.servlet.http.HttpServletResponse; /** * é¶ä»¶ç»è®¡è¡¨Serviceæ¥å£ @@ -59,4 +62,9 @@ */ public int deleteApsPartRouteStatById(String id); void updatePartRoutPlanDate(); AjaxResult selectResourceDateStat(); void exportExcel(HttpServletResponse response); } aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPartRouteStatServiceImpl.java
@@ -1,13 +1,29 @@ package com.aps.core.service.impl; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Map; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; import com.aps.common.core.utils.poi.ExcelUtil; import com.aps.common.core.utils.uuid.IdUtils; import com.aps.common.core.utils.uuid.UUID; import com.aps.common.core.web.domain.AjaxResult; import com.aps.core.domain.ApsPartPlan; import com.aps.core.domain.ApsResourceDateStat; import com.aps.core.mapper.ApsResourceGroupMapper; 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.cloud.commons.config.DefaultsBindHandlerAdvisor; import org.springframework.stereotype.Service; import com.aps.core.mapper.ApsPartRouteStatMapper; import com.aps.core.domain.ApsPartRouteStat; @@ -21,12 +37,15 @@ * @author zhl * @date 2025-04-11 */ @Slf4j @Service public class ApsPartRouteStatServiceImpl implements IApsPartRouteStatService { @Autowired private ApsPartRouteStatMapper apsPartRouteStatMapper; private DefaultsBindHandlerAdvisor.MappingsProvider mappingsProvider; @Autowired private ApsResourceGroupMapper resourceGroupMapper; /** * æ¥è¯¢é¶ä»¶ç»è®¡è¡¨ @@ -103,13 +122,16 @@ /** * æ¥è¯¢é¶ä»¶å·¥åºå¹¶æ´æ°è®¡åå¼å·¥æ¥æ * */ @Override public void updatePartRoutPlanDate() { List<ApsPartRouteStat> tempList = apsPartRouteStatMapper.selectPartRoutStat(); /*对tempList æç § workOrderNo è¿è¡åç»*/ Map<String, List<ApsPartRouteStat>> groupByWorkOrderNo = tempList.stream().collect(groupingBy(ApsPartRouteStat::getWorkOrderNo)); /*æ¬æ¬¡è®¡ç®æ¹æ¬¡å·*/ String batchNum = IdUtils.fastSimpleUUID(); apsPartRouteStatMapper.deleteLastBatch(batchNum); for (Map.Entry<String, List<ApsPartRouteStat>> entry : groupByWorkOrderNo.entrySet()) { /*ååºæ¯ä¸ªé¶ä»¶å·¥åçå·¥èºè·¯çº¿ä¿¡æ¯*/ List<ApsPartRouteStat> apsPartRouteStatList = entry.getValue(); @@ -118,7 +140,7 @@ /*临æ¶ä¿å ä¸ä¸éå·¥åºçå·¥åºæ»å·¥æ¶*/ ApsPartRouteStat last=null; for (int i = 0; i <apsPartRouteStatList.size(); i++) { ApsPartRouteStat stat = apsPartRouteStatList.get(0); ApsPartRouteStat stat = apsPartRouteStatList.get(i); /*夿å½åå·¥åº å½åå·¥åºåªæä¸æ¡*/ if (stat.getCurrentProcessNumber().equals(stat.getRoadProcessNumber())) { /* 对 stat.getProcessPlanStartDay() åå½åæ¥æ è¿è¡å¯¹æ¯ï¼åªå¯¹æ¯å°æ¥ï¼ä¸ç¨ç®¡ååç§*/ @@ -127,7 +149,7 @@ } } /*æªå¼å·¥å·¥åºç计åå¼å·¥æ¥=ä¸ä¸éå·¥åºç计åå¼å·¥æ¥+ä¸ä¸éå·¥åºçå·¥åºæ»å·¥æ¶ã*/ if (stat.getCurrentProcessNumber().compareTo(stat.getRoadProcessNumber()) > 0) { if (stat.getCurrentProcessNumber().compareTo(stat.getRoadProcessNumber()) < 0) { if (last != null) { stat.setProcessPlanStartDay(last.getProcessPlanStartDay().plusHours(last.getProcessTotalTime())); } @@ -140,6 +162,158 @@ } } apsPartRouteStatMapper.deleteLastBatch(batchNum); } /** æ¥è¯¢èµæºæ¥å表 */ @Override public AjaxResult selectResourceDateStat() { /*æ¥åºææç»è®¡çæ°æ®*/ AjaxResult result = new AjaxResult(200, "çææå"); List<ApsResourceDateStat> list = apsPartRouteStatMapper.selectResourceDateStat(); if (!list.isEmpty()) { /*æ±åºè®¡åçæå¤§æ¶é´ï¼æ²¡æ 设置为å½åæ¶é´+15天*/ ApsResourceDateStat apsResourceDateStat = list.stream().max(Comparator.comparing(ApsResourceDateStat::getPlanDay)).orElse(null); LocalDate maxPlanDay = LocalDate.now().plus(15, ChronoUnit.DAYS); if (apsResourceDateStat != null) { maxPlanDay = apsResourceDateStat.getPlanDay(); } /*ç»ç»åºæ¥æè¡¨å¤´*/ List<String> planDays = new ArrayList<>(); LocalDate startDay = LocalDate.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); while (!startDay.isAfter(maxPlanDay)) { planDays.add(startDay.format(formatter)); startDay = startDay.plus(1, ChronoUnit.DAYS); } /*ç»ç»åºåå¤´æ°æ®*/ List<String> resourceNames =list.stream().map(ApsResourceDateStat::getResourceName).distinct().toList(); /*åå¤èµæºç»ä¿¡æ¯*/ List<Map<String, List<ApsResourceDateStat>>> targetList = new ArrayList<>(); resourceNames.forEach(resourceName -> { /*æ ¹æ®æ¥æè¡¨å¤´ç顺åºï¼ç»ç»åºæ¯ä¸ªæ¥æä¸çç»è®¡é¡¹ç®*/ Map<String, List<ApsResourceDateStat>> maps = new HashMap<>(Map.of()); List<ApsResourceDateStat> currentDaysResouces=new ArrayList<>(); for (String planDay : planDays) { /*æ¥æ¾å½åè®¡åæ¥æä¸çææèµæºç»çæ°æ®*/ Optional<ApsResourceDateStat> first = list.stream() .filter(item -> item.getPlanDay().equals(LocalDate.parse(planDay, formatter)) && item.getResourceGroupName().equals(resourceName) ).collect(Collectors.toList()).stream().findFirst(); if(first.isPresent()){ currentDaysResouces.add(first.get()); } else { ApsResourceDateStat empty = new ApsResourceDateStat(); empty.setPlanDay(LocalDate.parse(planDay, formatter)); empty.setDesignTimes(0); empty.setRequireTimes(0); empty.setResourceName(resourceName); empty.setResourceGroupName(resourceName); empty.setCapacityLoad(BigDecimal.ZERO); currentDaysResouces.add(empty); } }; maps.put(resourceName, currentDaysResouces); targetList.add(maps); }); result.put("planTitle", planDays); result.put("planTable", targetList); } return result; } @Override public void exportExcel(HttpServletResponse response) { 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 { AjaxResult stat = selectResourceDateStat(); List<String> days = (List<String>) stat.get("planTitle"); List<Map<String, List<ApsResourceDateStat>>> table= (List<Map<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()); dataRow.createCell(j*3+3).setCellValue(apsResourceDateStat.getCapacityLoad().doubleValue()+"%"); } } } 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) 16); titleFont.setBold(true); style.setFont(titleFont); DataFormat dataFormat = wb.createDataFormat(); style.setDataFormat(dataFormat.getFormat("@")); styles.put("title", style); return styles; } } aps-modules/aps-core/src/main/resources/mapper/core/ApsPartRouteStatMapper.xml
@@ -17,10 +17,11 @@ <result property="delFlag" column="del_flag" /> <result property="createBy" column="create_by" /> <result property="batchNumber" column="batch_number" /> <result property="resourceGroupName" column="resource_group_name" /> </resultMap> <sql id="selectApsPartRouteStatVo"> select id, work_order_no, road_process_number, current_process_number, production_quantity, standard_time, process_total_time, process_plan_start_day, design_times, del_flag, create_by, batch_number from aps_part_route_stat select id, work_order_no, road_process_number, current_process_number, production_quantity, standard_time, process_total_time, process_plan_start_day, design_times, del_flag, create_by, batch_number ,resource_group_name from aps_part_route_stat </sql> <select id="selectApsPartRouteStatList" parameterType="ApsPartRouteStat" resultMap="ApsPartRouteStatResult"> @@ -53,11 +54,12 @@ <if test="productionQuantity != null">production_quantity,</if> <if test="standardTime != null">standard_time,</if> <if test="processTotalTime != null">process_total_time,</if> <if test="processPlanStartDay != null and processPlanStartDay != ''">process_plan_start_day,</if> <if test="processPlanStartDay != null ">process_plan_start_day,</if> <if test="designTimes != null">design_times,</if> <if test="delFlag != null">del_flag,</if> <if test="createBy != null">create_by,</if> <if test="batchNumber != null">batch_number,</if> <if test="resourceGroupName != null">resource_group_name,</if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="id != null">#{id},</if> @@ -67,11 +69,12 @@ <if test="productionQuantity != null">#{productionQuantity},</if> <if test="standardTime != null">#{standardTime},</if> <if test="processTotalTime != null">#{processTotalTime},</if> <if test="processPlanStartDay != null and processPlanStartDay != ''">#{processPlanStartDay},</if> <if test="processPlanStartDay != null">#{processPlanStartDay},</if> <if test="designTimes != null">#{designTimes},</if> <if test="delFlag != null">#{delFlag},</if> <if test="createBy != null">#{createBy},</if> <if test="batchNumber != null">#{batchNumber},</if> <if test="resourceGroupName != null">#{resourceGroupName},</if> </trim> </insert> @@ -109,7 +112,7 @@ </update> <select id="selectPartRoutStat" resultMap="ApsPartRouteStatResult" > select rt.work_order_no, rt.process_name, rt.process_name as resource_group_name, cast( rt.process_number as numeric(18,2)) as road_process_number, cast( pl.process_number as numeric(18,2)) as current_process_number, pl.production_quantity, @@ -122,13 +125,40 @@ left join aps_resource_group as rs on rs.resource_group_name=rt.process_name where pl.del_flag='0' and rt.del_flag='0' /*é¶ä»¶è®¡åç¶æä¸ºï¼éå®å·¥ */ and ( pl.order_status!='' and ( pl.order_status!='3' or pl.order_status!='å®å·¥') ) /*å·¥èºè·¯çº¿çå·¥åºå·>=é¶ä»¶è®¡åçå½åå·¥åº*/ and cast( rt.process_number as decimal(18,2)) >= cast( pl.process_number as decimal(18,2)) /*å·¥åºè®¡åå¼å·¥æ¥ <= èµæºç»çæªæ¢æ¥æ*/ and rt.process_plan_start_day<=rs.request_date /*èµæºç»éæ±æªæ¢æ¥æ<=å½åæ¥æ+15天*/ and rs.request_date<=(current_date + INTERVAL '15 day') and ( pl.document_status is not null and ( pl.document_status!='3' or pl.order_status!='å®å·¥') ) /*å·¥åºè®¡åå¼å·¥æ¥ å°äºçäº èµæºç»çæªæ¢æ¥æ*/ and rt.process_plan_start_day <= rs.request_date order by rt.work_order_no,process_plan_start_day </select> <resultMap type="ApsResourceDateStat" id="ApsResourceDateStatResult"> <result property="planDay" column="plan_day" /> <result property="resourceName" column="resource_name" /> <result property="requireTimes" column="require_times" /> <result property="designTimes" column="design_times" /> <result property="capacityLoad" column="capacity_load" /> <result property="resourceGroupName" column="resource_name" /> </resultMap> <select id="selectResourceDateStat" resultMap="ApsResourceDateStatResult"> with pl as (select DATE(st.process_plan_start_day) AS plan_day, resource_group_name as resource_name, sum(process_total_time) as require_times from aps_part_route_stat as st where st.del_flag = '0' group by resource_group_name, plan_day order by plan_day,resource_group_name ) select pl.plan_day ,pl.resource_name , require_times , (gp.theory_hours * gp.devices_quantity) as design_times , ((gp.theory_hours * gp.devices_quantity) / require_times*100) as capacity_load from pl left join aps_resource_group as gp on pl.resource_name = gp.resource_group_name where gp.del_flag = '0' </select> </mapper>