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 { ...@@ -2399,142 +2399,243 @@ public class SpaceOptimizeBaseService {
} }
} }
//判断是否需要补时间 //判断是否需要补时间
if (sumOpenTime < dayOpenMinute && CollUtil.isNotEmpty(weightList)) { if (sumOpenTime < dayOpenMinute) {
//创建需要补时间的时间范围 //创建需要补时间的时间范围
List<SpaceOptimizeWeightDuration> replenishList = new ArrayList<>(12); List<SpaceOptimizeDurationDTO> replenishList = new ArrayList<>(12);
//得到开始时间时间戳 int size = optimizeDurationDTOList.size();
DateTime beginTime = weightList.get(0).getTimestamp(); //记录下一个索引位置
for (int i1 = 0; i1 < optimizeDurationDTOList.size() - 1; i1++) { int indexNextRecord = 0;
//取相邻两段时间 //记录上一个索引位置
SpaceOptimizeDurationDTO first = optimizeDurationDTOList.get(i1); int indexLastRecord = -1;
SpaceOptimizeDurationDTO second = optimizeDurationDTOList.get(i1 + 1); for (int i1 = 0; i1 < size; i1++) {
Date firstOpenTime = first.getOpenTime(); //计算需要补的时间
Date firstCloseTime = first.getCloseTime(); long wantMinute = dayOpenMinute - sumOpenTime;
Date secondOpenTime = second.getOpenTime(); //取当前结果
Date secondCloseTime = second.getCloseTime(); SpaceOptimizeDurationDTO current = optimizeDurationDTOList.get(i1);
long closeMinute = DateUtil.between(firstCloseTime, secondOpenTime, DateUnit.MINUTE); Date currentOpenTime = current.getOpenTime();
//判断关井时长是否满足条件 Date currentCloseTime = current.getCloseTime();
if (closeMinute == minCloseMinute) { //计算开井时长
continue; 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 nextWantMinute = this.getCanMinute(nextCloseMinute, minCloseMinute, wantMinute);
long firstOpenMinute = DateUtil.between(firstOpenTime, firstCloseTime, DateUnit.MINUTE); //计算上一段可优化开井时长
if (firstOpenMinute < maxOpenMinute) { long lastWantMinute = this.getCanMinute(lastCloseMinute, minCloseMinute, wantMinute);
//找索引开始/结束位置 //记录(左右移动标识位,可补时间)
int firstBeginIndex = (int) DateUtil.between(beginTime, firstCloseTime, DateUnit.MINUTE) / 30; boolean rightFlag = false;
int firstEndIndex = (int) DateUtil.between(beginTime, DateUtil.offsetMinute(firstCloseTime, optimizeMinute), DateUnit.MINUTE) / 30; boolean leftFlag = false;
if (firstEndIndex >= weightList.size()) { long rightMinute = 0;
firstEndIndex = weightList.size() - 1; long leftMinute = 0;
//当前开井时长能否满足最小开井时长
if (openMinute >= minOpenMinute) {
//还能开多少
long spaceMinute = maxOpenMinute - openMinute;
if (spaceMinute <= 0) {
//没有优化空间 todo:研究研究是否需要往回缩 往回缩spaceMinute为负数
continue;
} }
//累加权重 //补齐:先补小
int weightSum = 0; boolean isNext = nextWantMinute < lastWantMinute;
int endIndex = firstBeginIndex; if (isNext && nextWantMinute > 0) {
//取时间段 rightFlag = true;
SpaceOptimizeWeight optimizeWeight; if (nextWantMinute >= spaceMinute) {
//从前往后推 //在范围内,直接补
for (int i2 = firstBeginIndex; i2 <= firstEndIndex; i2++) { rightMinute = spaceMinute;
optimizeWeight = weightList.get(i2); } else {
if (0 == optimizeWeight.getWeight()) { rightMinute = nextWantMinute;
break;
} }
weightSum += optimizeWeight.getWeight(); } else if (!isNext && lastWantMinute > 0) {
endIndex = i2; leftFlag = true;
} if (lastWantMinute >= spaceMinute) {
//添加优化区间 //在范围内,直接补
if (endIndex > firstBeginIndex) { leftMinute = spaceMinute;
replenishList.add( } else {
SpaceOptimizeWeightDuration.builder() leftMinute = lastWantMinute;
.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;
} }
weightSum += optimizeWeight.getWeight();
beginIndex = i2;
} }
//添加优化区间 //补大:谁大取谁 ---- 计算一大一小,不冲突,不用重置变量
if (beginIndex < secondEndIndex) { if (nextWantMinute > lastWantMinute) {
replenishList.add( //往后移关井时间
SpaceOptimizeWeightDuration.builder() rightFlag = true;
.openIndex(beginIndex) if (nextWantMinute >= spaceMinute) {
.closeIndex(secondEndIndex) //在范围内,直接补
.weight(weightSum) rightMinute = spaceMinute;
.optimizeIndex(i1 + 1) } else {
.build() rightMinute = nextWantMinute;
); }
} else {
//往前移开井时间
leftFlag = true;
if (lastWantMinute >= spaceMinute) {
//在范围内,直接补
leftMinute = spaceMinute;
} else {
leftMinute = lastWantMinute;
}
} }
} } else {
} //不满足最小开井时长,计算一个可补时间的区间
//按权重优先级排序补时间 long minLackMinute = minOpenMinute - openMinute;
if (CollUtil.isNotEmpty(replenishList)) { long maxLackMinute = maxOpenMinute - openMinute;
//计算需要补的时长 //补齐:先补小
long subMinute = dayOpenMinute - sumOpenTime; boolean isNext = nextWantMinute < lastWantMinute;
//按照权重降序排序 if (isNext && nextWantMinute > 0) {
replenishList.sort((o1, o2) -> o2.getWeight() - o1.getWeight()); rightFlag = true;
//遍历,补时间 if (nextWantMinute >= minLackMinute && nextWantMinute <= maxLackMinute) {
for (SpaceOptimizeWeightDuration replenish : replenishList) { //在区间范围内,直接补
if (subMinute <= 0) { rightMinute = nextWantMinute;
break; } 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()); if (nextWantMinute > lastWantMinute) {
//计算剩余可开井时长 //往后移关井时间
long remainOpenMinute = maxOpenMinute - DateUtil.between(durationDTO.getOpenTime(), durationDTO.getCloseTime(), DateUnit.MINUTE); rightFlag = true;
//取可优化时间段 if (nextWantMinute >= minLackMinute && nextWantMinute <= maxLackMinute) {
DateTime startTime = weightList.get(replenish.getOpenIndex()).getTimestamp(); //在区间范围内,直接补
DateTime endTime = weightList.get(replenish.getCloseIndex()).getTimestamp(); rightMinute = nextWantMinute;
//计算可优化时间
long replenishDuration = DateUtil.between(startTime, endTime, DateUnit.MINUTE);
//判断是否可以满足全部优化
if (replenishDuration >= subMinute) {
//可开井时间大于等于需要优化时长
if (remainOpenMinute >= subMinute) {
this.overtime(durationDTO, endTime, (int) subMinute);
break;
} else { } else {
this.overtime(durationDTO, endTime, (int) remainOpenMinute); if (nextWantMinute >= maxLackMinute) {
subMinute -= remainOpenMinute; rightMinute = maxLackMinute;
} else {
rightMinute = nextWantMinute;
}
} }
} else { } else {
//可开井时间大于等于可优化时长 //往前移开井时间
if (remainOpenMinute >= replenishDuration) { leftFlag = true;
this.overtime(durationDTO, endTime, (int) replenishDuration); if (lastWantMinute >= minLackMinute && lastWantMinute <= maxLackMinute) {
subMinute -= replenishDuration; //在区间范围内,直接补
leftMinute = lastWantMinute;
} else { } else {
this.overtime(durationDTO, endTime, (int) remainOpenMinute); if (lastWantMinute >= maxLackMinute) {
subMinute -= remainOpenMinute; 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; 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