Commit 26da6a1b authored by ZWT's avatar ZWT

feat(吉林演示): 松原

1.排查并修复各时段间开优化功能执行异常导致未执行间开优化问题;
2.排查并修复15天间开优化功能执行后,优化结果时间段展示错乱问题;
3.排查并修复光伏功率预测展示功能,实际功率未展示问题;
4.排查并修复天气数据获取服务,数据处理后入库缺少数据问题;

BREAKING CHANGE: 无

Closes 无

[skip ci]
parent a1afa891
......@@ -2399,142 +2399,243 @@ public class SpaceOptimizeBaseService {
}
}
//判断是否需要补时间
if (sumOpenTime < dayOpenMinute && CollUtil.isNotEmpty(weightList)) {
if (sumOpenTime < dayOpenMinute) {
//创建需要补时间的时间范围
List<SpaceOptimizeWeightDuration> replenishList = new ArrayList<>(12);
//得到开始时间时间戳
DateTime beginTime = weightList.get(0).getTimestamp();
for (int i1 = 0; i1 < optimizeDurationDTOList.size() - 1; i1++) {
//取相邻两段时间
SpaceOptimizeDurationDTO first = optimizeDurationDTOList.get(i1);
SpaceOptimizeDurationDTO second = optimizeDurationDTOList.get(i1 + 1);
Date firstOpenTime = first.getOpenTime();
Date firstCloseTime = first.getCloseTime();
Date secondOpenTime = second.getOpenTime();
Date secondCloseTime = second.getCloseTime();
long closeMinute = DateUtil.between(firstCloseTime, secondOpenTime, DateUnit.MINUTE);
//判断关井时长是否满足条件
if (closeMinute == minCloseMinute) {
continue;
List<SpaceOptimizeDurationDTO> replenishList = new ArrayList<>(12);
int size = optimizeDurationDTOList.size();
//记录下一个索引位置
int indexNextRecord = 0;
//记录上一个索引位置
int indexLastRecord = -1;
for (int i1 = 0; i1 < size; i1++) {
//计算需要补的时间
long wantMinute = dayOpenMinute - sumOpenTime;
//取当前结果
SpaceOptimizeDurationDTO current = optimizeDurationDTOList.get(i1);
Date currentOpenTime = current.getOpenTime();
Date currentCloseTime = current.getCloseTime();
//计算开井时长
long openMinute = DateUtil.between(currentOpenTime, currentCloseTime, DateUnit.MINUTE);
//取下一段
if (indexNextRecord == size - 1) {
//如果到最后,下一段则取开头
indexNextRecord = 0;
} else {
indexNextRecord++;
}
SpaceOptimizeDurationDTO next = optimizeDurationDTOList.get(indexNextRecord);
Date nextOpenTime = next.getOpenTime();
//计算和下一段的关井时长
long nextCloseMinute;
if (indexNextRecord == 0) {
//跨天计算
nextCloseMinute = DateUtil.between(currentCloseTime, DateUtil.offsetDay(nextOpenTime, 1), DateUnit.MINUTE);
} else {
nextCloseMinute = DateUtil.between(currentCloseTime, nextOpenTime, DateUnit.MINUTE);
}
//取上一段
if (indexLastRecord == -1) {
//如果到最后,下一段则取开头
indexLastRecord = size - 1;
} else {
indexLastRecord++;
}
SpaceOptimizeDurationDTO last = optimizeDurationDTOList.get(indexNextRecord);
Date lastCloseTime = last.getCloseTime();
//计算和上一段的关井时长
long lastCloseMinute;
if (indexNextRecord == size - 1) {
//跨天计算
lastCloseMinute = DateUtil.between(currentOpenTime, DateUtil.offsetDay(lastCloseTime, -1), DateUnit.MINUTE);
} else {
lastCloseMinute = DateUtil.between(currentOpenTime, lastCloseTime, DateUnit.MINUTE);
}
//计算可优化时长
int optimizeMinute = (int) (closeMinute - minCloseMinute);
//判断是否小于最大开井时长
long firstOpenMinute = DateUtil.between(firstOpenTime, firstCloseTime, DateUnit.MINUTE);
if (firstOpenMinute < maxOpenMinute) {
//找索引开始/结束位置
int firstBeginIndex = (int) DateUtil.between(beginTime, firstCloseTime, DateUnit.MINUTE) / 30;
int firstEndIndex = (int) DateUtil.between(beginTime, DateUtil.offsetMinute(firstCloseTime, optimizeMinute), DateUnit.MINUTE) / 30;
if (firstEndIndex >= weightList.size()) {
firstEndIndex = weightList.size() - 1;
//----------------------------------数据处理----------------------------------
//计算下一段可优化开井时长
long nextWantMinute = this.getCanMinute(nextCloseMinute, minCloseMinute, wantMinute);
//计算上一段可优化开井时长
long lastWantMinute = this.getCanMinute(lastCloseMinute, minCloseMinute, wantMinute);
//记录(左右移动标识位,可补时间)
boolean rightFlag = false;
boolean leftFlag = false;
long rightMinute = 0;
long leftMinute = 0;
//当前开井时长能否满足最小开井时长
if (openMinute >= minOpenMinute) {
//还能开多少
long spaceMinute = maxOpenMinute - openMinute;
if (spaceMinute <= 0) {
//没有优化空间 todo:研究研究是否需要往回缩 往回缩spaceMinute为负数
continue;
}
//累加权重
int weightSum = 0;
int endIndex = firstBeginIndex;
//取时间段
SpaceOptimizeWeight optimizeWeight;
//从前往后推
for (int i2 = firstBeginIndex; i2 <= firstEndIndex; i2++) {
optimizeWeight = weightList.get(i2);
if (0 == optimizeWeight.getWeight()) {
break;
//补齐:先补小
boolean isNext = nextWantMinute < lastWantMinute;
if (isNext && nextWantMinute > 0) {
rightFlag = true;
if (nextWantMinute >= spaceMinute) {
//在范围内,直接补
rightMinute = spaceMinute;
} else {
rightMinute = nextWantMinute;
}
weightSum += optimizeWeight.getWeight();
endIndex = i2;
}
//添加优化区间
if (endIndex > firstBeginIndex) {
replenishList.add(
SpaceOptimizeWeightDuration.builder()
.openIndex(firstBeginIndex)
.closeIndex(endIndex)
.weight(weightSum)
.optimizeIndex(i1)
.build()
);
}
}
/*---------------------------- 计算下一段 -------------------------------*/
long secondOpenMinute = DateUtil.between(secondOpenTime, secondCloseTime, DateUnit.MINUTE);
if (secondOpenMinute < maxOpenMinute) {
//找索引开始/结束位置
int secondBeginIndex = (int) DateUtil.between(beginTime, DateUtil.offsetMinute(secondOpenTime, -optimizeMinute), DateUnit.MINUTE) / 30;
int secondEndIndex = (int) DateUtil.between(beginTime, secondOpenTime, DateUnit.MINUTE) / 30;
//累加权重
int weightSum = 0;
int beginIndex = secondEndIndex;
//取时间段
SpaceOptimizeWeight optimizeWeight;
//从后往前推
for (int i2 = secondEndIndex; i2 > secondBeginIndex; i2--) {
optimizeWeight = weightList.get(i2);
if (0 == optimizeWeight.getWeight()) {
break;
} else if (!isNext && lastWantMinute > 0) {
leftFlag = true;
if (lastWantMinute >= spaceMinute) {
//在范围内,直接补
leftMinute = spaceMinute;
} else {
leftMinute = lastWantMinute;
}
weightSum += optimizeWeight.getWeight();
beginIndex = i2;
}
//添加优化区间
if (beginIndex < secondEndIndex) {
replenishList.add(
SpaceOptimizeWeightDuration.builder()
.openIndex(beginIndex)
.closeIndex(secondEndIndex)
.weight(weightSum)
.optimizeIndex(i1 + 1)
.build()
);
//补大:谁大取谁 ---- 计算一大一小,不冲突,不用重置变量
if (nextWantMinute > lastWantMinute) {
//往后移关井时间
rightFlag = true;
if (nextWantMinute >= spaceMinute) {
//在范围内,直接补
rightMinute = spaceMinute;
} else {
rightMinute = nextWantMinute;
}
} else {
//往前移开井时间
leftFlag = true;
if (lastWantMinute >= spaceMinute) {
//在范围内,直接补
leftMinute = spaceMinute;
} else {
leftMinute = lastWantMinute;
}
}
}
}
//按权重优先级排序补时间
if (CollUtil.isNotEmpty(replenishList)) {
//计算需要补的时长
long subMinute = dayOpenMinute - sumOpenTime;
//按照权重降序排序
replenishList.sort((o1, o2) -> o2.getWeight() - o1.getWeight());
//遍历,补时间
for (SpaceOptimizeWeightDuration replenish : replenishList) {
if (subMinute <= 0) {
break;
} else {
//不满足最小开井时长,计算一个可补时间的区间
long minLackMinute = minOpenMinute - openMinute;
long maxLackMinute = maxOpenMinute - openMinute;
//补齐:先补小
boolean isNext = nextWantMinute < lastWantMinute;
if (isNext && nextWantMinute > 0) {
rightFlag = true;
if (nextWantMinute >= minLackMinute && nextWantMinute <= maxLackMinute) {
//在区间范围内,直接补
rightMinute = nextWantMinute;
} else {
if (nextWantMinute >= minLackMinute) {
rightMinute = minLackMinute;
} else {
rightMinute = nextWantMinute;
}
}
} else if (!isNext && lastWantMinute > 0) {
leftFlag = true;
if (lastWantMinute >= minLackMinute && lastWantMinute <= maxLackMinute) {
//在区间范围内,直接补
leftMinute = lastWantMinute;
} else {
if (lastWantMinute >= minLackMinute) {
leftMinute = minLackMinute;
} else {
leftMinute = lastWantMinute;
}
}
}
//取需要优化的时间段
SpaceOptimizeDurationDTO durationDTO = optimizeDurationDTOList.get(replenish.getOptimizeIndex());
//计算剩余可开井时长
long remainOpenMinute = maxOpenMinute - DateUtil.between(durationDTO.getOpenTime(), durationDTO.getCloseTime(), DateUnit.MINUTE);
//取可优化时间段
DateTime startTime = weightList.get(replenish.getOpenIndex()).getTimestamp();
DateTime endTime = weightList.get(replenish.getCloseIndex()).getTimestamp();
//计算可优化时间
long replenishDuration = DateUtil.between(startTime, endTime, DateUnit.MINUTE);
//判断是否可以满足全部优化
if (replenishDuration >= subMinute) {
//可开井时间大于等于需要优化时长
if (remainOpenMinute >= subMinute) {
this.overtime(durationDTO, endTime, (int) subMinute);
break;
//补大:谁大取谁 ---- 计算一大一小,不冲突,不用重置变量
if (nextWantMinute > lastWantMinute) {
//往后移关井时间
rightFlag = true;
if (nextWantMinute >= minLackMinute && nextWantMinute <= maxLackMinute) {
//在区间范围内,直接补
rightMinute = nextWantMinute;
} else {
this.overtime(durationDTO, endTime, (int) remainOpenMinute);
subMinute -= remainOpenMinute;
if (nextWantMinute >= maxLackMinute) {
rightMinute = maxLackMinute;
} else {
rightMinute = nextWantMinute;
}
}
} else {
//可开井时间大于等于可优化时长
if (remainOpenMinute >= replenishDuration) {
this.overtime(durationDTO, endTime, (int) replenishDuration);
subMinute -= replenishDuration;
//往前移开井时间
leftFlag = true;
if (lastWantMinute >= minLackMinute && lastWantMinute <= maxLackMinute) {
//在区间范围内,直接补
leftMinute = lastWantMinute;
} else {
this.overtime(durationDTO, endTime, (int) remainOpenMinute);
subMinute -= remainOpenMinute;
if (lastWantMinute >= maxLackMinute) {
leftMinute = maxLackMinute;
} else {
leftMinute = lastWantMinute;
}
}
}
}
} else {
//todo : 没法补时间
//算时间补,修改总时间
DateTime optimizeTime;
if (rightFlag) {
optimizeTime = DateUtil.offsetMinute(currentCloseTime, (int) rightMinute);
if (DateUtil.compare(optimizeTime, BusinessConstant.DATE_FLAG) >= 0) {
//跨天转换,加到优化数组里
SpaceOptimizeDurationDTO copy = XCopyUtils.copyNewObject(current, SpaceOptimizeDurationDTO.class);
copy.setOpenTime(BusinessConstant.DATE_FLAG_BEGIN);
copy.setCloseTime(DateUtil.offsetDay(optimizeTime, -1));
replenishList.add(copy);
//重置结束时间到第二天0点
optimizeDurationDTOList.get(i1).setCloseTime(BusinessConstant.DATE_FLAG);
} else {
optimizeDurationDTOList.get(i1).setCloseTime(optimizeTime);
}
dayOpenMinute = dayOpenMinute - (int) rightMinute;
}
if (leftFlag) {
optimizeTime = DateUtil.offsetMinute(currentOpenTime, (int) -leftMinute);
if (DateUtil.compare(optimizeTime, BusinessConstant.DATE_FLAG_BEGIN) <= 0) {
//跨天转换,加到优化数组里
SpaceOptimizeDurationDTO copy = XCopyUtils.copyNewObject(current, SpaceOptimizeDurationDTO.class);
copy.setOpenTime(DateUtil.offsetDay(optimizeTime, 1));
copy.setCloseTime(BusinessConstant.DATE_FLAG);
replenishList.add(copy);
//重置开始时间到第一天0点
optimizeDurationDTOList.get(i1).setOpenTime(BusinessConstant.DATE_FLAG_BEGIN);
} else {
optimizeDurationDTOList.get(i1).setOpenTime(optimizeTime);
}
dayOpenMinute = dayOpenMinute - (int) leftMinute;
}
}
//将优化结果加入结果集中,并重新排序
if (CollUtil.isNotEmpty(replenishList)) {
for (SpaceOptimizeDurationDTO spaceOptimizeDurationDTO : replenishList) {
optimizeDurationDTOList.add(spaceOptimizeDurationDTO);
}
}
}
return firstOpenWellTime;
}
/**
* 可优化时长计算
*
* @param closeMinute 关闭分钟
* @param minCloseMinute 分钟关闭分钟
* @param wantMinute 需要补的总时间
* @return long
*/
private long getCanMinute(long closeMinute, long minCloseMinute, long wantMinute) {
long canMinute;
if (closeMinute == minCloseMinute) {
//满足最小关井时长舍弃
canMinute = 0;
} else if (closeMinute > minCloseMinute) {
//关井时长比最小设定值大
canMinute = closeMinute - minCloseMinute;
} else {
//不满足最小关井时长,能否合并
canMinute = closeMinute;
}
if (canMinute > wantMinute) {
canMinute = wantMinute;
}
return canMinute;
}
/**
* 添加优化结果
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment