Merge remote-tracking branch 'origin/dev' into dev
| | |
| | | apsGasPipingRouteStatService.exportExcel(response, apsGasPipingRouteStat); |
| | | } |
| | | |
| | | @PostMapping("/saveGasPipingRoutStateList") |
| | | public void saveGasPipingRoutStateList() |
| | | { |
| | | apsGasPipingRouteStatService.saveGasPipingRoutStateList(); |
| | | } |
| | | |
| | | } |
| | |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.apache.commons.lang3.builder.ToStringBuilder; |
| | | import org.apache.commons.lang3.builder.ToStringStyle; |
| | | import org.springframework.data.annotation.Transient; |
| | |
| | | * @author hjy |
| | | * @date 2025-04-24 |
| | | */ |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Schema(description = "气体管路产能负载统计实体类") |
| | | @Data |
| | | public class ApsGasPipingRouteStat extends BaseEntity |
| | |
| | | /** 工序号 */ |
| | | @Excel(name = "工序号") |
| | | @Schema(description = "工序号", type = "String") |
| | | private String roadProcessNumber; |
| | | private BigDecimal roadProcessNumber; |
| | | |
| | | /** 当前工序号 */ |
| | | @Excel(name = "当前工序号") |
| | |
| | | @Transient |
| | | private String searchType; |
| | | |
| | | private Boolean warning; |
| | | private Integer num; |
| | | |
| | | /** 计划完成日 */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @Excel(name = "计划完工日", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") |
| | |
| | | * @return |
| | | */ |
| | | public int insertApsGasPipingRouteStatBatch(List<ApsGasPipingRouteStat> apsGasPipingRouteStatList); |
| | | |
| | | List<ApsGasPipingRouteStat> queryTempStat(); |
| | | } |
| | |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.aps.core.domain.ApsGasPipingRouteStat; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.List; |
| | | |
| | |
| | | * @param response |
| | | */ |
| | | public void exportExcel(HttpServletResponse response, ApsGasPipingRouteStat apsGasPipingRouteStat); |
| | | |
| | | void saveGasPipingProcessStat(); |
| | | |
| | | @Transactional |
| | | void saveGasPipingRoutStateList(); |
| | | } |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | |
| | | 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); |
| | | } |
| | | |
| | | } |
| | |
| | | <result property="planStartYear" column="plan_start_year" /> |
| | | <result property="planStartMonth" column="plan_start_month" /> |
| | | <result property="planStartDay" column="plan_start_day" /> |
| | | <result property="processPlanEndDay" column="process_plan_end_day" /> |
| | | <result property="orderPlanEndDay" column="order_plan_end_day" /> |
| | | <result property="routeProcessNumber" column="route_process_number" /> |
| | | <result property="warning" column="warning" /> |
| | | </resultMap> |
| | | |
| | | <sql id="selectApsGasPipingRouteStatVo"> |
| | | 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, process_name, create_time, item_number, standard_dosage, process_total_dosage, design_capacity, major, plan_start_year, plan_start_month, plan_start_day from aps_gas_piping_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, |
| | | process_name, create_time, item_number, standard_dosage, |
| | | process_total_dosage, design_capacity, major, plan_start_year, |
| | | plan_start_month, plan_start_day , warning |
| | | from aps_gas_piping_route_stat |
| | | </sql> |
| | | |
| | | <select id="selectApsGasPipingRouteStatList" parameterType="ApsGasPipingRouteStat" resultMap="ApsGasPipingRouteStatResult"> |
| | |
| | | <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="planStartYear != null">plan_start_year,</if> |
| | | <if test="planStartMonth != null">plan_start_month,</if> |
| | | <if test="planStartDay != null">plan_start_day,</if> |
| | | <if test="processPlanEndDay != null">process_plan_end_day,</if> |
| | | <if test="orderPlanEndDay != null">order_plan_end_day,</if> |
| | | <if test="batchNumber != null">batch_number,</if> |
| | | <if test="warning != null">warning,</if> |
| | | </trim> |
| | | <trim prefix="values (" suffix=")" suffixOverrides=","> |
| | | <if test="id != null">#{id},</if> |
| | |
| | | <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="planStartYear != null">#{planStartYear},</if> |
| | | <if test="planStartMonth != null">#{planStartMonth},</if> |
| | | <if test="planStartDay != null">#{planStartDay},</if> |
| | | <if test="processPlanEndDay != null">#{processPlanEndDay},</if> |
| | | <if test="orderPlanEndDay != null">#{orderPlanEndDay},</if> |
| | | <if test="batchNumber != null">#{batchNumber},</if> |
| | | <if test="warning != null">#{warning},</if> |
| | | </trim> |
| | | </insert> |
| | | |
| | |
| | | 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, process_name, |
| | | create_time, item_number, standard_dosage, process_total_dosage, design_capacity, major, |
| | | plan_start_year, plan_start_month, plan_start_day,batch_number,process_plan_end_day |
| | | plan_start_year, plan_start_month, plan_start_day,batch_number,process_plan_end_day,warning |
| | | ) |
| | | VALUES |
| | | <foreach collection="apsGasPipingRouteStatList" item="stat" separator=","> |
| | |
| | | #{stat.standardTime}, #{stat.processTotalTime}, #{stat.processPlanStartDay}, #{stat.designTimes}, #{stat.delFlag}, |
| | | #{stat.createBy}, #{stat.processName}, #{stat.createTime}, #{stat.itemNumber}, #{stat.standardDosage}, |
| | | #{stat.processTotalDosage}, #{stat.designCapacity}, #{stat.major}, #{stat.planStartYear}, |
| | | #{stat.planStartMonth}, #{stat.planStartDay}, #{stat.batchNumber}, #{stat.processPlanEndDay} |
| | | #{stat.planStartMonth}, #{stat.planStartDay}, #{stat.batchNumber}, #{stat.processPlanEndDay},#{stat.warning} |
| | | ) |
| | | </foreach> |
| | | |
| | | </insert> |
| | | |
| | | <select id="queryTempStat" resultMap="ApsGasPipingRouteStatResult" > |
| | | select row_number() over (partition by rt.work_order_no order by rt.process_number desc ) as num, |
| | | rt.work_order_no, |
| | | rt.process_name, |
| | | cast(rt.process_number as numeric(18, 2)) as road_process_number, |
| | | cast(rt.process_number as numeric(18, 2)) as route_process_number, |
| | | cast(pl.process_number as numeric(18, 2)) as current_process_number, |
| | | pl.production_quantity, |
| | | rt.standard_time, |
| | | (rt.standard_time * pl.production_quantity) as process_total_time, |
| | | rt.process_plan_start_day, |
| | | rt.process_plan_end_day, |
| | | pl.plan_end_day as order_plan_end_day, |
| | | rt.item_no as item_number, |
| | | pl.plan_type as major, |
| | | false as warning |
| | | from aps_gas_piping_plan as pl |
| | | left join aps_process_route as rt on pl.document_number = rt.work_order_no |
| | | where pl.document_number is not null and rt.work_order_no is not null |
| | | order by rt.work_order_no asc, rt.process_number desc |
| | | </select> |
| | | |
| | | </mapper> |