方案数据历史趋势优化时间交叉范围(修改fuseWlRecordTime方法)

This commit is contained in:
guofeihu
2024-07-11 19:55:35 +08:00
parent c00cab7689
commit db04121fb6
2 changed files with 54 additions and 8 deletions

View File

@@ -88,6 +88,6 @@
test_item_id = #{testRecordId}
</if>
)
order by dev_id
order by start_time
</select>
</mapper>

View File

@@ -33,6 +33,7 @@ import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.system.pojo.po.EleEpdPqd;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -51,6 +52,7 @@ import java.util.stream.Stream;
* @author xuyang
* @since 2024-04-01
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class WlRecordServiceImpl extends ServiceImpl<WlRecordMapper, WlRecord> implements IWlRecordService {
@@ -281,8 +283,7 @@ public class WlRecordServiceImpl extends ServiceImpl<WlRecordMapper, WlRecord> i
}
//进行时间覆盖(查询的基础数据必须两个以上)
if(data.size()>1){
//fuseWlRecordTime(data,0);
//fuseWlRecordTime(data,0);
data = fuseWlRecordTime(data,0);
}
//格式化前端参数
formatQueryParamList(commonStatisticalQueryParam);
@@ -336,18 +337,63 @@ public class WlRecordServiceImpl extends ServiceImpl<WlRecordMapper, WlRecord> i
/**
* 数据项内的时间进行覆盖:解决多个数据项的startTime及endTime之间存在时间冲突
* @param data 数据项
* @param flag 覆盖规则(0:从左到右依次覆盖,1:时间范围度最大依次覆盖)
* @param flag 覆盖规则(0:从左到右依次覆盖,1:时间范围度最大依次覆盖) *注:从左到右依次覆盖规则下多个数据项必须按照 "开始时间升序排序"
*/
private void fuseWlRecordTime(List<WlRecord> data,int flag){
private static List<WlRecord> fuseWlRecordTime(List<WlRecord> data,int flag){
List<WlRecord> rs = new ArrayList<>();
log.info("覆盖规则为:{}",flag == 0 ? "从左到右依次覆盖":"时间范围度最大依次覆盖");
log.info("覆盖前源数据:");
for(WlRecord wlRecord : data){
log.info("id:{} , startTime:{} , endTime:{}",wlRecord.getId(),wlRecord.getStartTime().format(DateTimeFormatter.ofPattern(DataParam.timeFormat)),wlRecord.getEndTime().format(DateTimeFormatter.ofPattern(DataParam.timeFormat)));
}
if(flag == 0){
//为防止意外 还是进行下排序
data = data.stream().sorted(Comparator.comparing(WlRecord::getStartTime)).collect(Collectors.toList());
//从左到右依次覆盖
//由于覆盖规则是最左原则 所以第一个左主数据一定是有效的
rs.add(data.get(0));
WlRecord tempRecord = null;
for (int i = 0; i < data.size(); i++) {
for (int j = 0; j < data.size(); j++) {
if(data.get(0).getEndTime().isBefore(data.get(j+1).getEndTime())){
if(i<data.size()-1){
WlRecord current = null;
//当前比较的左主数据
if(tempRecord == null){
//正常便利获取左主数据(1-2,2-3,3-4...)
current = data.get(i);
}else{
//上一轮左主数据把上一轮的被比数据吃掉了 那么继续拿上一轮数据作为左主数据进行比较(1-2,1-3,1-4,4-5,4-5...)
current = tempRecord;
}
//下一个被比较数据
int index = i + 1;
WlRecord next = data.get(index);
//判断下一个数据时间范围是不是在当前时间范围内(判断是否有修改的必要)
if((current.getStartTime().compareTo(next.getStartTime())<0 || current.getStartTime().compareTo(next.getStartTime())==0)
&& (current.getEndTime().compareTo(next.getEndTime())>0 || current.getEndTime().compareTo(next.getEndTime())==0)){
//如果当前节点把下一个节点吃掉了 那么此节点将不变继续作为当前比较的左主数据 参加下一轮比较
tempRecord = current;
continue;
}else if(current.getEndTime().compareTo(next.getStartTime())<0){
//这种属于两个节点的数据本来就没有交叉 属于正常时间串
rs.add(next);
tempRecord = null;
}else{
//时间出现交叉
next.setStartTime(current.getEndTime().plusSeconds(1));
rs.add(next);
tempRecord = null;
}
}
}
}else{
//时间范围度最大依次覆盖
//此处逻辑暂定 默认按照上面最左原则
}
log.info("覆盖后新数据:");
for(WlRecord wlRecord : rs){
log.info("id:{} , startTime:{} , endTime:{}",wlRecord.getId(),wlRecord.getStartTime().format(DateTimeFormatter.ofPattern(DataParam.timeFormat)),wlRecord.getEndTime().format(DateTimeFormatter.ofPattern(DataParam.timeFormat)));
}
return rs;
}
private void formatQueryParamList(CommonStatisticalQueryParam commonStatisticalQueryParam){