|
@@ -1,6 +1,8 @@
|
|
|
package org.jeecg.modules.billet.billetOriginalProductRecord.service.impl;
|
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
@@ -17,6 +19,8 @@ import org.jeecg.modules.billet.billetOriginalProductRecord.mapper.BilletOrigina
|
|
|
import org.jeecg.modules.billet.billetOriginalProductRecord.service.IBilletOriginalProductRecordService;
|
|
|
import org.jeecg.modules.billet.billetOriginalProductRecord.vo.QualityInspectionStatisticsVO;
|
|
|
import org.jeecg.modules.billet.billetOriginalProductRecord.vo.QualityInspectionVO;
|
|
|
+import org.jeecg.modules.billet.qualityInspectionStatistics.entity.QualityInspectionStatistics;
|
|
|
+import org.jeecg.modules.billet.qualityInspectionStatistics.mapper.QualityInspectionStatisticsMapper;
|
|
|
import org.jeecg.modules.carUnit.service.ISysDictService;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
@@ -24,6 +28,9 @@ import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.ZoneId;
|
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
@@ -49,6 +56,9 @@ public class BilletOriginalProductRecordServiceImpl extends ServiceImpl<BilletOr
|
|
|
@Autowired
|
|
|
private BilletRulerConfigMapper billetRulerConfigMapper;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private QualityInspectionStatisticsMapper qualityInspectionStatisticsMapper;
|
|
|
+
|
|
|
@Override
|
|
|
public Map<String, Object> getQualityInspectionMenu(QualityInspectionQueryDTO queryDTO) {
|
|
|
if (queryDTO == null || StringUtils.isBlank(queryDTO.getCcmNo())) {
|
|
@@ -58,42 +68,58 @@ public class BilletOriginalProductRecordServiceImpl extends ServiceImpl<BilletOr
|
|
|
LambdaQueryWrapper<BilletOriginalProductRecord> oneQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
oneQueryWrapper.eq(BilletOriginalProductRecord::getCcmNo, queryDTO.getCcmNo());
|
|
|
Boolean search = true;
|
|
|
+ LambdaQueryWrapper<BilletHotsendChangeShift> changeShiftQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+
|
|
|
+ BilletHotsendChangeShift newBilletHotsendChangeShift = null;
|
|
|
|
|
|
if (oConvertUtils.isNotEmpty(queryDTO.getChangeShiftId())) {
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
- changeQueryWrapper.eq(BilletHotsendChangeShift::getId, queryDTO.getChangeShiftId()).eq(BilletHotsendChangeShift::getCcmNo, queryDTO.getCcmNo());
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
- if (billetHotsendChangeShift == null) {
|
|
|
- return Collections.emptyMap(); // 空数据返回
|
|
|
- }
|
|
|
- Date startChangeTime = billetHotsendChangeShift.getCreateTime();
|
|
|
- Date endChangeTime = oConvertUtils.isNotEmpty(billetHotsendChangeShift.getChangeShiftTime()) ? billetHotsendChangeShift.getChangeShiftTime() : new Date();
|
|
|
- oneQueryWrapper.eq(BilletOriginalProductRecord::getShift, billetHotsendChangeShift.getShift());
|
|
|
- oneQueryWrapper.eq(BilletOriginalProductRecord::getShiftGroup, billetHotsendChangeShift.getShiftGroup());
|
|
|
- oneQueryWrapper.between(BilletOriginalProductRecord::getCreateTime, startChangeTime, endChangeTime);
|
|
|
- search = false;
|
|
|
- } else if (oConvertUtils.isNotEmpty(queryDTO.getStartTime()) && oConvertUtils.isNotEmpty(queryDTO.getEndTime())) {
|
|
|
- oneQueryWrapper.between(BilletOriginalProductRecord::getCreateTime, queryDTO.getStartTime(), queryDTO.getEndTime());
|
|
|
- search = false;
|
|
|
+ // 指定了换班记录ID
|
|
|
+ changeShiftQueryWrapper.eq(BilletHotsendChangeShift::getId, queryDTO.getChangeShiftId());
|
|
|
+ } else {
|
|
|
+ // 未指定ID,则取指定铸机号下最新一条换班记录
|
|
|
+ changeShiftQueryWrapper.eq(BilletHotsendChangeShift::getCcmNo, queryDTO.getCcmNo())
|
|
|
+ .orderByDesc(BilletHotsendChangeShift::getCreateTime)
|
|
|
+ .last("limit 1"); // 只取一条
|
|
|
}
|
|
|
|
|
|
- if (oConvertUtils.isNotEmpty(queryDTO.getQueryDate()) || search) {
|
|
|
- if (oConvertUtils.isEmpty(queryDTO.getQueryDate())) {
|
|
|
- String nowDate = DateUtils.getDate("yyyy-MM-dd");
|
|
|
- Date startOneTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(nowDate));
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
- changeQueryWrapper.eq(BilletHotsendChangeShift::getCcmNo, queryDTO.getCcmNo()).orderByDesc(BilletHotsendChangeShift::getCreateTime).last("limit 1");
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
- oneQueryWrapper.ge(BilletOriginalProductRecord::getCreateTime,
|
|
|
- oConvertUtils.isNotEmpty(billetHotsendChangeShift.getCreateTime()) ? billetHotsendChangeShift.getCreateTime() : startOneTime);
|
|
|
- } else {
|
|
|
- Date queryDate = queryDTO.getQueryDate();
|
|
|
- Date startTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(queryDate));
|
|
|
- Date endTime = DateUtils.getEndOfDayByDate(startTime);
|
|
|
- oneQueryWrapper.between(BilletOriginalProductRecord::getCreateTime, startTime, endTime);
|
|
|
- }
|
|
|
+ newBilletHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeShiftQueryWrapper);
|
|
|
+
|
|
|
+ if (newBilletHotsendChangeShift == null) {
|
|
|
+ return Collections.emptyMap(); // 无数据,直接返回空
|
|
|
}
|
|
|
|
|
|
+ // 获取换班时间段
|
|
|
+ Date startChangeTime = newBilletHotsendChangeShift.getCreateTime();
|
|
|
+ Date endChangeTime = oConvertUtils.isNotEmpty(newBilletHotsendChangeShift.getChangeShiftTime())
|
|
|
+ ? newBilletHotsendChangeShift.getChangeShiftTime()
|
|
|
+ : new Date();
|
|
|
+
|
|
|
+ // 根据换班信息查询原始记录
|
|
|
+ oneQueryWrapper.eq(BilletOriginalProductRecord::getShift, newBilletHotsendChangeShift.getShift());
|
|
|
+ oneQueryWrapper.eq(BilletOriginalProductRecord::getShiftGroup, newBilletHotsendChangeShift.getShiftGroup());
|
|
|
+ oneQueryWrapper.between(BilletOriginalProductRecord::getCreateTime, startChangeTime, endChangeTime);
|
|
|
+// else if (oConvertUtils.isNotEmpty(queryDTO.getStartTime()) && oConvertUtils.isNotEmpty(queryDTO.getEndTime())) {
|
|
|
+// oneQueryWrapper.between(BilletOriginalProductRecord::getCreateTime, queryDTO.getStartTime(), queryDTO.getEndTime());
|
|
|
+// search = false;
|
|
|
+// }
|
|
|
+
|
|
|
+// if (oConvertUtils.isNotEmpty(queryDTO.getQueryDate()) || search) {
|
|
|
+// if (oConvertUtils.isEmpty(queryDTO.getQueryDate())) {
|
|
|
+// String nowDate = DateUtils.getDate("yyyy-MM-dd");
|
|
|
+// Date startOneTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(nowDate));
|
|
|
+// LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+// changeQueryWrapper.eq(BilletHotsendChangeShift::getCcmNo, queryDTO.getCcmNo()).orderByDesc(BilletHotsendChangeShift::getCreateTime).last("limit 1");
|
|
|
+// BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
+// oneQueryWrapper.ge(BilletOriginalProductRecord::getCreateTime,
|
|
|
+// oConvertUtils.isNotEmpty(billetHotsendChangeShift.getCreateTime()) ? billetHotsendChangeShift.getCreateTime() : startOneTime);
|
|
|
+// } else {
|
|
|
+// String queryDate = queryDTO.getQueryDate();
|
|
|
+// Date startTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(queryDate));
|
|
|
+// Date endTime = DateUtils.getEndOfDayByDate(startTime);
|
|
|
+// oneQueryWrapper.between(BilletOriginalProductRecord::getCreateTime, startTime, endTime);
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
if (oConvertUtils.isNotEmpty(queryDTO.getHeatNo())) {
|
|
|
oneQueryWrapper.eq(BilletOriginalProductRecord::getHeatNo, queryDTO.getHeatNo());
|
|
|
}
|
|
@@ -145,6 +171,7 @@ public class BilletOriginalProductRecordServiceImpl extends ServiceImpl<BilletOr
|
|
|
.orElseGet(() -> sysDictService.queryDictTextByKey("billet_spec", "5"));
|
|
|
vo.setBrandNum(brandNum);
|
|
|
vo.setDeliveryTime(record.getCreateTime());
|
|
|
+ vo.setOriginalProductRecordId(record.getId());
|
|
|
|
|
|
Map<String, Integer> mergedCount = new HashMap<>();
|
|
|
Map<String, BigDecimal> mergedWeight = new HashMap<>();
|
|
@@ -252,150 +279,225 @@ public class BilletOriginalProductRecordServiceImpl extends ServiceImpl<BilletOr
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 1. 先对定尺重量 map 统一保留4位小数(班次 + 当天)
|
|
|
- Map<String, BigDecimal> roundedClassWeightMap = classLengthWeightMap.entrySet().stream()
|
|
|
- .collect(Collectors.toMap(
|
|
|
- Map.Entry::getKey,
|
|
|
- e -> e.getValue().setScale(4, RoundingMode.HALF_UP)
|
|
|
- ));
|
|
|
+ LambdaQueryWrapper<QualityInspectionStatistics> qualityQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
|
- Map<String, BigDecimal> roundedDayWeightMap = dayLengthWeightMap.entrySet().stream()
|
|
|
- .collect(Collectors.toMap(
|
|
|
- Map.Entry::getKey,
|
|
|
- e -> e.getValue().setScale(4, RoundingMode.HALF_UP)
|
|
|
- ));
|
|
|
|
|
|
- // 2. 总重量使用已四舍五入后的子项重量相加,再保留4位小数
|
|
|
- BigDecimal roundedClassTotalWeight = roundedClassWeightMap.values().stream()
|
|
|
- .reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
- .setScale(4, RoundingMode.HALF_UP);
|
|
|
-
|
|
|
- BigDecimal roundedDayTotalWeight = roundedDayWeightMap.values().stream()
|
|
|
- .reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
- .setScale(4, RoundingMode.HALF_UP);
|
|
|
-
|
|
|
- // 3. 封装 VO 返回
|
|
|
- QualityInspectionStatisticsVO stats = new QualityInspectionStatisticsVO();
|
|
|
- stats.setClassLengthCountMap(classLengthCountMap);
|
|
|
- stats.setClassLengthWeightMap(roundedClassWeightMap);
|
|
|
- stats.setClassTotalCount(classTotalCount);
|
|
|
- stats.setClassTotalWeight(roundedClassTotalWeight);
|
|
|
-
|
|
|
- stats.setDayLengthCountMap(dayLengthCountMap);
|
|
|
- stats.setDayLengthWeightMap(roundedDayWeightMap);
|
|
|
- stats.setDayTotalCount(dayTotalCount);
|
|
|
- stats.setDayTotalWeight(roundedDayTotalWeight);
|
|
|
+ // 未指定ID,则取指定铸机号下最新一条换班记录
|
|
|
+ qualityQueryWrapper.eq(QualityInspectionStatistics::getChangeShiftId, newBilletHotsendChangeShift.getId())
|
|
|
+ .orderByDesc(QualityInspectionStatistics::getCreateTime)
|
|
|
+ .last("limit 1"); // 只取一条
|
|
|
|
|
|
+ QualityInspectionStatistics qualityInspectionStatistics = qualityInspectionStatisticsMapper.selectOne(qualityQueryWrapper);
|
|
|
|
|
|
Map<String, Object> result = new HashMap<>();
|
|
|
result.put("records", resultList);
|
|
|
- result.put("statistics", stats);
|
|
|
+ result.put("statistics", qualityInspectionStatistics);
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public Map<String, Object> getQualityInspectionScreen(QualityInspectionQueryDTO queryDTO) {
|
|
|
- if (queryDTO == null || StringUtils.isBlank(queryDTO.getCcmNo())) {
|
|
|
- return Collections.emptyMap();
|
|
|
- }
|
|
|
- List<QualityInspectionVO> resultList = new ArrayList<>();
|
|
|
- LambdaQueryWrapper<BilletOriginalProductRecord> oneQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
- oneQueryWrapper.eq(BilletOriginalProductRecord::getCcmNo, queryDTO.getCcmNo());
|
|
|
- Boolean search = true;
|
|
|
+ public void getQualityInspectionScreen(QualityInspectionQueryDTO queryDTO) {
|
|
|
+ String ccmNo = "5";
|
|
|
|
|
|
- if (oConvertUtils.isNotEmpty(queryDTO.getChangeShiftId())) {
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
- changeQueryWrapper.eq(BilletHotsendChangeShift::getId, queryDTO.getChangeShiftId()).eq(BilletHotsendChangeShift::getCcmNo, queryDTO.getCcmNo());
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
- if (billetHotsendChangeShift == null) {
|
|
|
- return Collections.emptyMap(); // 空数据返回
|
|
|
- }
|
|
|
- Date startChangeTime = billetHotsendChangeShift.getCreateTime();
|
|
|
- Date endChangeTime = oConvertUtils.isNotEmpty(billetHotsendChangeShift.getChangeShiftTime()) ? billetHotsendChangeShift.getChangeShiftTime() : new Date();
|
|
|
- oneQueryWrapper.eq(BilletOriginalProductRecord::getShift, billetHotsendChangeShift.getShift());
|
|
|
- oneQueryWrapper.eq(BilletOriginalProductRecord::getShiftGroup, billetHotsendChangeShift.getShiftGroup());
|
|
|
- oneQueryWrapper.between(BilletOriginalProductRecord::getCreateTime, startChangeTime, endChangeTime);
|
|
|
- search = false;
|
|
|
- } else if (oConvertUtils.isNotEmpty(queryDTO.getStartTime()) && oConvertUtils.isNotEmpty(queryDTO.getEndTime())) {
|
|
|
- oneQueryWrapper.between(BilletOriginalProductRecord::getCreateTime, queryDTO.getStartTime(), queryDTO.getEndTime());
|
|
|
- search = false;
|
|
|
+ // 1. 初始化补全月统计(缺失部分)
|
|
|
+ initMonthlyStatisticsIfMissing(ccmNo);
|
|
|
+
|
|
|
+ // 2. 查询当天班次
|
|
|
+ String nowDate = DateUtils.getDate("yyyy-MM-dd");
|
|
|
+ Date dayStart = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(nowDate));
|
|
|
+ Date dayEnd = DateUtils.getEndOfDayByDate(DateUtils.getEndOfDay(nowDate));
|
|
|
+
|
|
|
+ List<BilletHotsendChangeShift> shifts = billetHotsendChangeShiftService.list(
|
|
|
+ new LambdaQueryWrapper<BilletHotsendChangeShift>()
|
|
|
+ .eq(BilletHotsendChangeShift::getCcmNo, ccmNo)
|
|
|
+ .between(BilletHotsendChangeShift::getCreateTime, dayStart, dayEnd)
|
|
|
+ );
|
|
|
+
|
|
|
+ // 按 change_shift_time 升序排序
|
|
|
+ shifts.sort(Comparator.comparing(BilletHotsendChangeShift::getCreateTime));
|
|
|
+
|
|
|
+ // 日累计起点
|
|
|
+ BigDecimal dayStartWeight = BigDecimal.ONE;
|
|
|
+ int dayStartCount = 1;
|
|
|
+
|
|
|
+ // 月累计起点(查询已有最大记录)
|
|
|
+ Date monthStart = DateUtils.getMonthStart(new Date());
|
|
|
+ QualityInspectionStatistics last = qualityInspectionStatisticsMapper.selectOne(
|
|
|
+ new LambdaQueryWrapper<QualityInspectionStatistics>()
|
|
|
+ .eq(QualityInspectionStatistics::getCcmNo, ccmNo)
|
|
|
+ .ge(QualityInspectionStatistics::getChangeShiftTime, monthStart)
|
|
|
+ .orderByDesc(QualityInspectionStatistics::getChangeShiftTime)
|
|
|
+ .last("limit 1")
|
|
|
+ );
|
|
|
+ BigDecimal monthStartWeight = last != null ? last.getMonthEndWeight().add(BigDecimal.ONE) : BigDecimal.ONE;
|
|
|
+ int monthStartCount = last != null ? last.getMonthEndCount() + 1 : 1;
|
|
|
+
|
|
|
+ for (BilletHotsendChangeShift shift : shifts) {
|
|
|
+ QualityInspectionStatisticsVO vo = this.getStatisticsByShift(shift,shifts);
|
|
|
+
|
|
|
+ QualityInspectionStatistics entity = new QualityInspectionStatistics();
|
|
|
+ entity.setId(String.valueOf(IdWorker.getId()));
|
|
|
+ entity.setClassLengthCountWeight(JSON.toJSONString(vo.getClassLengthCountWeight()));
|
|
|
+ entity.setDayLengthCountWeight(JSON.toJSONString(vo.getDayLengthCountWeight()));
|
|
|
+ entity.setClassTotalCount(vo.getClassTotalCount());
|
|
|
+ entity.setClassTotalWeight(vo.getClassTotalWeight());
|
|
|
+ entity.setChangeShiftId(shift.getId());
|
|
|
+ entity.setShift(shift.getShift());
|
|
|
+ entity.setShiftGroup(shift.getShiftGroup());
|
|
|
+ entity.setClassHeatNum(vo.getClassHeatNum());
|
|
|
+ entity.setChangeShiftTime(shift.getCreateTime());
|
|
|
+ entity.setCcmNo(ccmNo);
|
|
|
+
|
|
|
+ // 日累计
|
|
|
+ entity.setDayStartCount(dayStartCount);
|
|
|
+ entity.setDayStartWeight(dayStartWeight);
|
|
|
+ int dayEndCount = dayStartCount + vo.getClassTotalCount() - 1;
|
|
|
+ BigDecimal dayEndWeight = dayStartWeight.add(vo.getClassTotalWeight()).subtract(BigDecimal.ONE);
|
|
|
+ entity.setDayEndCount(dayEndCount);
|
|
|
+ entity.setDayEndWeight(dayEndWeight);
|
|
|
+ dayStartCount = dayEndCount + 1;
|
|
|
+ dayStartWeight = dayEndWeight.add(BigDecimal.ONE);
|
|
|
+
|
|
|
+ // 月累计
|
|
|
+ entity.setMonthStartCount(monthStartCount);
|
|
|
+ entity.setMonthStartWeight(monthStartWeight);
|
|
|
+ int monthEndCount = monthStartCount + vo.getClassTotalCount() - 1;
|
|
|
+ BigDecimal monthEndWeight = monthStartWeight.add(vo.getClassTotalWeight()).subtract(BigDecimal.ONE);
|
|
|
+ entity.setMonthEndCount(monthEndCount);
|
|
|
+ entity.setMonthEndWeight(monthEndWeight);
|
|
|
+ monthStartCount = monthEndCount + 1;
|
|
|
+ monthStartWeight = monthEndWeight.add(BigDecimal.ONE);
|
|
|
+
|
|
|
+ qualityInspectionStatisticsMapper.insert(entity);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- if (oConvertUtils.isNotEmpty(queryDTO.getQueryDate()) || search) {
|
|
|
- if (oConvertUtils.isEmpty(queryDTO.getQueryDate())) {
|
|
|
- String nowDate = DateUtils.getDate("yyyy-MM-dd");
|
|
|
- Date startOneTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(nowDate));
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
- changeQueryWrapper.eq(BilletHotsendChangeShift::getCcmNo, queryDTO.getCcmNo()).orderByDesc(BilletHotsendChangeShift::getCreateTime).last("limit 1");
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
- oneQueryWrapper.ge(BilletOriginalProductRecord::getCreateTime,
|
|
|
- oConvertUtils.isNotEmpty(billetHotsendChangeShift.getCreateTime()) ? billetHotsendChangeShift.getCreateTime() : startOneTime);
|
|
|
- } else {
|
|
|
- Date queryDate = queryDTO.getQueryDate();
|
|
|
- Date startTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(queryDate));
|
|
|
- Date endTime = DateUtils.getEndOfDayByDate(startTime);
|
|
|
- oneQueryWrapper.between(BilletOriginalProductRecord::getCreateTime, startTime, endTime);
|
|
|
+
|
|
|
+
|
|
|
+ private void initMonthlyStatisticsIfMissing(String ccmNo) {
|
|
|
+ Date monthStart = DateUtils.getMonthStart(new Date());
|
|
|
+ Date searchStart = new Date(monthStart.getTime() - 10 * 60 * 1000); // 向前推10分钟
|
|
|
+ Date now = new Date();
|
|
|
+
|
|
|
+ List<BilletHotsendChangeShift> allShifts = billetHotsendChangeShiftService.list(
|
|
|
+ new LambdaQueryWrapper<BilletHotsendChangeShift>()
|
|
|
+ .eq(BilletHotsendChangeShift::getCcmNo, ccmNo)
|
|
|
+ .between(BilletHotsendChangeShift::getCreateTime, searchStart, now)
|
|
|
+ );
|
|
|
+
|
|
|
+ // 按归属日期分组
|
|
|
+ Map<LocalDate, List<BilletHotsendChangeShift>> shiftByDate = allShifts.stream()
|
|
|
+ .collect(Collectors.groupingBy(s -> getShiftDate(s.getCreateTime(), s.getShift()),
|
|
|
+ TreeMap::new, Collectors.toList()));
|
|
|
+
|
|
|
+ // 初始化月累计起点
|
|
|
+ int monthStartCount = 1;
|
|
|
+ BigDecimal monthStartWeight = BigDecimal.ONE;
|
|
|
+
|
|
|
+ for (List<BilletHotsendChangeShift> shiftList : shiftByDate.values()) {
|
|
|
+ // 按班次顺序处理:夜班 > 白班 > 中班
|
|
|
+ Map<String, Integer> shiftOrder = new HashMap<>();
|
|
|
+ shiftOrder.put("1", 0); // 夜班
|
|
|
+ shiftOrder.put("0", 1); // 白班
|
|
|
+ shiftOrder.put("2", 2); // 中班
|
|
|
+
|
|
|
+ shiftList.sort(Comparator
|
|
|
+ .comparing((BilletHotsendChangeShift s) -> shiftOrder.getOrDefault(s.getShift(), 99))
|
|
|
+ .thenComparing(BilletHotsendChangeShift::getCreateTime));
|
|
|
+
|
|
|
+ // 日累计起点
|
|
|
+ int dayStartCount = 1;
|
|
|
+ BigDecimal dayStartWeight = BigDecimal.ONE;
|
|
|
+
|
|
|
+ for (BilletHotsendChangeShift shift : shiftList) {
|
|
|
+ Long count = qualityInspectionStatisticsMapper.selectCount(
|
|
|
+ new LambdaQueryWrapper<QualityInspectionStatistics>()
|
|
|
+ .eq(QualityInspectionStatistics::getChangeShiftId, shift.getId())
|
|
|
+ );
|
|
|
+ if (count > 0) continue;
|
|
|
+
|
|
|
+ QualityInspectionStatisticsVO vo = this.getStatisticsByShift(shift,shiftList);
|
|
|
+
|
|
|
+ QualityInspectionStatistics entity = new QualityInspectionStatistics();
|
|
|
+ entity.setId(String.valueOf(IdWorker.getId()));
|
|
|
+ entity.setClassLengthCountWeight(JSON.toJSONString(vo.getClassLengthCountWeight()));
|
|
|
+ entity.setDayLengthCountWeight(JSON.toJSONString(vo.getDayLengthCountWeight()));
|
|
|
+ entity.setClassTotalCount(vo.getClassTotalCount());
|
|
|
+ entity.setClassTotalWeight(vo.getClassTotalWeight());
|
|
|
+ entity.setChangeShiftId(shift.getId());
|
|
|
+ entity.setShift(shift.getShift());
|
|
|
+ entity.setShiftGroup(shift.getShiftGroup());
|
|
|
+ entity.setClassHeatNum(vo.getClassHeatNum());
|
|
|
+ entity.setChangeShiftTime(shift.getCreateTime());
|
|
|
+ entity.setCcmNo(ccmNo);
|
|
|
+
|
|
|
+ // 日累计
|
|
|
+ entity.setDayStartCount(dayStartCount);
|
|
|
+ entity.setDayStartWeight(dayStartWeight);
|
|
|
+ int dayEndCount = dayStartCount + vo.getClassTotalCount() - 1;
|
|
|
+ BigDecimal dayEndWeight = dayStartWeight.add(vo.getClassTotalWeight()).subtract(BigDecimal.ONE);
|
|
|
+ entity.setDayEndCount(dayEndCount);
|
|
|
+ entity.setDayEndWeight(dayEndWeight);
|
|
|
+ dayStartCount = dayEndCount + 1;
|
|
|
+ dayStartWeight = dayEndWeight.add(BigDecimal.ONE);
|
|
|
+
|
|
|
+ // 月累计
|
|
|
+ entity.setMonthStartCount(monthStartCount);
|
|
|
+ entity.setMonthStartWeight(monthStartWeight);
|
|
|
+ int monthEndCount = monthStartCount + vo.getClassTotalCount() - 1;
|
|
|
+ BigDecimal monthEndWeight = monthStartWeight.add(vo.getClassTotalWeight()).subtract(BigDecimal.ONE);
|
|
|
+ entity.setMonthEndCount(monthEndCount);
|
|
|
+ entity.setMonthEndWeight(monthEndWeight);
|
|
|
+ monthStartCount = monthEndCount + 1;
|
|
|
+ monthStartWeight = monthEndWeight.add(BigDecimal.ONE);
|
|
|
+
|
|
|
+ qualityInspectionStatisticsMapper.insert(entity);
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- if (oConvertUtils.isNotEmpty(queryDTO.getHeatNo())) {
|
|
|
- oneQueryWrapper.eq(BilletOriginalProductRecord::getHeatNo, queryDTO.getHeatNo());
|
|
|
- }
|
|
|
- if (oConvertUtils.isNotEmpty(queryDTO.getSize())) {
|
|
|
- oneQueryWrapper.like(BilletOriginalProductRecord::getRollClubOneDetails, queryDTO.getSize());
|
|
|
- }
|
|
|
- if (oConvertUtils.isNotEmpty(queryDTO.getBrandNum())) {
|
|
|
- oneQueryWrapper.eq(BilletOriginalProductRecord::getGrade, queryDTO.getBrandNum());
|
|
|
- }
|
|
|
- oneQueryWrapper.orderByAsc(BilletOriginalProductRecord::getCreateTime);
|
|
|
|
|
|
- List<BilletOriginalProductRecord> records = this.list(oneQueryWrapper);
|
|
|
- Set<String> allLengths = new TreeSet<>();
|
|
|
- ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
|
- // 获取当前班次记录
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
- changeQueryWrapper.eq(BilletHotsendChangeShift::getCcmNo, queryDTO.getCcmNo())
|
|
|
- .orderByDesc(BilletHotsendChangeShift::getCreateTime)
|
|
|
- .last("limit 1");
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
|
|
|
- // 设置班次时间范围
|
|
|
- Date classStartTime = billetHotsendChangeShift != null ? billetHotsendChangeShift.getCreateTime() : null;
|
|
|
- Date classEndTime = billetHotsendChangeShift != null && billetHotsendChangeShift.getChangeShiftTime() != null
|
|
|
- ? billetHotsendChangeShift.getChangeShiftTime()
|
|
|
- : new Date();
|
|
|
+ public QualityInspectionStatisticsVO getStatisticsByShift(BilletHotsendChangeShift shiftRecord, List<BilletHotsendChangeShift> allShiftsOfTheDay) {
|
|
|
+ Date classStartTime = shiftRecord.getCreateTime();
|
|
|
+ Date classEndTime = Optional.ofNullable(shiftRecord.getChangeShiftTime()).orElse(new Date());
|
|
|
+ String ccmNo = shiftRecord.getCcmNo();
|
|
|
|
|
|
- String nowDate = DateUtils.getDate("yyyy-MM-dd");
|
|
|
+ // 获取米重数据
|
|
|
+ String meterWeightKey = String.format("ccmno:meter:weight:%s", ccmNo);
|
|
|
+ String mWeightStr = oConvertUtils.getString(redisTemplate.opsForValue().get(meterWeightKey));
|
|
|
+ BigDecimal meterWeightFactor = StringUtils.isNotEmpty(mWeightStr)
|
|
|
+ ? new BigDecimal(mWeightStr)
|
|
|
+ : BigDecimal.ONE; // 如果没有米重数据,使用1作为系数
|
|
|
|
|
|
- Date startCurrentTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(nowDate));
|
|
|
- Date endCurrentTime = DateUtils.getEndOfDayByDate(DateUtils.getEndOfDay(nowDate));
|
|
|
+ // 查询当前班次的原始记录
|
|
|
+ LambdaQueryWrapper<BilletOriginalProductRecord> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(BilletOriginalProductRecord::getCcmNo, ccmNo)
|
|
|
+ .eq(BilletOriginalProductRecord::getShift, shiftRecord.getShift())
|
|
|
+ .eq(BilletOriginalProductRecord::getShiftGroup, shiftRecord.getShiftGroup())
|
|
|
+ .between(BilletOriginalProductRecord::getCreateTime, classStartTime, classEndTime)
|
|
|
+ .orderByAsc(BilletOriginalProductRecord::getCreateTime);
|
|
|
+ List<BilletOriginalProductRecord> records = this.list(queryWrapper);
|
|
|
+
|
|
|
+ // 获取当前班次逻辑日期,用作日统计参考
|
|
|
+ LocalDate logicalDay = getShiftDate(classStartTime, shiftRecord.getShift());
|
|
|
+ Date dayStartTime = shiftRecord.getCreateTime(); // 日累计从当前班次开始
|
|
|
+ Date dayEndTime = DateUtils.getEndOfDayByDate(Date.from(logicalDay.atStartOfDay(ZoneId.systemDefault()).toInstant()));
|
|
|
|
|
|
- // 汇总统计
|
|
|
Map<String, Integer> classLengthCountMap = new TreeMap<>();
|
|
|
Map<String, BigDecimal> classLengthWeightMap = new TreeMap<>();
|
|
|
- Map<String, Integer> dayLengthCountMap = new TreeMap<>();
|
|
|
- Map<String, BigDecimal> dayLengthWeightMap = new TreeMap<>();
|
|
|
int classTotalCount = 0;
|
|
|
BigDecimal classTotalWeight = BigDecimal.ZERO;
|
|
|
- int dayTotalCount = 0;
|
|
|
- BigDecimal dayTotalWeight = BigDecimal.ZERO;
|
|
|
|
|
|
- for (BilletOriginalProductRecord record : records) {
|
|
|
- QualityInspectionVO vo = new QualityInspectionVO();
|
|
|
- vo.setHeatNo(record.getHeatNo());
|
|
|
- String brandNum = Optional.ofNullable(record.getGrade())
|
|
|
- .map(bn -> sysDictService.queryDictTextByKey("billet_spec", bn))
|
|
|
- .orElseGet(() -> sysDictService.queryDictTextByKey("billet_spec", "5"));
|
|
|
- vo.setBrandNum(brandNum);
|
|
|
- vo.setDeliveryTime(record.getCreateTime());
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
|
+ for (BilletOriginalProductRecord record : records) {
|
|
|
Map<String, Integer> mergedCount = new HashMap<>();
|
|
|
Map<String, BigDecimal> mergedWeight = new HashMap<>();
|
|
|
|
|
|
try {
|
|
|
- // --- rollClubOneDetails ---
|
|
|
JsonNode rollDetails = objectMapper.readTree(record.getRollClubOneDetails());
|
|
|
JsonNode lengthGroupCount = rollDetails.path("lengthGroupCount");
|
|
|
BigDecimal totalWeight = rollDetails.path("directRollingTotalWeight").decimalValue();
|
|
@@ -407,24 +509,21 @@ public class BilletOriginalProductRecordServiceImpl extends ServiceImpl<BilletOr
|
|
|
int count = entry.getValue().asInt(0);
|
|
|
|
|
|
LambdaQueryWrapper<BilletRulerConfig> configQuery = new LambdaQueryWrapper<BilletRulerConfig>()
|
|
|
- .eq(BilletRulerConfig::getLength, Integer.valueOf(mm)); // mm 是字符串长度
|
|
|
-
|
|
|
+ .eq(BilletRulerConfig::getLength, Integer.valueOf(mm));
|
|
|
BilletRulerConfig rulerConfig = billetRulerConfigMapper.selectOne(configQuery);
|
|
|
|
|
|
BigDecimal weight;
|
|
|
-
|
|
|
if (rulerConfig != null && rulerConfig.getWeight() != null) {
|
|
|
- // 方式一:用定尺表配置重量
|
|
|
- weight = BigDecimal.valueOf(rulerConfig.getWeight())
|
|
|
- .multiply(BigDecimal.valueOf(count));
|
|
|
+ weight = BigDecimal.valueOf(rulerConfig.getWeight()).multiply(BigDecimal.valueOf(count));
|
|
|
} else {
|
|
|
- // 方式二:用总重量按支数比例分摊
|
|
|
weight = (totalCount > 0)
|
|
|
- ? totalWeight.divide(BigDecimal.valueOf(totalCount), 4, RoundingMode.HALF_UP)
|
|
|
- .multiply(BigDecimal.valueOf(count))
|
|
|
+ ? totalWeight.divide(BigDecimal.valueOf(totalCount), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(count))
|
|
|
: BigDecimal.ZERO;
|
|
|
}
|
|
|
|
|
|
+ // 应用米重系数
|
|
|
+ weight = weight.multiply(meterWeightFactor);
|
|
|
+
|
|
|
mergedCount.merge(mm, count, Integer::sum);
|
|
|
mergedWeight.merge(mm, weight, BigDecimal::add);
|
|
|
}
|
|
@@ -432,110 +531,151 @@ public class BilletOriginalProductRecordServiceImpl extends ServiceImpl<BilletOr
|
|
|
} catch (Exception ignored) {}
|
|
|
|
|
|
try {
|
|
|
- // --- hotChargeLength ---
|
|
|
JsonNode hotArray = objectMapper.readTree(record.getHotChargeLength());
|
|
|
for (JsonNode node : hotArray) {
|
|
|
String mm = node.path("hotChargeLength").asText();
|
|
|
int count = node.path("totalCount").asInt(0);
|
|
|
BigDecimal weight = new BigDecimal(node.path("totalWeight").asText("0"));
|
|
|
+
|
|
|
+ // 应用米重系数
|
|
|
+ weight = weight.multiply(meterWeightFactor);
|
|
|
+
|
|
|
mergedCount.merge(mm, count, Integer::sum);
|
|
|
mergedWeight.merge(mm, weight, BigDecimal::add);
|
|
|
}
|
|
|
} catch (Exception ignored) {}
|
|
|
|
|
|
try {
|
|
|
- // --- stackLength ---
|
|
|
JsonNode stackArray = objectMapper.readTree(record.getStackLength());
|
|
|
for (JsonNode node : stackArray) {
|
|
|
String mm = node.path("stackingLength").asText();
|
|
|
int count = node.path("stackingCount").asInt(0);
|
|
|
BigDecimal weight = new BigDecimal(node.path("stackingWeight").asText("0"));
|
|
|
+
|
|
|
+ // 应用米重系数
|
|
|
+ weight = weight.multiply(meterWeightFactor);
|
|
|
+
|
|
|
mergedCount.merge(mm, count, Integer::sum);
|
|
|
mergedWeight.merge(mm, weight, BigDecimal::add);
|
|
|
}
|
|
|
} catch (Exception ignored) {}
|
|
|
|
|
|
Date createTime = record.getCreateTime();
|
|
|
- boolean isInClassTime = createTime != null && !createTime.before(classStartTime) && !createTime.after(classEndTime);
|
|
|
- boolean isInDayTime = createTime != null && !createTime.before(startCurrentTime) && !createTime.after(endCurrentTime);
|
|
|
-
|
|
|
- for (Map.Entry<String, Integer> entry : mergedCount.entrySet()) {
|
|
|
- String mmStr = entry.getKey();
|
|
|
- int count = entry.getValue();
|
|
|
- BigDecimal weight = mergedWeight.getOrDefault(mmStr, BigDecimal.ZERO);
|
|
|
- String mStr;
|
|
|
- try {
|
|
|
- BigDecimal mm = new BigDecimal(mmStr);
|
|
|
- mStr = mm.divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP).toString();
|
|
|
- } catch (Exception e) {
|
|
|
- mStr = mmStr;
|
|
|
- }
|
|
|
- vo.getLengthCountMap().put(mStr, count);
|
|
|
- allLengths.add(mStr);
|
|
|
-
|
|
|
- if (isInClassTime) {
|
|
|
- classLengthCountMap.merge(mStr, count, Integer::sum);
|
|
|
- classLengthWeightMap.merge(mStr, weight, BigDecimal::add);
|
|
|
+ if (createTime != null && !createTime.before(classStartTime) && !createTime.after(classEndTime)) {
|
|
|
+ for (Map.Entry<String, Integer> entry : mergedCount.entrySet()) {
|
|
|
+ String mm = entry.getKey();
|
|
|
+ int count = entry.getValue();
|
|
|
+ BigDecimal weight = mergedWeight.getOrDefault(mm, BigDecimal.ZERO);
|
|
|
+
|
|
|
+ classLengthCountMap.merge(mm, count, Integer::sum);
|
|
|
+ classLengthWeightMap.merge(mm, weight, BigDecimal::add);
|
|
|
classTotalCount += count;
|
|
|
classTotalWeight = classTotalWeight.add(weight);
|
|
|
}
|
|
|
- if (isInDayTime) {
|
|
|
- dayLengthCountMap.merge(mStr, count, Integer::sum);
|
|
|
- dayLengthWeightMap.merge(mStr, weight, BigDecimal::add);
|
|
|
- dayTotalCount += count;
|
|
|
- dayTotalWeight = dayTotalWeight.add(weight);
|
|
|
- }
|
|
|
}
|
|
|
-
|
|
|
- resultList.add(vo);
|
|
|
}
|
|
|
|
|
|
- // 补齐定尺列
|
|
|
- for (QualityInspectionVO vo : resultList) {
|
|
|
- for (String length : allLengths) {
|
|
|
- vo.getLengthCountMap().putIfAbsent(length, 0);
|
|
|
- }
|
|
|
+ // 构建日累计数据,初始为当前班次数据
|
|
|
+ Map<String, Integer> dayLengthCountMap = new TreeMap<>(classLengthCountMap);
|
|
|
+ Map<String, BigDecimal> dayLengthWeightMap = new TreeMap<>(classLengthWeightMap);
|
|
|
+ int dayTotalCount = classTotalCount;
|
|
|
+ BigDecimal dayTotalWeight = classTotalWeight;
|
|
|
+
|
|
|
+ // 当前班次信息
|
|
|
+ String shift = shiftRecord.getShift();
|
|
|
+ Map<String, Integer> shiftOrder = new HashMap<>();
|
|
|
+ shiftOrder.put("1", 0); // 夜班
|
|
|
+ shiftOrder.put("0", 1); // 白班
|
|
|
+ shiftOrder.put("2", 2); // 中班
|
|
|
+
|
|
|
+ int currentOrder = shiftOrder.getOrDefault(shift, 99);
|
|
|
+
|
|
|
+ // 查找当前逻辑日内的前置班次
|
|
|
+ List<BilletHotsendChangeShift> previousShifts = allShiftsOfTheDay.stream()
|
|
|
+ .filter(s -> getShiftDate(s.getCreateTime(), s.getShift()).equals(logicalDay))
|
|
|
+ .filter(s -> shiftOrder.getOrDefault(s.getShift(), 99) < currentOrder)
|
|
|
+ .sorted(Comparator.comparing(s -> shiftOrder.getOrDefault(s.getShift(), 99)))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ for (BilletHotsendChangeShift previous : previousShifts) {
|
|
|
+ QualityInspectionStatisticsVO prevVO = this.getStatisticsByShift(previous, allShiftsOfTheDay);
|
|
|
+ prevVO.getClassLengthCountMap().forEach((k, v) -> dayLengthCountMap.merge(k, v, Integer::sum));
|
|
|
+ prevVO.getClassLengthWeightMap().forEach((k, v) -> dayLengthWeightMap.merge(k, v, BigDecimal::add));
|
|
|
+ dayTotalCount += prevVO.getClassTotalCount();
|
|
|
+ dayTotalWeight = dayTotalWeight.add(prevVO.getClassTotalWeight());
|
|
|
}
|
|
|
|
|
|
- // 1. 先对定尺重量 map 统一保留4位小数(班次 + 当天)
|
|
|
+ // 四舍五入保留 4 位小数
|
|
|
Map<String, BigDecimal> roundedClassWeightMap = classLengthWeightMap.entrySet().stream()
|
|
|
- .collect(Collectors.toMap(
|
|
|
- Map.Entry::getKey,
|
|
|
- e -> e.getValue().setScale(4, RoundingMode.HALF_UP)
|
|
|
- ));
|
|
|
+ .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().setScale(4, RoundingMode.HALF_UP)));
|
|
|
|
|
|
Map<String, BigDecimal> roundedDayWeightMap = dayLengthWeightMap.entrySet().stream()
|
|
|
- .collect(Collectors.toMap(
|
|
|
- Map.Entry::getKey,
|
|
|
- e -> e.getValue().setScale(4, RoundingMode.HALF_UP)
|
|
|
- ));
|
|
|
+ .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().setScale(4, RoundingMode.HALF_UP)));
|
|
|
|
|
|
- // 2. 总重量使用已四舍五入后的子项重量相加,再保留4位小数
|
|
|
BigDecimal roundedClassTotalWeight = roundedClassWeightMap.values().stream()
|
|
|
- .reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
- .setScale(4, RoundingMode.HALF_UP);
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(4, RoundingMode.HALF_UP);
|
|
|
|
|
|
BigDecimal roundedDayTotalWeight = roundedDayWeightMap.values().stream()
|
|
|
- .reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
- .setScale(4, RoundingMode.HALF_UP);
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(4, RoundingMode.HALF_UP);
|
|
|
|
|
|
- // 3. 封装 VO 返回
|
|
|
QualityInspectionStatisticsVO stats = new QualityInspectionStatisticsVO();
|
|
|
stats.setClassLengthCountMap(classLengthCountMap);
|
|
|
stats.setClassLengthWeightMap(roundedClassWeightMap);
|
|
|
stats.setClassTotalCount(classTotalCount);
|
|
|
stats.setClassTotalWeight(roundedClassTotalWeight);
|
|
|
-
|
|
|
stats.setDayLengthCountMap(dayLengthCountMap);
|
|
|
stats.setDayLengthWeightMap(roundedDayWeightMap);
|
|
|
stats.setDayTotalCount(dayTotalCount);
|
|
|
stats.setDayTotalWeight(roundedDayTotalWeight);
|
|
|
+ stats.setClassHeatNum(records.size());
|
|
|
+
|
|
|
+ // 合并展示格式
|
|
|
+ Map<String, String> classLengthCountWeight = new TreeMap<>();
|
|
|
+ for (String length : classLengthCountMap.keySet()) {
|
|
|
+ int count = classLengthCountMap.getOrDefault(length, 0);
|
|
|
+ BigDecimal weight = roundedClassWeightMap.getOrDefault(length, BigDecimal.ZERO);
|
|
|
+ classLengthCountWeight.put(length, count + " / " + weight.toPlainString());
|
|
|
+ }
|
|
|
+ stats.setClassLengthCountWeight(classLengthCountWeight);
|
|
|
|
|
|
+ Map<String, String> dayLengthCountWeight = new TreeMap<>();
|
|
|
+ for (String length : dayLengthCountMap.keySet()) {
|
|
|
+ int count = dayLengthCountMap.getOrDefault(length, 0);
|
|
|
+ BigDecimal weight = roundedDayWeightMap.getOrDefault(length, BigDecimal.ZERO);
|
|
|
+ dayLengthCountWeight.put(length, count + " / " + weight.toPlainString());
|
|
|
+ }
|
|
|
+ stats.setDayLengthCountWeight(dayLengthCountWeight);
|
|
|
|
|
|
- Map<String, Object> result = new HashMap<>();
|
|
|
- result.put("records", resultList);
|
|
|
- result.put("statistics", stats);
|
|
|
+ return stats;
|
|
|
+ }
|
|
|
|
|
|
- return result;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断班次所属的业务日期(白班/中班/夜班)
|
|
|
+ * - 夜班(shift = "1"):
|
|
|
+ * - 如果时间在 00:00 ~ 08:00,视为“当天的夜班”
|
|
|
+ * - 如果时间在 23:50 ~ 23:59,视为“第二天的夜班”
|
|
|
+ * - 其他:按正常的 createTime 日期返回
|
|
|
+ */
|
|
|
+ /**
|
|
|
+ * 获取班次逻辑日期:
|
|
|
+ * - 夜班如果时间在 23:50 ~ 次日 08:00,算作第二天夜班
|
|
|
+ * - 其他班次默认用日期当天
|
|
|
+ */
|
|
|
+ private LocalDate getShiftDate(Date date, String shift) {
|
|
|
+ LocalDateTime ldt = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
|
|
|
+ int hour = ldt.getHour();
|
|
|
+ int minute = ldt.getMinute();
|
|
|
+
|
|
|
+ if ("1".equals(shift)) { // 夜班
|
|
|
+ if ((hour == 23 && minute >= 50) || hour < 8) {
|
|
|
+ return ldt.toLocalDate().plusDays(1); // 属于第二天夜班
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ldt.toLocalDate();
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|