refactor(anneal): 优化炉火实绩明细数据结构和查询逻辑
- 将WmsAnnealPerformanceDetailVo中的coils列表改为单个coil对象 - 新增parentCoilIds字段支持按父卷ID批量查询加工后钢卷 - 实现通过parentCoilId查找split后子卷的映射逻辑 - 添加直接查询未split原卷的备用查询机制 - 重构详情数据扁平化处理,每个计划钢卷创建独立详情记录 - 优化统计信息重新计算逻辑,准确统计过滤后的计划数量 - 移除WmsMaterialCoilVo中不再使用的furnaceLevel字段
This commit is contained in:
@@ -443,5 +443,8 @@ public class WmsMaterialCoilBo extends BaseEntity {
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Boolean excludeScheduledDetail;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String parentCoilIds;
|
||||
}
|
||||
|
||||
|
||||
@@ -261,10 +261,10 @@ public class WmsMaterialCoilVo extends BaseEntity {
|
||||
*/
|
||||
private Integer exclusiveStatus;
|
||||
|
||||
/**
|
||||
* 炉火层级(1=一层,2=二层,3=三层)
|
||||
*/
|
||||
private Integer furnaceLevel;
|
||||
// /**
|
||||
// * 炉火层级(1=一层,2=二层,3=三层)
|
||||
// */
|
||||
// private Integer furnaceLevel;
|
||||
|
||||
/**
|
||||
* 是否已被发货单明细绑定(true=不可再次绑定)
|
||||
|
||||
@@ -5,7 +5,6 @@ import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 炉火实绩明细视图对象
|
||||
@@ -42,5 +41,5 @@ public class WmsAnnealPerformanceDetailVo {
|
||||
|
||||
private Integer furnaceLevel;
|
||||
|
||||
private List<WmsMaterialCoilVo> coils;
|
||||
private WmsMaterialCoilVo coil;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.klp.service.impl;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.domain.bo.WmsAnnealPerformanceBo;
|
||||
import com.klp.domain.bo.WmsMaterialCoilBo;
|
||||
import com.klp.domain.vo.WmsMaterialCoilVo;
|
||||
@@ -86,30 +87,61 @@ public class WmsAnnealPerformanceServiceImpl implements IWmsAnnealPerformanceSer
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 批量查询钢卷信息
|
||||
Map<Long, WmsMaterialCoilVo> coilVoMap = new HashMap<>();
|
||||
// 批量查询钢卷信息(通过parentCoilId查加工后的卷)
|
||||
// 加工后钢卷的parentCoilId指向加工前钢卷的coilId,需要以此建立映射
|
||||
Map<Long, WmsMaterialCoilVo> parentIdToCoilMap = new HashMap<>();
|
||||
if (!allCoilIds.isEmpty()) {
|
||||
WmsMaterialCoilBo coilBo = new WmsMaterialCoilBo();
|
||||
coilBo.setCoilIds(allCoilIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
|
||||
coilBo.setParentCoilIds(allCoilIds.stream().map(String::valueOf).collect(Collectors.joining("-")));
|
||||
PageQuery pageQuery = new PageQuery();
|
||||
pageQuery.setPageNum(1);
|
||||
pageQuery.setPageSize(Integer.MAX_VALUE);
|
||||
TableDataInfo<WmsMaterialCoilVo> coilPage = materialCoilService.queryPageList(coilBo, pageQuery);
|
||||
if (coilPage != null && coilPage.getRows() != null) {
|
||||
for (WmsMaterialCoilVo coilVo : coilPage.getRows()) {
|
||||
if (coilVo.getCoilId() != null) {
|
||||
coilVoMap.put(coilVo.getCoilId(), coilVo);
|
||||
// 加工后钢卷的parentCoilId存的是加工前coilId
|
||||
String parentCoilIdStr = coilVo.getParentCoilId();
|
||||
if (StringUtils.isNotBlank(parentCoilIdStr)) {
|
||||
for (String pid : parentCoilIdStr.split(",")) {
|
||||
String trimmed = pid.trim();
|
||||
if (StringUtils.isNotBlank(trimmed)) {
|
||||
try {
|
||||
parentIdToCoilMap.put(Long.parseLong(trimmed), coilVo);
|
||||
} catch (NumberFormatException e) {
|
||||
// 忽略无效ID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 用于重新计算统计信息
|
||||
// 查询2:直接通过coilId查未split的钢卷(它们本身就是加工后的卷)
|
||||
Map<Long, WmsMaterialCoilVo> directCoilMap = new HashMap<>();
|
||||
{
|
||||
WmsMaterialCoilBo directBo = new WmsMaterialCoilBo();
|
||||
directBo.setCoilIds(allCoilIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
|
||||
PageQuery pq = new PageQuery();
|
||||
pq.setPageNum(1);
|
||||
pq.setPageSize(Integer.MAX_VALUE);
|
||||
TableDataInfo<WmsMaterialCoilVo> directPage = materialCoilService.queryPageList(directBo, pq);
|
||||
if (directPage != null && directPage.getRows() != null) {
|
||||
for (WmsMaterialCoilVo cv : directPage.getRows()) {
|
||||
if (cv.getCoilId() != null) {
|
||||
directCoilMap.put(cv.getCoilId(), cv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重新构建details:每条detail对应一个计划钢卷,logicWarehouseId/furnaceLevel从planCoil获取
|
||||
List<WmsAnnealPerformanceDetailVo> flatDetails = new ArrayList<>();
|
||||
Long filteredPlanCount = 0L;
|
||||
Long filteredCoilCount = 0L;
|
||||
BigDecimal filteredTotalWeight = BigDecimal.ZERO;
|
||||
Set<Long> countedPlanIds = new HashSet<>();
|
||||
|
||||
// 处理每个计划
|
||||
for (WmsAnnealPerformanceDetailVo detail : details) {
|
||||
Long planId = detail.getPlanId();
|
||||
List<WmsFurnacePlanCoil> planCoils = planCoilsMap.get(planId);
|
||||
@@ -118,34 +150,22 @@ public class WmsAnnealPerformanceServiceImpl implements IWmsAnnealPerformanceSer
|
||||
continue;
|
||||
}
|
||||
|
||||
// 设置出炉时的逻辑库区到detail级别(取第一个非空的logicWarehouseId)
|
||||
for (WmsFurnacePlanCoil planCoil : planCoils) {
|
||||
if (planCoil.getLogicWarehouseId() != null) {
|
||||
detail.setLogicWarehouseId(planCoil.getLogicWarehouseId());
|
||||
detail.setLogicWarehouseName(logicWarehouseNameMap.get(planCoil.getLogicWarehouseId()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 为每个钢卷设置炉火层级和钢卷信息(不覆盖钢卷本身的逻辑库区)
|
||||
List<WmsMaterialCoilVo> coilVos = new ArrayList<>();
|
||||
for (WmsFurnacePlanCoil planCoil : planCoils) {
|
||||
Long coilId = planCoil.getCoilId();
|
||||
if (coilId == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
WmsMaterialCoilVo coilVo = coilVoMap.get(coilId);
|
||||
// 优先取split后的子卷,没有再取原卷(未split场景)
|
||||
WmsMaterialCoilVo coilVo = parentIdToCoilMap.get(coilId);
|
||||
if (coilVo == null) {
|
||||
coilVo = directCoilMap.get(coilId);
|
||||
}
|
||||
if (coilVo == null) {
|
||||
coilVo = new WmsMaterialCoilVo();
|
||||
coilVo.setCoilId(coilId);
|
||||
}
|
||||
|
||||
// 保持钢卷本身的warehouseId/warehouseName不变,不覆盖
|
||||
|
||||
// 设置炉火层级
|
||||
coilVo.setFurnaceLevel(planCoil.getFurnaceLevel());
|
||||
|
||||
// 如果传入了筛选条件,只保留匹配的钢卷
|
||||
if (bo.getEnterCoilNo() != null && !bo.getEnterCoilNo().isEmpty()) {
|
||||
if (coilVo.getEnterCoilNo() == null ||
|
||||
@@ -167,35 +187,38 @@ public class WmsAnnealPerformanceServiceImpl implements IWmsAnnealPerformanceSer
|
||||
}
|
||||
}
|
||||
|
||||
coilVos.add(coilVo);
|
||||
}
|
||||
// 为每个planCoil创建独立的detail,携带自身的logicWarehouseId/furnaceLevel
|
||||
WmsAnnealPerformanceDetailVo coilDetail = new WmsAnnealPerformanceDetailVo();
|
||||
coilDetail.setPlanId(detail.getPlanId());
|
||||
coilDetail.setPlanNo(detail.getPlanNo());
|
||||
coilDetail.setTargetFurnaceId(detail.getTargetFurnaceId());
|
||||
coilDetail.setTargetFurnaceName(detail.getTargetFurnaceName());
|
||||
coilDetail.setActualStartTime(detail.getActualStartTime());
|
||||
coilDetail.setEndTime(detail.getEndTime());
|
||||
coilDetail.setLogicWarehouseId(planCoil.getLogicWarehouseId());
|
||||
coilDetail.setLogicWarehouseName(planCoil.getLogicWarehouseId() != null
|
||||
? logicWarehouseNameMap.get(planCoil.getLogicWarehouseId()) : null);
|
||||
coilDetail.setFurnaceLevel(planCoil.getFurnaceLevel());
|
||||
coilDetail.setCoil(coilVo);
|
||||
flatDetails.add(coilDetail);
|
||||
|
||||
// 如果过滤后没有钢卷,跳过该计划
|
||||
if (!coilVos.isEmpty()) {
|
||||
detail.setCoils(coilVos);
|
||||
filteredPlanCount++;
|
||||
filteredCoilCount += coilVos.size();
|
||||
BigDecimal planWeight = coilVos.stream()
|
||||
.map(c -> c.getNetWeight() != null ? c.getNetWeight() : BigDecimal.ZERO)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
filteredTotalWeight = filteredTotalWeight.add(planWeight);
|
||||
filteredCoilCount++;
|
||||
if (coilVo.getNetWeight() != null) {
|
||||
filteredTotalWeight = filteredTotalWeight.add(coilVo.getNetWeight());
|
||||
}
|
||||
countedPlanIds.add(planId);
|
||||
}
|
||||
}
|
||||
|
||||
// 移除没有钢卷的计划
|
||||
details.removeIf(detail -> detail.getCoils() == null || detail.getCoils().isEmpty());
|
||||
filteredPlanCount = (long) countedPlanIds.size();
|
||||
|
||||
// 如果传入了筛选条件,重新计算统计信息
|
||||
if ((bo.getEnterCoilNo() != null && !bo.getEnterCoilNo().isEmpty())
|
||||
|| (bo.getCurrentCoilNo() != null && !bo.getCurrentCoilNo().isEmpty())
|
||||
|| bo.getWarehouseId() != null
|
||||
|| bo.getCoilWarehouseId() != null) {
|
||||
// 替换details并重新计算统计信息
|
||||
details = flatDetails;
|
||||
summary.setPlanCount(filteredPlanCount);
|
||||
summary.setCoilCount(filteredCoilCount);
|
||||
summary.setTotalWeight(filteredTotalWeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WmsAnnealPerformanceVo vo = new WmsAnnealPerformanceVo();
|
||||
vo.setSummary(summary);
|
||||
|
||||
@@ -1253,6 +1253,31 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
qw.in("mc.coil_id", coilIdList);
|
||||
}
|
||||
}
|
||||
// 根据parentCoilId筛选(查询某个原始钢卷的加工后子卷,支持逗号分隔多ID)
|
||||
// 注意此处合卷不能用
|
||||
if (StringUtils.isNotBlank(bo.getParentCoilIds())) {
|
||||
String[] parentIdArray = bo.getParentCoilIds().split("-");
|
||||
List<String> findInSetConditions = new ArrayList<>();
|
||||
for (String pid : parentIdArray) {
|
||||
String trimmed = pid.trim();
|
||||
if (StringUtils.isNotBlank(trimmed)) {
|
||||
try {
|
||||
Long.parseLong(trimmed);
|
||||
findInSetConditions.add("FIND_IN_SET('" + trimmed + "', mc.parent_coil_id)");
|
||||
} catch (NumberFormatException e) {
|
||||
// 忽略无效ID
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!findInSetConditions.isEmpty()) {
|
||||
qw.and(w -> {
|
||||
for (int i = 0; i < findInSetConditions.size(); i++) {
|
||||
if (i > 0) w.or();
|
||||
w.apply(findInSetConditions.get(i));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// // 仅查询未发货且未绑定在发货计划里的钢卷
|
||||
// if (Boolean.TRUE.equals(bo.getOnlyUnshippedAndUnplanned())) {
|
||||
// // 未发货:排除状态=1(已出库/已发货)
|
||||
|
||||
Reference in New Issue
Block a user