|
@@ -8,9 +8,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
-import org.jeecg.common.api.vo.Result;
|
|
|
import org.jeecg.common.util.DateUtils;
|
|
|
-import org.jeecg.common.util.SpringContextUtils;
|
|
|
import org.jeecg.common.util.oConvertUtils;
|
|
|
import org.jeecg.modules.actualControl.billetActual.billetActual.entity.BilletRulerConfig;
|
|
|
import org.jeecg.modules.actualControl.billetActual.billetActual.mapper.BilletRulerConfigMapper;
|
|
@@ -32,7 +30,6 @@ import org.jeecg.modules.billet.rollClubOne.vo.RollClubOneVO;
|
|
|
import org.jeecg.modules.billet.rollHeight.entity.DestinationStatistics;
|
|
|
import org.jeecg.modules.billet.rollHeight.entity.DestinationStatisticsDetails;
|
|
|
import org.jeecg.modules.billet.storageBill.vo.StorageCenterExportRow;
|
|
|
-import org.jeecg.modules.carUnit.entity.SysDict;
|
|
|
import org.jeecg.modules.carUnit.service.ISysDictService;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
@@ -316,76 +313,72 @@ public class RollClubOneServiceImpl extends ServiceImpl<RollClubOneMapper, RollC
|
|
|
//构造数据
|
|
|
Map<String, RollClubOneHeatVO.RollOneHeatNo> rollOneMap = buildRollOneHeatNoMap(list); // 根据棒一明细构建
|
|
|
|
|
|
- // 1. 按炉号聚合棒一数据到 StorageCenterHeatNoInvoicingVO
|
|
|
+ // 1. 构建 heatNoVOMap:聚合棒一明细
|
|
|
Map<String, RollClubOneHeatVO> heatNoVOMap = new HashMap<>();
|
|
|
- for (String heatNo : rollOneMap.keySet()) {
|
|
|
- RollClubOneHeatVO vo = heatNoVOMap.computeIfAbsent(heatNo, k -> new RollClubOneHeatVO());
|
|
|
- RollClubOneHeatVO.RollOneHeatNo rollOne = rollOneMap.get(heatNo);
|
|
|
+ for (Map.Entry<String, RollClubOneHeatVO.RollOneHeatNo> entry : rollOneMap.entrySet()) {
|
|
|
+ String key = entry.getKey(); // key: heatNo_shift_shiftGroup
|
|
|
+ RollClubOneHeatVO.RollOneHeatNo rollOne = entry.getValue();
|
|
|
+ RollClubOneHeatVO vo = heatNoVOMap.computeIfAbsent(key, k -> new RollClubOneHeatVO());
|
|
|
vo.setRollClubOneDetails(rollOne);
|
|
|
-
|
|
|
}
|
|
|
|
|
|
+ // 2. 提取所有 heatNo(用于查询 billet_hotsend)
|
|
|
+ Set<String> allHeatNos = rollOneMap.keySet().stream()
|
|
|
+ .map(k -> k.split("_")[0])
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
|
- Set<String> allHeatNos = new HashSet<>();
|
|
|
- allHeatNos.addAll(rollOneMap.keySet());
|
|
|
-
|
|
|
+ // 3. 查询 billet_hotsend(只查有用的炉号)
|
|
|
Map<String, RollClubOneVO.HeatNoDetail> heatNoDetailMap = new HashMap<>();
|
|
|
-
|
|
|
-
|
|
|
if (CollectionUtils.isNotEmpty(allHeatNos)) {
|
|
|
LambdaQueryWrapper<BilletHotsend> hotsendWrapper = new LambdaQueryWrapper<>();
|
|
|
- hotsendWrapper.in(BilletHotsend::getHeatNo, allHeatNos); // 只查用到的炉号
|
|
|
+ hotsendWrapper.in(BilletHotsend::getHeatNo, allHeatNos);
|
|
|
List<BilletHotsend> hotsendList = billetHotsendBaseMapper.selectList(hotsendWrapper);
|
|
|
|
|
|
if (CollectionUtils.isNotEmpty(hotsendList)) {
|
|
|
Map<String, List<BilletHotsend>> hotsendGroupMap = hotsendList.stream()
|
|
|
- .collect(Collectors.groupingBy(BilletHotsend::getHeatNo));
|
|
|
+ .collect(Collectors.groupingBy(h -> h.getHeatNo() + "_" + h.getShift() + "_" + h.getShiftGroup()));
|
|
|
|
|
|
for (Map.Entry<String, List<BilletHotsend>> entry : hotsendGroupMap.entrySet()) {
|
|
|
- String heatNo = entry.getKey();
|
|
|
+ String key = entry.getKey(); // heatNo_shift_shiftGroup
|
|
|
List<BilletHotsend> hotsends = entry.getValue();
|
|
|
- if (CollectionUtils.isEmpty(hotsends)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- // 先定义 rollOne,初始值为 null
|
|
|
+ if (CollectionUtils.isEmpty(hotsends)) continue;
|
|
|
+
|
|
|
+ String[] parts = key.split("_", 3);
|
|
|
+ String heatNo = parts[0];
|
|
|
+ String shift = parts[1];
|
|
|
+ String shiftGroup = parts[2];
|
|
|
+
|
|
|
RollClubOneHeatVO.RollOneHeatNo rollOne = null;
|
|
|
- RollClubOneHeatVO vo = heatNoVOMap.get(heatNo);
|
|
|
+ RollClubOneHeatVO vo = heatNoVOMap.get(key);
|
|
|
if (vo != null) {
|
|
|
rollOne = vo.getRollClubOneDetails();
|
|
|
}
|
|
|
- // 初始化累计值
|
|
|
- int totalAmount = 0;
|
|
|
- BigDecimal totalWeight = BigDecimal.ZERO;
|
|
|
|
|
|
- if (rollOne != null && rollOne.getTotalAmount() != null) {
|
|
|
- totalAmount += rollOne.getTotalAmount();
|
|
|
- }
|
|
|
- if (rollOne != null && rollOne.getTotalWeight() != null) {
|
|
|
- totalWeight = totalWeight.add(rollOne.getTotalWeight());
|
|
|
- }
|
|
|
- RollClubOneVO.HeatNoDetail detail = new RollClubOneVO.HeatNoDetail();
|
|
|
- detail.setHeatNo(heatNo);
|
|
|
- // 按 createTime 降序,选最新记录
|
|
|
+ // 计算总支数、总重量
|
|
|
+ int totalAmount = rollOne != null && rollOne.getTotalAmount() != null ? rollOne.getTotalAmount() : 0;
|
|
|
+ BigDecimal totalWeight = rollOne != null && rollOne.getTotalWeight() != null ? rollOne.getTotalWeight() : BigDecimal.ZERO;
|
|
|
+
|
|
|
+ // 按 createTime 降序取最新 billetHotsend
|
|
|
hotsends.sort(Comparator.comparing(BilletHotsend::getCreateTime, Comparator.nullsLast(Date::compareTo)).reversed());
|
|
|
BilletHotsend latest = hotsends.get(0);
|
|
|
|
|
|
- // 这里用优先级取 createTime
|
|
|
+ // 取 createTime
|
|
|
Date finalCreateTime = null;
|
|
|
- if (rollOne != null
|
|
|
- && rollOne.getRollSendDetails() != null
|
|
|
- && !rollOne.getRollSendDetails().isEmpty()
|
|
|
+ if (rollOne != null && CollectionUtils.isNotEmpty(rollOne.getRollSendDetails())
|
|
|
&& rollOne.getRollSendDetails().get(0).getCreateTime() != null) {
|
|
|
-
|
|
|
finalCreateTime = rollOne.getRollSendDetails().get(0).getCreateTime();
|
|
|
} else {
|
|
|
finalCreateTime = latest.getCreateTime();
|
|
|
}
|
|
|
|
|
|
+ RollClubOneVO.HeatNoDetail detail = new RollClubOneVO.HeatNoDetail();
|
|
|
+ detail.setHeatNo(heatNo);
|
|
|
+ detail.setShift(shift);
|
|
|
+ detail.setShiftGroup(shiftGroup);
|
|
|
detail.setCreateTime(finalCreateTime);
|
|
|
detail.setHeatNoAmount(totalAmount);
|
|
|
detail.setHeatNoWeight(totalWeight);
|
|
|
|
|
|
- // ccmNo 可能为空或非数字,需要校验
|
|
|
try {
|
|
|
if (StringUtils.isNotBlank(latest.getCcmNo())) {
|
|
|
detail.setCcmNo(Integer.valueOf(latest.getCcmNo()));
|
|
@@ -394,9 +387,7 @@ public class RollClubOneServiceImpl extends ServiceImpl<RollClubOneMapper, RollC
|
|
|
log.warn("炉号 {} 的 ccmNo 非法值:{}", heatNo, latest.getCcmNo(), e);
|
|
|
}
|
|
|
|
|
|
- detail.setShift(latest.getShift());
|
|
|
- detail.setShiftGroup(latest.getShiftGroup());
|
|
|
- heatNoDetailMap.put(heatNo, detail);
|
|
|
+ heatNoDetailMap.put(key, detail);
|
|
|
}
|
|
|
} else {
|
|
|
log.warn("未查询到 billet_hotsend 记录,heatNo 列表为:{}", allHeatNos);
|
|
@@ -405,24 +396,22 @@ public class RollClubOneServiceImpl extends ServiceImpl<RollClubOneMapper, RollC
|
|
|
log.warn("heatNo 集合为空,跳过 billet_hotsend 查询");
|
|
|
}
|
|
|
|
|
|
- if (CollectionUtils.isNotEmpty(allHeatNos)) {
|
|
|
- for (String heatNo : allHeatNos) {
|
|
|
- RollClubOneVO invoicingVO = new RollClubOneVO();
|
|
|
+ // 4. 组装结果:遍历 heatNo_shift_shiftGroup 聚合数据
|
|
|
+ for (String key : rollOneMap.keySet()) {
|
|
|
+ RollClubOneVO invoicingVO = new RollClubOneVO();
|
|
|
|
|
|
- // 设置基础详情
|
|
|
- RollClubOneVO.HeatNoDetail detail = heatNoDetailMap.get(heatNo);
|
|
|
- invoicingVO.setHeatNoDetails(detail == null ? Collections.emptyList() : Collections.singletonList(detail));
|
|
|
+ // 设置明细
|
|
|
+ RollClubOneVO.HeatNoDetail detail = heatNoDetailMap.get(key);
|
|
|
+ invoicingVO.setHeatNoDetails(detail == null ? Collections.emptyList() : Collections.singletonList(detail));
|
|
|
|
|
|
- // 设置聚合的棒一数据
|
|
|
- RollClubOneHeatVO heatNoInvoicing = heatNoVOMap.get(heatNo);
|
|
|
- invoicingVO.setStorageCenterHeatNoInvoicing(heatNoInvoicing);
|
|
|
+ // 设置棒一聚合数据
|
|
|
+ RollClubOneHeatVO heatNoInvoicing = heatNoVOMap.get(key);
|
|
|
+ invoicingVO.setStorageCenterHeatNoInvoicing(heatNoInvoicing);
|
|
|
|
|
|
- resultList.add(invoicingVO);
|
|
|
- }
|
|
|
- } else {
|
|
|
- log.warn("allHeatNos 为空,未生成棒一信息结果");
|
|
|
+ resultList.add(invoicingVO);
|
|
|
}
|
|
|
|
|
|
+ // 5. 按 createTime 倒序排序
|
|
|
resultList.sort(Comparator.comparing(
|
|
|
vo -> vo.getHeatNoDetails() == null || vo.getHeatNoDetails().isEmpty()
|
|
|
? null
|
|
@@ -514,111 +503,109 @@ public class RollClubOneServiceImpl extends ServiceImpl<RollClubOneMapper, RollC
|
|
|
}
|
|
|
|
|
|
|
|
|
- public Map<String, RollClubOneHeatVO.RollOneHeatNo> buildRollOneHeatNoMap(List<BilletOriginalProductRecord> oneList) {
|
|
|
+ public Map<String, RollClubOneHeatVO.RollOneHeatNo> buildRollOneHeatNoMap(
|
|
|
+ List<BilletOriginalProductRecord> oneList) {
|
|
|
Map<String, RollClubOneHeatVO.RollOneHeatNo> resultMap = new HashMap<>();
|
|
|
Map<String, BigDecimal> lengthWeightCache = new HashMap<>();
|
|
|
Map<String, String> lengthSpecCache = new HashMap<>();
|
|
|
- Map<String, Integer> lengthCumulativeCountMap = new HashMap<>(); // 新增:记录每种定尺的累计终止根数
|
|
|
+ Map<String, Integer> lengthCumulativeCountMap = new HashMap<>();
|
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
|
for (BilletOriginalProductRecord record : oneList) {
|
|
|
- Map<String, Integer> lengthCountMap = new HashMap<>();
|
|
|
- RollClubOneHeatVO.RollOneHeatNo rollOneHeatNo = new RollClubOneHeatVO.RollOneHeatNo();
|
|
|
- List<RollClubOneHeatVO.SizeDetail> sizeDetailsList = new ArrayList<>();
|
|
|
- List<RollClubOneHeatVO.RollSendDetail> rollSendDetailList = new ArrayList<>();
|
|
|
- String brandNum = "";
|
|
|
-
|
|
|
- if (record.getGrade() != null) {
|
|
|
- brandNum = Optional.ofNullable(record.getGrade())
|
|
|
- .map(bn -> sysDictService.queryDictTextByKey("billet_spec", bn))
|
|
|
- .orElseGet(() -> sysDictService.queryDictTextByKey("billet_spec", "5"));
|
|
|
- }
|
|
|
-
|
|
|
- rollOneHeatNo.setBrandNum(brandNum);
|
|
|
+ // 1. 计算复合 key
|
|
|
+ String heatNo = record.getHeatNo();
|
|
|
+ String shift = record.getShift();
|
|
|
+ String shiftGroup = record.getShiftGroup();
|
|
|
+ String key = heatNo + "_" + shift + "_" + shiftGroup;
|
|
|
|
|
|
+ // 2. 新建 VO 和中间统计结构
|
|
|
+ RollClubOneHeatVO.RollOneHeatNo rollOneHeatNo = new RollClubOneHeatVO.RollOneHeatNo();
|
|
|
rollOneHeatNo.setId(record.getId());
|
|
|
rollOneHeatNo.setConfirmTime(record.getConfirmTime());
|
|
|
+ // 品号从 grade 映射
|
|
|
+ String brandNum = Optional.ofNullable(record.getGrade())
|
|
|
+ .map(bn -> sysDictService.queryDictTextByKey("billet_spec", bn))
|
|
|
+ .orElseGet(() -> sysDictService.queryDictTextByKey("billet_spec", "5"));
|
|
|
+ rollOneHeatNo.setBrandNum(brandNum);
|
|
|
|
|
|
- String detailJson = record.getRollClubOneDetails();
|
|
|
+ List<RollClubOneHeatVO.SizeDetail> sizeDetailsList = new ArrayList<>();
|
|
|
+ List<RollClubOneHeatVO.RollSendDetail> rollSendDetailList = new ArrayList<>();
|
|
|
+ Map<String, Integer> lengthCountMap = new HashMap<>();
|
|
|
|
|
|
+ // 3. 解析 JSON 明细
|
|
|
+ String detailJson = record.getRollClubOneDetails();
|
|
|
if (StringUtils.isNotBlank(detailJson)) {
|
|
|
try {
|
|
|
JsonNode rootNode = objectMapper.readTree(detailJson);
|
|
|
-
|
|
|
+ // 总支数、总重量
|
|
|
rollOneHeatNo.setTotalAmount(getIntValue(rootNode, "directRollingTotalCount"));
|
|
|
rollOneHeatNo.setTotalWeight(getBigDecimalValue(rootNode, "directRollingTotalWeight"));
|
|
|
|
|
|
+ // 各定尺计数
|
|
|
JsonNode lengthGroupNode = rootNode.get("lengthGroupCount");
|
|
|
if (lengthGroupNode != null && lengthGroupNode.isObject()) {
|
|
|
- Iterator<Map.Entry<String, JsonNode>> fields = lengthGroupNode.fields();
|
|
|
- while (fields.hasNext()) {
|
|
|
- Map.Entry<String, JsonNode> entry = fields.next();
|
|
|
- String length = entry.getKey();
|
|
|
- int count = entry.getValue().asInt();
|
|
|
- lengthCountMap.merge(length, count, Integer::sum);
|
|
|
- }
|
|
|
+ lengthGroupNode.fields().forEachRemaining(e ->
|
|
|
+ lengthCountMap.merge(e.getKey(), e.getValue().asInt(), Integer::sum)
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
+ // 4. 根据每种定尺构建 sizeDetail & rollSendDetail
|
|
|
for (Map.Entry<String, Integer> entry : lengthCountMap.entrySet()) {
|
|
|
String length = entry.getKey();
|
|
|
int count = entry.getValue();
|
|
|
|
|
|
- BigDecimal unitWeight = BigDecimal.ZERO;
|
|
|
- String spec = "";
|
|
|
-
|
|
|
-
|
|
|
- if (lengthWeightCache.containsKey(length)) {
|
|
|
- unitWeight = lengthWeightCache.get(length);
|
|
|
- spec = lengthSpecCache.getOrDefault(length, "");
|
|
|
-
|
|
|
- } else {
|
|
|
- LambdaQueryWrapper<BilletRulerConfig> wrapper = new LambdaQueryWrapper<BilletRulerConfig>()
|
|
|
- .eq(BilletRulerConfig::getLength, length);
|
|
|
- BilletRulerConfig config = billetRulerConfigMapper.selectOne(wrapper);
|
|
|
- if (config != null) {
|
|
|
- if (config.getWeight() != null) {
|
|
|
- unitWeight = BigDecimal.valueOf(config.getWeight());
|
|
|
+ // 查缓存 / 数据库 获取单根重量 & 规格
|
|
|
+ BigDecimal unitWeight = lengthWeightCache.getOrDefault(length, BigDecimal.ZERO);
|
|
|
+ String spec = lengthSpecCache.getOrDefault(length, "");
|
|
|
+ if (unitWeight.equals(BigDecimal.ZERO) || "".equals(spec)) {
|
|
|
+ BilletRulerConfig cfg = billetRulerConfigMapper.selectOne(
|
|
|
+ new LambdaQueryWrapper<BilletRulerConfig>()
|
|
|
+ .eq(BilletRulerConfig::getLength, length)
|
|
|
+ );
|
|
|
+ if (cfg != null) {
|
|
|
+ if (cfg.getWeight() != null) {
|
|
|
+ unitWeight = BigDecimal.valueOf(cfg.getWeight());
|
|
|
lengthWeightCache.put(length, unitWeight);
|
|
|
}
|
|
|
- if (config.getSpec() != null) {
|
|
|
- spec = config.getSpec();
|
|
|
+ if (cfg.getSpec() != null) {
|
|
|
+ spec = cfg.getSpec();
|
|
|
lengthSpecCache.put(length, spec);
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
BigDecimal totalWeight = unitWeight.multiply(BigDecimal.valueOf(count));
|
|
|
|
|
|
- // 计算起始根数与终止根数
|
|
|
- int lastEndAmount = lengthCumulativeCountMap.getOrDefault(length, 0);
|
|
|
- int startAmount = lastEndAmount + 1;
|
|
|
- int endAmount = lastEndAmount + count;
|
|
|
- lengthCumulativeCountMap.put(length, endAmount); // 更新累计值
|
|
|
-
|
|
|
- // sizeDetail
|
|
|
- RollClubOneHeatVO.SizeDetail sizeDetail = new RollClubOneHeatVO.SizeDetail();
|
|
|
- sizeDetail.setSize(Integer.valueOf(length));
|
|
|
- sizeDetail.setSizeAmount(count);
|
|
|
- sizeDetail.setSizeWeight(totalWeight);
|
|
|
- sizeDetail.setStartAmount(startAmount);
|
|
|
- sizeDetail.setEndAmount(endAmount);
|
|
|
- sizeDetailsList.add(sizeDetail);
|
|
|
-
|
|
|
- // rollSendDetail
|
|
|
- RollClubOneHeatVO.RollSendDetail rollSendDetail = new RollClubOneHeatVO.RollSendDetail();
|
|
|
- rollSendDetail.setSize(Integer.valueOf(length));
|
|
|
- rollSendDetail.setAmount(count);
|
|
|
- rollSendDetail.setWeight(totalWeight);
|
|
|
- rollSendDetail.setSpec(spec);
|
|
|
- rollSendDetail.setCreateTime(record.getCreateTime());
|
|
|
- rollSendDetailList.add(rollSendDetail);
|
|
|
+ // 计算 start/end
|
|
|
+ int lastEnd = lengthCumulativeCountMap.getOrDefault(length, 0);
|
|
|
+ int startAmount = lastEnd + 1;
|
|
|
+ int endAmount = lastEnd + count;
|
|
|
+ lengthCumulativeCountMap.put(length, endAmount);
|
|
|
+
|
|
|
+ // 填充 sizeDetail
|
|
|
+ RollClubOneHeatVO.SizeDetail sd = new RollClubOneHeatVO.SizeDetail();
|
|
|
+ sd.setSize(Integer.valueOf(length));
|
|
|
+ sd.setSizeAmount(count);
|
|
|
+ sd.setSizeWeight(totalWeight);
|
|
|
+ sd.setStartAmount(startAmount);
|
|
|
+ sd.setEndAmount(endAmount);
|
|
|
+ sizeDetailsList.add(sd);
|
|
|
+
|
|
|
+ // 填充 rollSendDetail
|
|
|
+ RollClubOneHeatVO.RollSendDetail rsd = new RollClubOneHeatVO.RollSendDetail();
|
|
|
+ rsd.setSize(Integer.valueOf(length));
|
|
|
+ rsd.setAmount(count);
|
|
|
+ rsd.setWeight(totalWeight);
|
|
|
+ rsd.setSpec(spec);
|
|
|
+ rsd.setCreateTime(record.getCreateTime());
|
|
|
+ rollSendDetailList.add(rsd);
|
|
|
}
|
|
|
|
|
|
rollOneHeatNo.setSizeDetails(sizeDetailsList);
|
|
|
rollOneHeatNo.setRollSendDetails(rollSendDetailList);
|
|
|
- resultMap.put(record.getHeatNo(), rollOneHeatNo);
|
|
|
+
|
|
|
+ // 5. 放入 resultMap —— key 为 heatNo_shift_shiftGroup
|
|
|
+ resultMap.put(key, rollOneHeatNo);
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
log.info("JSON 解析失败,数据:{}", detailJson, e);
|
|
@@ -630,6 +617,7 @@ public class RollClubOneServiceImpl extends ServiceImpl<RollClubOneMapper, RollC
|
|
|
}
|
|
|
|
|
|
|
|
|
+
|
|
|
// 工具方法:解析 int
|
|
|
private Integer getIntValue(JsonNode node, String fieldName) {
|
|
|
JsonNode valueNode = node.get(fieldName);
|