Commit 137ea7f8 authored by tianchao's avatar tianchao

Merge branch 'master' of https://gitlab.sunboxauto.com/tianchao/gf_back

 Conflicts:
	D03-deploy/deploy-pps-all/src/main/java/app/DeployPpsAllApplication.java
	D03-deploy/deploy-pps-all/src/main/resources/deploy-pps-all.app.properties
	D03-deploy/deploy-pps-task/src/main/java/app/DeployPpsTaskApplication.java
	D03-deploy/deploy-pps-task/src/main/resources/deploy-pps-task.app.properties
parents c222a1ab 7da51c66
......@@ -11,6 +11,23 @@ import cn.hutool.core.date.DateUtil;
*/
public class BusinessConstant {
/**
* 初始父级组织机构ID
*/
public static final String PARENT_OU_ID = "00000000-0000-0000-0000-000000000000";
/**
* 光伏电站
*/
public static final String PHOTOVOLTAIC_POWER_STATION = "photovoltaic_power_station";
/**
* 井口
*/
public static final String WELLHEAD = "wellhead";
/*------------------------------数字------------------------------*/
/**
* 1
*/
......@@ -26,10 +43,17 @@ public class BusinessConstant {
*/
public static final Integer TEN = 10;
/*------------------------------日期------------------------------*/
/**
* 初始父级组织机构ID
* 日期格式化到天
*/
public static final String PARENT_OU_ID = "00000000-0000-0000-0000-000000000000";
public static final String DATE_FORMAT_DAY = "yyyy-MM-dd";
/**
* 日期格式化到天(年月日)
*/
public static final String DATE_FORMAT_DAY_C = "yyyy年MM月dd日";
/**
* 时间格式
......
......@@ -104,9 +104,39 @@ public class BaseUtils {
*/
public static String getExecutionCycleForMonth(Date date) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(DateUtil.format(DateUtil.beginOfMonth(date), "yyyy-MM-dd"))
stringBuilder.append(DateUtil.format(DateUtil.beginOfDay(date), BusinessConstant.DATE_FORMAT_DAY_C))
.append('-')
.append(DateUtil.format(DateUtil.endOfMonth(date), "yyyy-MM-dd"));
.append(DateUtil.format(DateUtil.endOfMonth(date), BusinessConstant.DATE_FORMAT_DAY_C));
return stringBuilder.toString();
}
/**
* 获取周执行周期
*
* @param date 日期
* @return {@link String}
*/
public static String getExecutionCycleForWeek(DateTime date) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(date.year())
.append("年第")
.append(date.weekOfYear())
.append('周');
return stringBuilder.toString();
}
/**
* 获取校准执行周期
*
* @param date 日期
* @param offset 抵消
* @return {@link String}
*/
public static String getExecutionCycleForCalibration(Date date, int offset) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(DateUtil.format(DateUtil.beginOfDay(date), BusinessConstant.DATE_FORMAT_DAY_C))
.append('-')
.append(DateUtil.format(DateUtil.offsetDay(date, offset), BusinessConstant.DATE_FORMAT_DAY_C));
return stringBuilder.toString();
}
......
......@@ -9,12 +9,22 @@ package pps.core.task.constant;
public class CronConstant {
/**
* 每月第一天 0
* 每月第一天 00:30:00
*/
public static final String FIRST_DAY_OF_THE_MONTH = "0 0 0 1 * ?";
public static final String FIRST_DAY_OF_THE_MONTH = "0 30 0 1 * ?";
/**
* 每周一 0
* 每周一 00:00:00
*/
public static final String EVERY_MONDAY = "0 0 0 ? * 2";
/**
* 每一天 00:15:00
*/
public static final String EVERY_DAY = "0 15 0 * * ?";
/**
* 每一天结束时间 23:30:00
*/
public static final String END_OF_DAY = "0 30 23 * * ?";
}
package pps.core.task.job;
import pps.cloud.space.service.ISpaceCalibrationCloudService;
import pps.core.task.constant.CronConstant;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.base.tool.XLoggerTool;
import xstartup.data.XServiceResult;
import xstartup.service.job.XJob;
import xstartup.service.job.annotation.XCronTrigger;
/**
* 定期校准定时任务
*
* @author ZWT
* @date 2023/09/20 09:20
*/
@XText("长期间开优化定时任务")
@XService
public class SpaceCalibrationJob implements XJob {
/**
* 处决
*
* @param xContext x上下文
* @return {@link XServiceResult}
*/
@XCronTrigger(value = CronConstant.EVERY_DAY)
@Override
public XServiceResult execute(XContext xContext) {
XLoggerTool logger = xContext.getLogger();
logger.info("------ SpaceCalibrationJob start:{}", System.currentTimeMillis());
ISpaceCalibrationCloudService service = xContext.getBean(ISpaceCalibrationCloudService.class);
XServiceResult result = service.calibrateJob(xContext);
result.throwIfFail();
logger.info("------ SpaceCalibrationJob end:{}", System.currentTimeMillis());
return XServiceResult.OK;
}
}
......@@ -5,6 +5,7 @@ import pps.core.task.constant.CronConstant;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.base.tool.XLoggerTool;
import xstartup.data.XServiceResult;
import xstartup.service.job.XJob;
import xstartup.service.job.annotation.XCronTrigger;
......@@ -28,9 +29,12 @@ public class SpaceOptimizeLongJob implements XJob {
@XCronTrigger(value = CronConstant.FIRST_DAY_OF_THE_MONTH)
@Override
public XServiceResult execute(XContext xContext) {
XLoggerTool logger = xContext.getLogger();
logger.info("------ SpaceOptimizeLongJob start:{}", System.currentTimeMillis());
ISpaceOptimizeLongCloudService service = xContext.getBean(ISpaceOptimizeLongCloudService.class);
XServiceResult result = service.optimizeLongJob(xContext);
result.throwIfFail();
logger.info("------ SpaceOptimizeLongJob end:{}", System.currentTimeMillis());
return XServiceResult.OK;
}
}
\ No newline at end of file
package pps.core.task.job;
import pps.cloud.space.service.ISpaceOptimizeMidCloudService;
import pps.core.task.constant.CronConstant;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.base.tool.XLoggerTool;
import xstartup.data.XServiceResult;
import xstartup.service.job.XJob;
import xstartup.service.job.annotation.XCronTrigger;
......@@ -27,6 +29,12 @@ public class SpaceOptimizeMidJob implements XJob {
@XCronTrigger(value = CronConstant.EVERY_MONDAY)
@Override
public XServiceResult execute(XContext xContext) {
XLoggerTool logger = xContext.getLogger();
logger.info("------ SpaceOptimizeMidJob start:{}", System.currentTimeMillis());
ISpaceOptimizeMidCloudService service = xContext.getBean(ISpaceOptimizeMidCloudService.class);
XServiceResult result = service.optimizeMidJob(xContext);
result.throwIfFail();
logger.info("------ SpaceOptimizeMidJob end:{}", System.currentTimeMillis());
return XServiceResult.OK;
}
}
package pps.core.task.job;
import pps.cloud.space.service.ISpaceOptimizeShortCloudService;
import pps.core.task.constant.CronConstant;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.base.tool.XLoggerTool;
import xstartup.data.XServiceResult;
import xstartup.service.job.XJob;
import xstartup.service.job.annotation.XCronTrigger;
/**
* 短期间开优化定时任务
*
* @author ZWT
* @date 2023/09/20 11:39
*/
@XText("短期间开优化定时任务")
@XService
public class SpaceOptimizeShortJob implements XJob {
/**
* 每一天 23:30:00 执行
*
* @param xContext x上下文
* @return {@link XServiceResult}
*/
@XCronTrigger(value = CronConstant.END_OF_DAY)
@Override
public XServiceResult execute(XContext xContext) {
XLoggerTool logger = xContext.getLogger();
logger.info("------ SpaceOptimizeShortJob start:{}", System.currentTimeMillis());
ISpaceOptimizeShortCloudService service = xContext.getBean(ISpaceOptimizeShortCloudService.class);
XServiceResult result = service.optimizeShortJob(xContext);
result.throwIfFail();
logger.info("------ SpaceOptimizeShortJob end:{}", System.currentTimeMillis());
return XServiceResult.OK;
}
}
package pps.cloud.space.service;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
/**
* 定期校准Cloud模块
*
* @author ZWT
* @date 2023/09/20 09:36
*/
@XService
@XText("定期校准Cloud模块")
public interface ISpaceCalibrationCloudService {
/**
* 定期校准Cloud模块--定时任务
*
* @param context 上下文
* @return {@link XServiceResult}
*/
@XText("定期校准Cloud模块--定时任务")
XServiceResult calibrateJob(XContext context);
}
package pps.cloud.space.service;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
/**
* 中短期间开优化Cloud模块
*
* @author ZWT
* @date 2023/09/13 14:03
*/
@XService
@XText("中短期间开优化Cloud模块")
public interface ISpaceOptimizeMidCloudService {
/**
* 中短期间开优化Cloud模块--定时任务
*
* @param context 上下文
* @return {@link XServiceResult}
*/
@XText("中短期间开优化Cloud模块--定时任务")
XServiceResult optimizeMidJob(XContext context);
}
\ No newline at end of file
package pps.cloud.space.service;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
/**
* 短期间开优化Cloud模块
*
* @author ZWT
* @date 2023/09/20 11:43
*/
@XService
@XText("短期间开优化Cloud模块")
public interface ISpaceOptimizeShortCloudService {
/**
* 短期间开优化Cloud模块--定时任务
*
* @param context 上下文
* @return {@link XServiceResult}
*/
@XText("中短期间开优化Cloud模块--定时任务")
XServiceResult optimizeShortJob(XContext context);
}
package pps.core.space.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import pps.core.common.entity.BaseModel;
import xstartup.annotation.XText;
import java.io.Serializable;
/**
* 间开优化井口制度记录
*
* @author ZWT
* @date 2023/09/05
*/
@Data
public class SpaceOptimizeDurationDTO extends BaseModel implements Serializable {
@XText("井口记录ID")
@TableField
private String recordId;
@XText("间开优化周期ID")
@TableField
private String periodId;
@XText("井口ID")
@TableField
private String wellheadId;
@XText("是否优化(0_是;1_否)")
@TableField
private Integer isOptimize;
@XText("发电类型key(字典获取)")
@TableField
private String generationTypeKey;
@XText("开井时间")
@TableField
private String openWellTime;
@XText("关井时间")
@TableField
private String closeWellTime;
}
package pps.core.space.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import pps.core.common.entity.BaseModel;
import xstartup.annotation.XText;
import java.io.Serializable;
import java.util.Date;
/**
* 间开优化周期记录
*
* @author ZWT
* @date 2023/09/05
*/
@Data
public class SpaceOptimizePeriodDTO extends BaseModel implements Serializable {
@XText("线路ID")
@TableField
private String lineId;
@XText("间开制度ID")
@TableField
private String institutionId;
@XText("执行周期")
@TableField
private String executionCycle;
@XText("优化状态(0_已优化;1_未优化)")
@TableField
private Integer optimizeState;
@XText("优化截止日期")
@TableField
private Date optimizeDeadline;
}
package pps.core.space.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import pps.core.common.entity.BaseModel;
import xstartup.annotation.XText;
import java.io.Serializable;
/**
* 间开优化井口记录
*
* @author ZWT
* @date 2023/09/05
*/
@Data
public class SpaceOptimizeWellheadDTO extends BaseModel implements Serializable {
@XText("间开优化周期ID")
@TableField
private String periodId;
@XText("井口ID")
@TableField
private String wellheadId;
@XText("井号")
@TableField
private String wellNumber;
}
......@@ -11,9 +11,11 @@ import xstartup.error.XError;
public enum BusinessError implements XError {
LineExists(2100, "当前线路已设定周期"),
RepeatSetting(2101, "请勿重复设定"),
DidNotFindSpace(2102, "未发现可优化基础间开制度"),
DidNotFindSpace(2102, "未发现可基础间开制度"),
DidNotFindWellhead(2103, "未发现可优化井口"),
DidNotFindPlant(2104, "未发现可用光伏电站"),
DidNotFindCalibration(2105, "未发现可用周期配置"),
UnableToOptimize(2106, "无法优化"),
;
private int code;
......
package pps.core.space.mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import pps.core.space.entity.SpaceCalibrationHistoryView;
......@@ -29,4 +30,12 @@ public interface SpaceCalibrationHistoryViewMapper {
* @return {@link List}<{@link SpaceCalibrationHistoryView}>
*/
List<SpaceCalibrationHistoryView> selectList(SpaceCalibrationHistoryView record);
/**
* 批量新增
*
* @param list 列表
* @return int
*/
int batchInsertList(@Param(value = "list") List<SpaceCalibrationHistoryView> list);
}
package pps.core.space.mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import pps.core.space.entity.*;
import java.util.List;
/**
* 间开优化
*
* @author ZWT
* @date 2023/09/19 09:40
*/
@Repository(value = "pps.core.space.mapper.SpaceOptimizeViewMapper")
public interface SpaceOptimizeViewMapper {
/**
* 长期间开优化批量新增
*
* @param list 列表
* @return int
*/
int longPeriodBatchInsertList(@Param(value = "list") List<SpaceOptimizePeriodDTO> list);
/**
* 长期间开优化井口批量新增
*
* @param list 列表
* @return int
*/
int longWellheadBatchInsertList(@Param(value = "list") List<SpaceOptimizeWellheadDTO> list);
/**
* 长期间开优化井口配置批量新增
*
* @param list 列表
* @return int
*/
int longDurationBatchInsertList(@Param(value = "list") List<SpaceOptimizeDurationDTO> list);
/**
* 长期间开优化批量新增
*
* @param list 列表
* @return int
*/
int midPeriodBatchInsertList(@Param(value = "list") List<SpaceOptimizePeriodDTO> list);
/**
* 长期间开优化井口批量新增
*
* @param list 列表
* @return int
*/
int midWellheadBatchInsertList(@Param(value = "list") List<SpaceOptimizeWellheadDTO> list);
/**
* 长期间开优化井口配置批量新增
*
* @param list 列表
* @return int
*/
int midDurationBatchInsertList(@Param(value = "list") List<SpaceOptimizeDurationDTO> list);
}
package pps.core.space.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import pps.cloud.space.service.ISpaceCalibrationCloudService;
import pps.core.common.constant.BusinessConstant;
import pps.core.common.entity.BaseModel;
import pps.core.common.utils.BaseUtils;
import pps.core.space.entity.SpaceCalibrationHistoryEnt;
import pps.core.space.entity.SpaceCalibrationHistoryView;
import pps.core.space.entity.SpaceCalibrationPeriodEnt;
import pps.core.space.entity.SpaceInstitutionDetailEnt;
import pps.core.space.enums.BusinessError;
import pps.core.space.mapper.SpaceCalibrationHistoryMapper;
import pps.core.space.mapper.SpaceCalibrationHistoryViewMapper;
import pps.core.space.mapper.SpaceCalibrationPeriodMapper;
import pps.core.space.mapper.SpaceInstitutionDetailMapper;
import xstartup.annotation.XService;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
import xstartup.helper.XTransactionHelper;
import java.util.*;
import java.util.stream.Collectors;
/**
* 定期校准Cloud模块
*
* @author ZWT
* @date 2023/09/20 09:40
*/
@XService
public class SpaceCalibrationCloudServiceImpl implements ISpaceCalibrationCloudService {
/**
* 定期校准Cloud模块--定时任务
*
* @param context 上下文
* @return {@link XServiceResult}
*/
@Override
public XServiceResult calibrateJob(XContext context) {
//查出所有周期配置
SpaceCalibrationPeriodMapper mapper = context.getBean(SpaceCalibrationPeriodMapper.class);
List<SpaceCalibrationPeriodEnt> calibrationList = mapper.selectList(new LambdaQueryWrapper<SpaceCalibrationPeriodEnt>()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
);
if (CollUtil.isEmpty(calibrationList)) {
return XServiceResult.error(context, BusinessError.DidNotFindCalibration);
}
//取当前时间
DateTime date = DateUtil.date();
String sameDay = date.toString(BusinessConstant.DATE_FORMAT_DAY);
//查生效中的基础间开
SpaceInstitutionDetailMapper detailMapper = context.getBean(SpaceInstitutionDetailMapper.class);
List<SpaceInstitutionDetailEnt> detailEntList = detailMapper.selectList(new LambdaQueryWrapper<SpaceInstitutionDetailEnt>()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceInstitutionDetailEnt::getIsCurrentBasic, BusinessConstant.ZERO)
.in(SpaceInstitutionDetailEnt::getLineId,
calibrationList.stream()
.map(SpaceCalibrationPeriodEnt::getLineId)
.collect(Collectors.toList()))
.le(SpaceInstitutionDetailEnt::getInstitutionStartDate, sameDay)
.ge(SpaceInstitutionDetailEnt::getInstitutionEndDate, sameDay)
);
if (CollUtil.isEmpty(detailEntList)) {
return XServiceResult.error(context, BusinessError.DidNotFindSpace);
}
//生效中的间开按照线路ID分组
Map<String, List<SpaceInstitutionDetailEnt>> institutionDetailMap = detailEntList.stream()
.collect(Collectors.groupingBy(SpaceInstitutionDetailEnt::getLineId));
//周期数据处理
List<SpaceCalibrationHistoryView> historyViewList = new ArrayList<>(128);
String lineId;
Integer dayNumber;
List<SpaceInstitutionDetailEnt> institutionDetailList;
SpaceCalibrationHistoryMapper historyMapper = context.getBean(SpaceCalibrationHistoryMapper.class);
for (SpaceCalibrationPeriodEnt calibration : calibrationList) {
lineId = calibration.getLineId();
if (!institutionDetailMap.containsKey(lineId)) {
continue;
}
institutionDetailList = institutionDetailMap.get(lineId);
if (CollUtil.isEmpty(institutionDetailList)) {
continue;
}
dayNumber = Integer.valueOf(calibration.getDayNumber());
for (SpaceInstitutionDetailEnt detailEnt : institutionDetailList) {
String institutionId = detailEnt.getId();
//查当前制度最新的的历史周期
SpaceCalibrationHistoryEnt lastHistory = historyMapper.selectOne(new LambdaQueryWrapper<SpaceCalibrationHistoryEnt>()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceCalibrationHistoryEnt::getInstitutionId, institutionId)
.orderByDesc(SpaceCalibrationHistoryEnt::getCalibrationDate)
.last("limit 1")
);
if (Objects.isNull(lastHistory)) {
//创建周期
this.createCalibrationHistory(historyViewList, lineId, institutionId, date, dayNumber);
} else {
//判断当前时间是否大于等于周期校准时间
Date calibrationDate = lastHistory.getCalibrationDate();
if (DateUtil.compare(date, calibrationDate) >= 0) {
this.createCalibrationHistory(historyViewList, lineId, institutionId, calibrationDate, dayNumber);
}
}
}
}
//开启事务
return XTransactionHelper.begin(context, () -> {
SpaceCalibrationHistoryViewMapper historyViewMapper = context.getBean(SpaceCalibrationHistoryViewMapper.class);
if (CollUtil.isNotEmpty(historyViewList)) {
int size = historyViewList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceCalibrationHistoryView>> subList = BaseUtils.getSubList(historyViewList);
subList.forEach(b -> historyViewMapper.batchInsertList(b));
} else {
historyViewMapper.batchInsertList(historyViewList);
}
}
return XServiceResult.OK;
});
}
/*-----------------------------------private-----------------------------------*/
/**
* 创建校准历史记录
*
* @param historyViewList 历史视图列表
* @param lineId 线路id
* @param institutionId 机构id
* @param date 日期
* @param dayNumber 天数
*/
private void createCalibrationHistory(List<SpaceCalibrationHistoryView> historyViewList, String lineId,
String institutionId, Date date, Integer dayNumber) {
SpaceCalibrationHistoryView historyView = new SpaceCalibrationHistoryView();
BaseUtils.setBaseModelDefaultForJob(historyView);
historyView.setLineId(lineId);
historyView.setInstitutionId(institutionId);
historyView.setExecutionCycle(BaseUtils.getExecutionCycleForCalibration(date, dayNumber));
historyView.setCalibrationDate(DateUtil.beginOfDay(DateUtil.offsetDay(date, dayNumber + 1)));
historyViewList.add(historyView);
}
}
package pps.core.space.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
......@@ -10,10 +12,12 @@ import pps.core.common.session.PpsUserSession;
import pps.core.common.utils.BaseUtils;
import pps.core.space.entity.SpaceCalibrationHistoryView;
import pps.core.space.entity.SpaceCalibrationPeriodEnt;
import pps.core.space.entity.SpaceInstitutionDetailEnt;
import pps.core.space.entity.SpaceInstitutionWellheadEnt;
import pps.core.space.enums.BusinessError;
import pps.core.space.mapper.SpaceCalibrationHistoryViewMapper;
import pps.core.space.mapper.SpaceCalibrationPeriodMapper;
import pps.core.space.mapper.SpaceInstitutionDetailMapper;
import pps.core.space.mapper.SpaceInstitutionWellheadMapper;
import pps.core.space.service.data.space_calibration_history.QuerySpaceCalibrationHistoryInput;
import pps.core.space.service.data.space_calibration_history.QuerySpaceCalibrationHistoryOutput;
......@@ -38,10 +42,7 @@ import xstartup.feature.api.annotation.XApiGet;
import xstartup.feature.api.annotation.XApiPost;
import xstartup.helper.XTransactionHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.stream.Collectors;
/**
......@@ -66,15 +67,39 @@ public class SpaceCalibrationService {
@XText("校准周期--新增")
public XServiceResult createSpaceCalibrationPeriod(XContext context, CreateSpaceCalibrationPeriodInput input) {
PpsUserSession session = context.getSession(PpsUserSession.class);
return XTransactionHelper.begin(context, () -> {
SpaceCalibrationPeriodMapper mapper = context.getBean(SpaceCalibrationPeriodMapper.class);
SpaceCalibrationPeriodEnt periodEnt = this.getPeriodEntByParam(mapper, input.getLineId(), input.getOuId());
if (Objects.nonNull(periodEnt)) {
return XServiceResult.error(context, BusinessError.LineExists);
}
SpaceCalibrationPeriodEnt entity = XCopyUtils.copyNewObject(input, SpaceCalibrationPeriodEnt.class);
//查生效中的基础间开
String lineId = entity.getLineId();
//取当前时间
DateTime date = DateUtil.date();
String sameDay = date.toString(BusinessConstant.DATE_FORMAT_DAY);
SpaceInstitutionDetailMapper detailMapper = context.getBean(SpaceInstitutionDetailMapper.class);
List<SpaceInstitutionDetailEnt> detailEntList = detailMapper.selectList(new LambdaQueryWrapper<SpaceInstitutionDetailEnt>()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceInstitutionDetailEnt::getIsCurrentBasic, BusinessConstant.ZERO)
.eq(SpaceInstitutionDetailEnt::getLineId, lineId)
.le(SpaceInstitutionDetailEnt::getInstitutionStartDate, sameDay)
.ge(SpaceInstitutionDetailEnt::getInstitutionEndDate, sameDay)
);
List<SpaceCalibrationHistoryView> historyViewList = new ArrayList<>(8);
if (CollUtil.isNotEmpty(detailEntList)) {
for (SpaceInstitutionDetailEnt detailEnt : detailEntList) {
//创建周期
this.createCalibrationHistory(historyViewList, lineId, detailEnt.getId(), date, Integer.valueOf(entity.getDayNumber()));
}
}
return XTransactionHelper.begin(context, () -> {
BaseUtils.setBaseModelDefault(entity, session);
mapper.insert(entity);
SpaceCalibrationHistoryViewMapper historyViewMapper = context.getBean(SpaceCalibrationHistoryViewMapper.class);
if (CollUtil.isNotEmpty(historyViewList)) {
historyViewMapper.batchInsertList(historyViewList);
}
return XServiceResult.OK;
});
}
......@@ -217,4 +242,25 @@ public class SpaceCalibrationService {
.eq(SpaceCalibrationPeriodEnt::getOuId, ouId)
);
}
/**
* 创建校准历史记录
*
* @param historyViewList 历史视图列表
* @param lineId 线路id
* @param institutionId 机构id
* @param date 日期
* @param dayNumber 天数
*/
private void createCalibrationHistory(List<SpaceCalibrationHistoryView> historyViewList, String lineId,
String institutionId, Date date, Integer dayNumber) {
SpaceCalibrationHistoryView historyView = new SpaceCalibrationHistoryView();
BaseUtils.setBaseModelDefaultForJob(historyView);
historyView.setLineId(lineId);
historyView.setInstitutionId(institutionId);
historyView.setExecutionCycle(BaseUtils.getExecutionCycleForCalibration(date, dayNumber));
historyView.setCalibrationDate(DateUtil.beginOfDay(DateUtil.offsetDay(date, dayNumber + 1)));
historyViewList.add(historyView);
}
}
package pps.core.space.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
......@@ -10,6 +12,8 @@ import org.apache.commons.lang3.StringUtils;
import pps.cloud.base.service.IBasePowerLineCloudService;
import pps.cloud.base.service.data.base_power_line_wellhead.DynamicQueryBasePowerLineWellheadInput;
import pps.cloud.base.service.data.base_power_line_wellhead.DynamicQueryBasePowerLineWellheadViewOutput;
import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerInput;
import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerOutput;
import pps.core.common.constant.BusinessConstant;
import pps.core.common.entity.BaseModel;
import pps.core.common.session.PpsUserSession;
......@@ -17,6 +21,7 @@ import pps.core.common.utils.BaseUtils;
import pps.core.space.entity.*;
import pps.core.space.enums.BusinessError;
import pps.core.space.mapper.*;
import pps.core.space.service.data.SpaceOptimizeWellheadAndPlant;
import pps.core.space.service.data.space_institution_detail.*;
import pps.core.space.service.data.space_institution_duration.GetSpaceInstitutionDurationViewOutput;
import pps.core.space.service.data.space_institution_wellhead.CreateSpaceInstitutionWellheadInput;
......@@ -48,7 +53,7 @@ import java.util.stream.Collectors;
*/
@XService
@XText("基础间开配置模块")
public class SpaceInstitutionDetailService {
public class SpaceInstitutionDetailService extends SpaceOptimizeBaseService {
/**
* 基础间开配置--新增
......@@ -290,11 +295,11 @@ public class SpaceInstitutionDetailService {
String institutionId = input.getId();
return XTransactionHelper.begin(context, () -> {
SpaceInstitutionDetailMapper mapper = context.getBean(SpaceInstitutionDetailMapper.class);
SpaceInstitutionDetailEnt entity = this.getInstitutionDetail(mapper, institutionId);
if (Objects.isNull(entity)) {
SpaceInstitutionDetailEnt detail = this.getInstitutionDetail(mapper, institutionId);
if (Objects.isNull(detail)) {
return XServiceResult.error(context, XError.NotFound);
}
Integer isCurrentBasic = entity.getIsCurrentBasic();
Integer isCurrentBasic = detail.getIsCurrentBasic();
if (isCurrentBasic.equals(BusinessConstant.ZERO)) {
return XServiceResult.error(context, BusinessError.RepeatSetting);
}
......@@ -310,7 +315,8 @@ public class SpaceInstitutionDetailService {
.eq(BaseModel::getId, institutionId)
.set(SpaceInstitutionDetailEnt::getIsCurrentBasic, BusinessConstant.ZERO)
);
//todo: 初始化长期/中短期优化
//长期/中短期制度优化初始化
this.institutionOptimizeInitialize(context, detail);
return XServiceResult.OK;
});
}
......@@ -328,18 +334,211 @@ public class SpaceInstitutionDetailService {
public XServiceResult anewOptimizeInstitution(XContext context, UpdateSpaceInstitutionDetailInput input) {
PpsUserSession session = context.getSession(PpsUserSession.class);
String institutionId = input.getId();
return XTransactionHelper.begin(context, () -> {
SpaceInstitutionDetailMapper mapper = context.getBean(SpaceInstitutionDetailMapper.class);
SpaceInstitutionDetailEnt entity = this.getInstitutionDetail(mapper, institutionId);
if (Objects.isNull(entity)) {
SpaceInstitutionDetailEnt detail = this.getInstitutionDetail(mapper, institutionId);
if (Objects.isNull(detail)) {
return XServiceResult.error(context, XError.NotFound);
}
this.updateInstitutionDetail(context, session, mapper, institutionId, input, entity);
//todo: 如果前往校准修改制度,长期/中短期优化重新跑
return XTransactionHelper.begin(context, () -> {
this.updateInstitutionDetail(context, session, mapper, institutionId, input, detail);
//制度优化
this.institutionOptimizeInitialize(context, detail);
return XServiceResult.OK;
});
}
/**
* 制度优化
*
* @param context 上下文
* @param detail 细节
*/
private void institutionOptimizeInitialize(XContext context, SpaceInstitutionDetailEnt detail) {
String institutionId = detail.getId();
//取制度开始时间,判断是否可以执行
Date institutionStartDate = detail.getInstitutionStartDate();
DateTime currentTime = DateUtil.date();
if (currentTime.compareTo(institutionStartDate) >= 0) {
List<SpaceOptimizePeriodDTO> longPeriodDTOList = new ArrayList<>(32);
List<SpaceOptimizeWellheadDTO> longWellheadDTOList = new ArrayList<>(64);
List<SpaceOptimizeDurationDTO> longDurationDTOList = new ArrayList<>(128);
List<SpaceOptimizeDurationDTO> longUnOptimizeDurationList = new ArrayList<>(128);
List<SpaceOptimizePeriodDTO> midPeriodDTOList = new ArrayList<>(32);
List<SpaceOptimizeWellheadDTO> midWellheadDTOList = new ArrayList<>(64);
List<SpaceOptimizeDurationDTO> midDurationDTOList = new ArrayList<>(128);
List<SpaceOptimizeDurationDTO> midUnOptimizeDurationList = new ArrayList<>(128);
DateTime endOfMonth = DateUtil.endOfMonth(currentTime);
DateTime endOfWeek = DateUtil.endOfWeek(currentTime);
String lineId = detail.getLineId();
//取年份
int year = currentTime.year();
//月份要加一
int monthNum = currentTime.month() + 1;
String month;
if (monthNum < BusinessConstant.TEN) {
month = "0" + monthNum;
} else {
month = String.valueOf(monthNum);
}
SpaceOptimizeWellheadAndPlant wellheadAndPlant = super.getWellheadAndPlant(context, ListUtil.toList(detail));
//长期间开优化
List<DynamicQueryPlantPredictedPowerOutput> longAvgPowerList = super.getAveragePowerGenerationListByPlantIds(context,
DynamicQueryPlantPredictedPowerInput.builder()
.plantIds(wellheadAndPlant.getPlantIdsByLineIdMap().get(lineId))
.yearTime(String.valueOf(year))
.monthTime(month)
.build()
);
this.institutionalOptimization(context, longPeriodDTOList, longWellheadDTOList, longDurationDTOList, longUnOptimizeDurationList, wellheadAndPlant,
longAvgPowerList, detail, BaseUtils.getExecutionCycleForMonth(currentTime), endOfMonth, monthNum);
//中短期间开优化
List<DynamicQueryPlantPredictedPowerOutput> midAvgPowerList = super.getAveragePowerGenerationListByPlantIds(context,
DynamicQueryPlantPredictedPowerInput.builder()
.plantIds(wellheadAndPlant.getPlantIdsByLineIdMap().get(lineId))
.startTime(DateUtil.beginOfWeek(currentTime).toString(BusinessConstant.DATE_FORMAT_DAY))
.endTime(DateUtil.beginOfWeek(DateUtil.nextWeek()).toString(BusinessConstant.DATE_FORMAT_DAY))
.build()
);
this.institutionalOptimization(context, midPeriodDTOList, midWellheadDTOList, midDurationDTOList, midUnOptimizeDurationList, wellheadAndPlant,
midAvgPowerList, detail, BaseUtils.getExecutionCycleForWeek(currentTime), endOfWeek, monthNum);
//逻辑删除已创建的长期优化数据
SpaceOptimizeLongPeriodMapper longPeriodMapper = context.getBean(SpaceOptimizeLongPeriodMapper.class);
List<SpaceOptimizeLongPeriodEnt> longPeriodEntList = longPeriodMapper.selectList(new LambdaQueryWrapper<SpaceOptimizeLongPeriodEnt>()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceOptimizeLongPeriodEnt::getOptimizeState, BusinessConstant.ZERO)
.eq(SpaceOptimizeLongPeriodEnt::getInstitutionId, institutionId)
.eq(SpaceOptimizeLongPeriodEnt::getLineId, lineId)
.eq(SpaceOptimizeLongPeriodEnt::getOptimizeDeadline, endOfMonth)
);
if (CollUtil.isNotEmpty(longPeriodEntList)) {
List<String> longIds = longPeriodEntList.stream()
.map(BaseModel::getId)
.collect(Collectors.toList());
longPeriodMapper.update(null, new LambdaUpdateWrapper<SpaceOptimizeLongPeriodEnt>()
.set(BaseModel::getIsDeleted, BusinessConstant.ZERO)
.in(BaseModel::getId, longIds)
);
//删除关联数据
SpaceOptimizeLongWellheadMapper longWellheadMapper = context.getBean(SpaceOptimizeLongWellheadMapper.class);
longWellheadMapper.update(null, new LambdaUpdateWrapper<SpaceOptimizeLongWellheadEnt>()
.set(BaseModel::getIsDeleted, BusinessConstant.ZERO)
.in(SpaceOptimizeLongWellheadEnt::getLongPeriodId, longIds)
);
SpaceOptimizeLongDurationMapper longDurationMapper = context.getBean(SpaceOptimizeLongDurationMapper.class);
longDurationMapper.update(null, new LambdaUpdateWrapper<SpaceOptimizeLongDurationEnt>()
.set(BaseModel::getIsDeleted, BusinessConstant.ZERO)
.in(SpaceOptimizeLongDurationEnt::getLongPeriodId, longIds)
);
}
//逻辑删除已创建的中短期优化数据
SpaceOptimizeMidPeriodMapper midPeriodMapper = context.getBean(SpaceOptimizeMidPeriodMapper.class);
List<SpaceOptimizeMidPeriodEnt> midPeriodEntList = midPeriodMapper.selectList(new LambdaQueryWrapper<SpaceOptimizeMidPeriodEnt>()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceOptimizeMidPeriodEnt::getOptimizeState, BusinessConstant.ZERO)
.eq(SpaceOptimizeMidPeriodEnt::getInstitutionId, institutionId)
.eq(SpaceOptimizeMidPeriodEnt::getLineId, lineId)
.eq(SpaceOptimizeMidPeriodEnt::getOptimizeDeadline, endOfWeek)
);
if (CollUtil.isNotEmpty(midPeriodEntList)) {
List<String> midIds = midPeriodEntList.stream()
.map(BaseModel::getId)
.collect(Collectors.toList());
midPeriodMapper.update(null, new LambdaUpdateWrapper<SpaceOptimizeMidPeriodEnt>()
.set(BaseModel::getIsDeleted, BusinessConstant.ZERO)
.in(BaseModel::getId, midIds)
);
//删除关联数据
SpaceOptimizeMidWellheadMapper longWellheadMapper = context.getBean(SpaceOptimizeMidWellheadMapper.class);
longWellheadMapper.update(null, new LambdaUpdateWrapper<SpaceOptimizeMidWellheadEnt>()
.set(BaseModel::getIsDeleted, BusinessConstant.ZERO)
.in(SpaceOptimizeMidWellheadEnt::getMidPeriodId, midIds)
);
SpaceOptimizeMidDurationMapper longDurationMapper = context.getBean(SpaceOptimizeMidDurationMapper.class);
longDurationMapper.update(null, new LambdaUpdateWrapper<SpaceOptimizeMidDurationEnt>()
.set(BaseModel::getIsDeleted, BusinessConstant.ZERO)
.in(SpaceOptimizeMidDurationEnt::getMidPeriodId, midIds)
);
}
//创建长期优化数据
int size;
SpaceOptimizeViewMapper optimizeViewMapper = context.getBean(SpaceOptimizeViewMapper.class);
if (CollUtil.isNotEmpty(longPeriodDTOList)) {
size = longPeriodDTOList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizePeriodDTO>> subList = BaseUtils.getSubList(longPeriodDTOList);
subList.forEach(b -> optimizeViewMapper.longPeriodBatchInsertList(b));
} else {
optimizeViewMapper.longPeriodBatchInsertList(longPeriodDTOList);
}
}
if (CollUtil.isNotEmpty(longWellheadDTOList)) {
size = longWellheadDTOList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeWellheadDTO>> subList = BaseUtils.getSubList(longWellheadDTOList);
subList.forEach(b -> optimizeViewMapper.longWellheadBatchInsertList(b));
} else {
optimizeViewMapper.longWellheadBatchInsertList(longWellheadDTOList);
}
}
if (CollUtil.isNotEmpty(longDurationDTOList)) {
size = longDurationDTOList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeDurationDTO>> subList = BaseUtils.getSubList(longDurationDTOList);
subList.forEach(b -> optimizeViewMapper.longDurationBatchInsertList(b));
} else {
optimizeViewMapper.longDurationBatchInsertList(longDurationDTOList);
}
}
if (CollUtil.isNotEmpty(longUnOptimizeDurationList)) {
size = longUnOptimizeDurationList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeDurationDTO>> subList = BaseUtils.getSubList(longUnOptimizeDurationList);
subList.forEach(b -> optimizeViewMapper.longDurationBatchInsertList(b));
} else {
optimizeViewMapper.longDurationBatchInsertList(longUnOptimizeDurationList);
}
}
//创建中短期优化数据
if (CollUtil.isNotEmpty(midPeriodDTOList)) {
size = midPeriodDTOList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizePeriodDTO>> subList = BaseUtils.getSubList(midPeriodDTOList);
subList.forEach(b -> optimizeViewMapper.midPeriodBatchInsertList(b));
} else {
optimizeViewMapper.midPeriodBatchInsertList(midPeriodDTOList);
}
}
if (CollUtil.isNotEmpty(midWellheadDTOList)) {
size = midWellheadDTOList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeWellheadDTO>> subList = BaseUtils.getSubList(midWellheadDTOList);
subList.forEach(b -> optimizeViewMapper.midWellheadBatchInsertList(b));
} else {
optimizeViewMapper.midWellheadBatchInsertList(midWellheadDTOList);
}
}
if (CollUtil.isNotEmpty(midDurationDTOList)) {
size = midDurationDTOList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeDurationDTO>> subList = BaseUtils.getSubList(midDurationDTOList);
subList.forEach(b -> optimizeViewMapper.midDurationBatchInsertList(b));
} else {
optimizeViewMapper.midDurationBatchInsertList(midDurationDTOList);
}
}
if (CollUtil.isNotEmpty(midUnOptimizeDurationList)) {
size = midUnOptimizeDurationList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeDurationDTO>> subList = BaseUtils.getSubList(midUnOptimizeDurationList);
subList.forEach(b -> optimizeViewMapper.midDurationBatchInsertList(b));
} else {
optimizeViewMapper.midDurationBatchInsertList(midUnOptimizeDurationList);
}
}
}
}
/**
* 间开优化历史--分页列表
*
......@@ -465,4 +664,43 @@ public class SpaceInstitutionDetailService {
BaseUtils.setBaseModelDefault(entity, session);
mapper.updateById(entity);
}
/**
* 制度优化
*
* @param context 上下文
* @param periodDTOList 时期数据主义者
* @param wellheadDTOList 井口dtolist
* @param durationDTOList 持续时间dtolist
* @param unOptimizeDurationList 取消优化工期列表
* @param avgPowerList 平均功率列表
* @param detail 细节
* @param executionCycle 执行周期
* @param optimizeDeadline 优化截止日期
* @param monthNum 月份
*/
private void institutionalOptimization(XContext context, List<SpaceOptimizePeriodDTO> periodDTOList, List<SpaceOptimizeWellheadDTO> wellheadDTOList,
List<SpaceOptimizeDurationDTO> durationDTOList, List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
SpaceOptimizeWellheadAndPlant wellheadAndPlant, List<DynamicQueryPlantPredictedPowerOutput> avgPowerList, SpaceInstitutionDetailEnt detail,
String executionCycle, Date optimizeDeadline, int monthNum) {
String detailId = detail.getId();
String lineId = detail.getLineId();
List<SpaceInstitutionWellheadView> spaceWellheadList = wellheadAndPlant.getSpaceWellheadList();
SpaceInstitutionDurationMapper durationMapper = context.getBean(SpaceInstitutionDurationMapper.class);
//创建记录
String periodId = super.createOptimizePeriod(periodDTOList, detailId, lineId, executionCycle, optimizeDeadline);
switch (detail.getGridTypeKey()) {
//并网型优化
case "1":
super.gridConnectedOptimization(context, durationMapper, wellheadDTOList, durationDTOList, unOptimizeDurationList,
spaceWellheadList, avgPowerList, detail, monthNum, detailId, periodId, lineId);
break;
//离网型优化
case "0":
break;
default:
//电网类型不存在
}
}
}
package pps.core.space.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import pps.cloud.base.service.IBasePowerLineCloudService;
import pps.cloud.base.service.IBaseWellheadCloudService;
import pps.cloud.base.service.data.base_power_line_plant.DynamicQueryBasePowerLinePlantInput;
import pps.cloud.base.service.data.base_power_line_plant.DynamicQueryBasePowerLinePlantOutput;
import pps.cloud.base.service.data.base_price_strategy_detail.GetBasePriceStrategyDetailInput;
import pps.cloud.base.service.data.base_price_strategy_detail.GetBasePriceStrategyDetailOutput;
import pps.cloud.base.service.data.base_wellhead.DynamicQueryBaseWellheadInput;
import pps.cloud.base.service.data.base_wellhead.DynamicQueryBaseWellheadOutput;
import pps.cloud.prediction.service.IPlantPredictedPowerCloudService;
import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerInput;
import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerOutput;
import pps.core.common.constant.BusinessConstant;
import pps.core.common.entity.BaseModel;
import pps.core.common.utils.BaseUtils;
import pps.core.space.entity.*;
import pps.core.space.enums.BusinessError;
import pps.core.space.mapper.SpaceInstitutionDetailMapper;
import pps.core.space.mapper.SpaceInstitutionDurationMapper;
import pps.core.space.mapper.SpaceInstitutionWellheadViewMapper;
import pps.core.space.service.data.SpaceOptimizeWellheadAndPlant;
import pps.core.space.utils.ServiceUtil;
import xstartup.base.XContext;
import xstartup.base.exception.XServiceException;
import xstartup.data.XListResult;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* 间开优化公用方法
*
* @author ZWT
* @date 2023/09/18 16:02
*/
public class SpaceOptimizeBaseService {
/**
* 获得生效中的基础间开
*
* @param context 上下文
* @param sameDay 同一天
* @return {@link List}<{@link SpaceInstitutionDetailEnt}>
*/
public List<SpaceInstitutionDetailEnt> getEffectiveSpaceInstitution(XContext context, String sameDay) {
//取生效中的基础间开
SpaceInstitutionDetailMapper detailMapper = context.getBean(SpaceInstitutionDetailMapper.class);
List<SpaceInstitutionDetailEnt> detailEntList = detailMapper.selectList(new LambdaQueryWrapper<SpaceInstitutionDetailEnt>()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceInstitutionDetailEnt::getIsCurrentBasic, BusinessConstant.ZERO)
.le(SpaceInstitutionDetailEnt::getInstitutionStartDate, sameDay)
.ge(SpaceInstitutionDetailEnt::getInstitutionEndDate, sameDay)
);
if (CollUtil.isEmpty(detailEntList)) {
//未发现可优化基础间开制度
throw new XServiceException(BusinessError.DidNotFindSpace);
}
return detailEntList;
}
/**
* 获取所有生效中制度关联的井口及光伏电站
*
* @param context 上下文
* @param detailEntList 详细ent列表
* @return {@link SpaceOptimizeWellheadAndPlant}
*/
public SpaceOptimizeWellheadAndPlant getWellheadAndPlant(XContext context, List<SpaceInstitutionDetailEnt> detailEntList) {
Set<String> lineIds = new HashSet<>(32);
Set<String> institutionIds = new HashSet<>(32);
for (SpaceInstitutionDetailEnt spaceInstitutionDetailEnt : detailEntList) {
lineIds.add(spaceInstitutionDetailEnt.getLineId());
institutionIds.add(spaceInstitutionDetailEnt.getId());
}
//取生效中间开的所有井口
SpaceInstitutionWellheadViewMapper wellheadMapper = context.getBean(SpaceInstitutionWellheadViewMapper.class);
List<SpaceInstitutionWellheadView> spaceWellheadList = wellheadMapper.selectListByInstitutionIds(institutionIds);
if (CollUtil.isEmpty(spaceWellheadList)) {
//未发现可优化井口
throw new XServiceException(BusinessError.DidNotFindWellhead);
}
this.setServiceRatingForSpaceWellheadList(context, spaceWellheadList);
//取线路关联的所有光伏电站ID
List<DynamicQueryBasePowerLinePlantOutput> plantList = this.getPowerLinePlantListByLineIds(context, lineIds);
if (CollUtil.isEmpty(plantList)) {
//未发现可用光伏电站
throw new XServiceException(BusinessError.DidNotFindPlant);
}
return SpaceOptimizeWellheadAndPlant.builder()
.spaceWellheadList(spaceWellheadList)
.plantIdsByLineIdMap(
plantList.stream()
.collect(
Collectors.groupingBy(DynamicQueryBasePowerLinePlantOutput::getLineId,
Collectors.mapping(DynamicQueryBasePowerLinePlantOutput::getPlantId, Collectors.toList()))
)
)
.build();
}
/**
* 条件获取获取光伏预测各时段平均值列表
*
* @param context 上下文
* @param input 输入
* @return {@link List}<{@link DynamicQueryPlantPredictedPowerOutput}>
*/
public List<DynamicQueryPlantPredictedPowerOutput> getAveragePowerGenerationListByPlantIds(XContext context, DynamicQueryPlantPredictedPowerInput input) {
IPlantPredictedPowerCloudService cloudService = context.getBean(IPlantPredictedPowerCloudService.class);
XListResult<DynamicQueryPlantPredictedPowerOutput> result = cloudService.queryAveragePowerGenerationListByParam(context, input);
result.throwIfFail();
return result.getResult();
}
/**
* 获得最大功率
*
* @param avgPowerList 平均功率列表
* @return {@link BigDecimal}
*/
public BigDecimal getPowerMax(List<DynamicQueryPlantPredictedPowerOutput> avgPowerList) {
return avgPowerList.stream()
.map(DynamicQueryPlantPredictedPowerOutput::getPower)
.max(BigDecimal::compareTo)
.orElse(BigDecimal.ZERO);
}
/**
* 获取井口总功率
*
* @param spaceWellheadList 空间井口清单
* @param detailId 详细信息id
* @return {@link BigDecimal}
*/
public BigDecimal getWellheadTotalPower(List<SpaceInstitutionWellheadView> spaceWellheadList, String detailId) {
return spaceWellheadList.stream()
.filter(w -> StringUtils.equals(detailId, w.getInstitutionId()))
.map(SpaceInstitutionWellheadView::getServiceRating)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
* 获取井口视图列表
*
* @param spaceWellheadList 空间井口清单
* @param detailId 详细信息id
* @return {@link List}<{@link SpaceInstitutionWellheadView}>
*/
public List<SpaceInstitutionWellheadView> getWellheadViewList(List<SpaceInstitutionWellheadView> spaceWellheadList, String detailId) {
return spaceWellheadList.stream()
.filter(w -> StringUtils.equals(detailId, w.getInstitutionId()) &&
StringUtils.equals("INTERVAL", w.getRunTypeKey()) &&
StringUtils.equals("0", w.getIntervalTypeKey()))
.sorted(Comparator.comparing(SpaceInstitutionWellheadView::getStartSeq))
.collect(Collectors.toList());
}
/**
* 获取井口间开时间段
*
* @param durationMapper 持续时间映射器
* @param detailId 详细信息id
* @return {@link Map}<{@link String}, {@link List}<{@link SpaceInstitutionDurationEnt}>>
*/
public Map<String, List<SpaceInstitutionDurationEnt>> getDurationMap(SpaceInstitutionDurationMapper durationMapper, String detailId) {
//通过间开ID和井口ID查所有井口时段配置
List<SpaceInstitutionDurationEnt> durationList = durationMapper.selectList(new LambdaQueryWrapper<SpaceInstitutionDurationEnt>()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceInstitutionDurationEnt::getInstitutionId, detailId)
.orderByAsc(SpaceInstitutionDurationEnt::getOpenWellTime)
);
if (CollUtil.isEmpty(durationList)) {
//没有设置时间段,无法优化
return null;
}
return durationList.stream()
.collect(
Collectors.groupingBy(SpaceInstitutionDurationEnt::getWellheadId)
);
}
/**
* 获取井口Map通过最大功率区分
*
* @param wellheadViewList 井口视图列表
* @param powerMax 最大功率
* @return {@link Map}<{@link Boolean}, {@link List}<{@link SpaceInstitutionWellheadView}>>
*/
public Map<Boolean, List<SpaceInstitutionWellheadView>> getWellheadViewMapByPower(List<SpaceInstitutionWellheadView> wellheadViewList, BigDecimal powerMax) {
return wellheadViewList.stream()
.collect(
Collectors.partitioningBy(w -> powerMax.compareTo(w.getServiceRating()) >= BusinessConstant.ZERO)
);
}
/*-----------------------------------private-----------------------------------*/
/**
* 按线路ID集合获取电站列表
*
* @param context 上下文
* @param lineIds 线路ID
* @return {@link List}<{@link DynamicQueryBasePowerLinePlantOutput}>
*/
private List<DynamicQueryBasePowerLinePlantOutput> getPowerLinePlantListByLineIds(XContext context, Set<String> lineIds) {
IBasePowerLineCloudService cloudService = context.getBean(IBasePowerLineCloudService.class);
XListResult<DynamicQueryBasePowerLinePlantOutput> result = cloudService.queryPowerLinePlantListByParam(context,
DynamicQueryBasePowerLinePlantInput.builder()
.lineIds(lineIds)
.build()
);
result.throwIfFail();
return result.getResult();
}
/**
* 为间开井口列表设置发电功率
*
* @param context 上下文
* @param spaceWellheadList 空间井口清单
*/
private void setServiceRatingForSpaceWellheadList(XContext context, List<SpaceInstitutionWellheadView> spaceWellheadList) {
IBaseWellheadCloudService cloudService = context.getBean(IBaseWellheadCloudService.class);
XListResult<DynamicQueryBaseWellheadOutput> result = cloudService.queryBaseWellheadListByParam(context,
DynamicQueryBaseWellheadInput.builder()
.wellheadIds(spaceWellheadList.stream()
.map(SpaceInstitutionWellheadView::getWellheadId)
.collect(Collectors.toList())
)
.build());
result.throwIfFail();
List<DynamicQueryBaseWellheadOutput> wellheadOutputList = result.getResult();
if (CollUtil.isEmpty(wellheadOutputList)) {
return;
}
spaceWellheadList.forEach(s -> {
s.setServiceRating(
wellheadOutputList.stream()
.filter(w -> StringUtils.equals(s.getWellheadId(), w.getId()))
.findAny()
.map(DynamicQueryBaseWellheadOutput::getServiceRating)
.orElse(BigDecimal.ZERO)
);
});
}
/**
* 创建间开优化信息
*
* @param periodDTOList 时期数据主义者
* @param detailId 详细信息id
* @param lineId 线路id
* @param executionCycleForMonth 月执行周期
* @param optimizeDeadline 优化截止日期
* @return {@link String}
*/
public String createOptimizePeriod(List<SpaceOptimizePeriodDTO> periodDTOList, String detailId,
String lineId, String executionCycleForMonth, Date optimizeDeadline) {
SpaceOptimizePeriodDTO periodDTO = new SpaceOptimizePeriodDTO();
BaseUtils.setBaseModelDefaultForJob(periodDTO);
periodDTO.setInstitutionId(detailId);
periodDTO.setLineId(lineId);
periodDTO.setExecutionCycle(executionCycleForMonth);
periodDTO.setOptimizeState(BusinessConstant.ZERO);
periodDTO.setOptimizeDeadline(optimizeDeadline);
periodDTOList.add(periodDTO);
return periodDTO.getId();
}
/**
* 创建间开优化井口信息
*
* @param wellheadDTOList 井口dtolist
* @param periodId 期间id
* @param wellheadId 井口id
* @param wellNumber 井号
* @return {@link String}
*/
public String createOptimizeWellhead(List<SpaceOptimizeWellheadDTO> wellheadDTOList, String periodId,
String wellheadId, String wellNumber) {
SpaceOptimizeWellheadDTO wellheadDTO = new SpaceOptimizeWellheadDTO();
BaseUtils.setBaseModelDefaultForJob(wellheadDTO);
wellheadDTO.setPeriodId(periodId);
wellheadDTO.setWellheadId(wellheadId);
wellheadDTO.setWellNumber(wellNumber);
wellheadDTOList.add(wellheadDTO);
return wellheadDTO.getId();
}
/**
* 创建间开优化井口区间配置信息
*
* @param durationDTOList 持续时间dtolist
* @param periodId 期间id
* @param recordId 记录id
* @param wellheadId 井口id
* @param generationTypeKey 生成类型密钥
* @param openWellTime 开井时间
* @param endTimeString 结束时间字符串
*/
public void createOptimizeDuration(List<SpaceOptimizeDurationDTO> durationDTOList, String periodId,
String recordId, String wellheadId, String generationTypeKey,
String openWellTime, String endTimeString) {
SpaceOptimizeDurationDTO durationDTO = new SpaceOptimizeDurationDTO();
BaseUtils.setBaseModelDefaultForJob(durationDTO);
durationDTO.setRecordId(recordId);
durationDTO.setPeriodId(periodId);
durationDTO.setWellheadId(wellheadId);
durationDTO.setGenerationTypeKey(generationTypeKey);
durationDTO.setIsOptimize(BusinessConstant.ZERO);
durationDTO.setOpenWellTime(openWellTime);
durationDTO.setCloseWellTime(endTimeString);
durationDTOList.add(durationDTO);
}
/**
* 创建间开原始间开区间
*
* @param unOptimizeDurationList 取消优化工期列表
* @param durationEnt 持续时间ent
* @param periodId 期间id
* @param recordId 记录id
* @param wellheadId 井口id
*/
public void createUnOptimizeDuration(List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
SpaceInstitutionDurationEnt durationEnt,
String periodId, String recordId, String wellheadId) {
SpaceOptimizeDurationDTO durationDTO = new SpaceOptimizeDurationDTO();
BaseUtils.setBaseModelDefaultForJob(durationDTO);
durationDTO.setRecordId(recordId);
durationDTO.setPeriodId(periodId);
durationDTO.setWellheadId(wellheadId);
durationDTO.setIsOptimize(BusinessConstant.ONE);
durationDTO.setOpenWellTime(durationEnt.getOpenWellTime());
durationDTO.setCloseWellTime(durationEnt.getCloseWellTime());
unOptimizeDurationList.add(durationDTO);
}
/**
* 绿电消纳策略
*
* @param wellheadDTOList 井口dtolist
* @param unOptimizeDurationList 取消优化工期列表
* @param durationDTOList 持续时间dtolist
* @param wellheadViewList 井口视图列表
* @param avgPowerList 平均功率列表
* @param durationMap 持续时间图
* @param detail 细节
* @param periodId 期间id
*/
public void greenElectricityConsumptionStrategy(List<SpaceOptimizeWellheadDTO> wellheadDTOList, List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
List<SpaceOptimizeDurationDTO> durationDTOList, List<SpaceInstitutionWellheadView> wellheadViewList,
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList, Map<String, List<SpaceInstitutionDurationEnt>> durationMap,
SpaceInstitutionDetailEnt detail, String periodId) {
//时间差
int between = 0;
//启动间隔累积
int startInterval = 0;
//判断是否第一口井
boolean isFirstWellhead;
//第一口井启动时间
DateTime firstStartTime = null;
//井口累积运行总功率
BigDecimal totalOperatingPower = BigDecimal.ZERO;
for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) {
SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w);
String wellheadId = wellhead.getWellheadId();
String recordId = this.createOptimizeWellhead(wellheadDTOList, periodId, wellheadId, wellhead.getWellNumber());
//取当前井口最大发电量
BigDecimal serviceRating = wellhead.getServiceRating();
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellhead);
if (CollUtil.isEmpty(durationConfigList)) {
//没有设置时间段,无法优化
continue;
}
//保存原始记录
for (SpaceInstitutionDurationEnt durationEnt : durationConfigList) {
this.createUnOptimizeDuration(unOptimizeDurationList, durationEnt, periodId, recordId, wellheadId);
}
//累加
totalOperatingPower = totalOperatingPower.add(serviceRating);
if (w == 0) {
//第一个井口
isFirstWellhead = true;
} else {
startInterval = startInterval + detail.getStartInterval();
isFirstWellhead = false;
}
for (int d = 0, durationSize = durationConfigList.size(); d < durationSize; d++) {
SpaceInstitutionDurationEnt duration = durationConfigList.get(d);
String openWellTime = duration.getOpenWellTime();
DateTime startTime = DateUtil.parse(openWellTime + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
DateTime endTime = DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
//第一次启动
if (d == 0) {
//第一口井的启动时间
if (isFirstWellhead) {
firstStartTime = startTime;
//计算开井时间
int startIndex = 0;
for (int a = 0, avgPowerSize = avgPowerList.size(); a < avgPowerSize; a++) {
DynamicQueryPlantPredictedPowerOutput predictedPower = avgPowerList.get(a);
//当日时间段平均光伏出力>=第一口井运行负荷时,该时间为第一口井运行时间
if (predictedPower.getPower().compareTo(serviceRating) >= BusinessConstant.ZERO) {
startIndex = a;
break;
}
}
DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(startIndex);
String startTimeString = start.getHourTime() + start.getMinTime();
//计算第一次关井时间,按照间开时间段顺延
int startDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
DateTime endTimeOptimize = startTime.offset(DateField.MINUTE, startDuration);
this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null,
startTimeString, endTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT)
);
//计算时间偏移
DateTime startTimeOptimize = DateUtil.parse(startTimeString, BusinessConstant.TIME_FORMAT);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(startTimeOptimize, startTime);
}
//其它井口的第一次启动时间
else {
DateTime startTimeOffset = firstStartTime.offset(DateField.MINUTE, startInterval);
int startIndex = -1;
for (int a = 0, avgPowerSize = avgPowerList.size(); a < avgPowerSize; a++) {
DynamicQueryPlantPredictedPowerOutput predictedPower = avgPowerList.get(a);
if (DateUtil.parse(predictedPower.getHourTime() + predictedPower.getMinTime(), BusinessConstant.TIME_FORMAT)
.compareTo(startTimeOffset) >= 0) {
//判断第一口井启动时间+启动间隔时日平均光伏出力-前两口井的运行功率是否为正数
if (predictedPower.getPower().compareTo(totalOperatingPower) >= 0) {
//确定第二口井第一次开井时间为第一口井启动时间+启动间隔
startIndex = a;
break;
}
}
}
if (startIndex > -1) {
DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(startIndex);
DateTime startTimeOptimize = DateUtil.parse(start.getHourTime() + start.getMinTime(), BusinessConstant.TIME_FORMAT);
//计算未优化启动间隔
int openDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
DateTime endTimeOptimize = startTimeOptimize.offset(DateField.MINUTE, openDuration);
this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null,
openWellTime, BaseUtils.getEndTimeString(endTimeOptimize)
);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(endTimeOptimize, endTime);
} else {
//无法优化
}
}
} else {
DateTime offset = startTime.offset(DateField.MINUTE, between);
if (offset.compareTo(BusinessConstant.DATE_FLAG) > 0) {
//如果时间超过当天,舍弃
continue;
}
//计算偏移
this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null,
offset.toString(BusinessConstant.MINUTES_FORMAT),
BaseUtils.getEndTimeString(DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT)
.offset(DateField.MINUTE, between))
);
}
}
}
}
/**
* 消峰平谷策略
*
* @param context 上下文
* @param wellheadDTOList 井口dtolist
* @param unOptimizeDurationList 取消优化工期列表
* @param durationDTOList 持续时间dtolist
* @param wellheadViewList 井口视图列表
* @param durationMap 持续时间图
* @param detail 细节
* @param lineId 线路id
* @param monthNum 月份
* @param midPeriodId 中期id
*/
public void peakEliminationAndValleyLevelingStrategy(XContext context, List<SpaceOptimizeWellheadDTO> wellheadDTOList, List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
List<SpaceOptimizeDurationDTO> durationDTOList, List<SpaceInstitutionWellheadView> wellheadViewList,
Map<String, List<SpaceInstitutionDurationEnt>> durationMap, SpaceInstitutionDetailEnt detail,
String lineId, int monthNum, String midPeriodId) {
//通过线路ID和月份获取市电峰谷策略明细配置
List<GetBasePriceStrategyDetailOutput> strategyDetailList = ServiceUtil.getStrategyDetailList(context,
GetBasePriceStrategyDetailInput.builder()
.lineId(lineId)
.strategyMonth(String.valueOf(monthNum))
.build()
);
if (CollUtil.isEmpty(strategyDetailList)) {
//没有配置,不优化
return;
}
//获取第一段谷电阶段的开始时间为第一口井的开井时间
Optional<GetBasePriceStrategyDetailOutput> low = strategyDetailList.stream()
.filter(s -> !StringUtils.isAnyBlank(s.getEndTime(), s.getStartTime()) && StringUtils.equals("LOW", s.getPeriodTypeKey()))
.findFirst();
if (!low.isPresent()) {
//没有谷电,不优化
return;
}
GetBasePriceStrategyDetailOutput strategyDetailOutput = low.get();
//第一口井启动时间
DateTime firstStartTime = DateUtil.parse(strategyDetailOutput.getStartTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
DateTime firstEndTime = DateUtil.parse(strategyDetailOutput.getEndTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
//判断是否第一口井
boolean isFirstWellhead;
//时间差
int between = 0;
//启动间隔累积
int startInterval = 0;
for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) {
SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w);
String wellheadId = wellhead.getWellheadId();
String recordId = this.createOptimizeWellhead(wellheadDTOList, midPeriodId, wellheadId, wellhead.getWellNumber());
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellhead);
if (CollUtil.isEmpty(durationConfigList)) {
//没有设置时间段,无法优化
continue;
}
//保存原始记录
for (SpaceInstitutionDurationEnt durationEnt : durationConfigList) {
this.createUnOptimizeDuration(unOptimizeDurationList, durationEnt, midPeriodId, recordId, wellheadId);
}
if (w == 0) {
//第一个井口
isFirstWellhead = true;
} else {
//计算启动间隔
startInterval = startInterval + detail.getStartInterval();
isFirstWellhead = false;
}
for (int d = 0, durationSize = durationConfigList.size(); d < durationSize; d++) {
SpaceInstitutionDurationEnt duration = durationConfigList.get(d);
String openWellTime = duration.getOpenWellTime();
DateTime startTime = DateUtil.parse(openWellTime + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
DateTime endTime = DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
//第一次启动
if (d == 0) {
//第一口井的启动时间
if (isFirstWellhead) {
//计算优化后的时间差优化后的第一口井开井时间-优化前第一次开井时间
int startDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
//第一次关井时间按照启动时长顺延
DateTime endTimeOptimize = startTime.offset(DateField.MINUTE, startDuration);
this.createOptimizeDuration(durationDTOList, midPeriodId, recordId, wellheadId, null,
strategyDetailOutput.getStartTime(), endTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT)
);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(firstEndTime, endTime);
}//其它井口的第一次启动时间
else {
//其它井启动时间:第一口井启动时间+启动间隔
DateTime startTimeOffset = firstStartTime.offset(DateField.MINUTE, startInterval);
DateTime endTimeOffset = firstEndTime.offset(DateField.MINUTE, startInterval);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(firstEndTime, endTime);
this.createOptimizeDuration(durationDTOList, midPeriodId, recordId, wellheadId, null,
startTimeOffset.toString(BusinessConstant.MINUTES_FORMAT), endTimeOffset.toString(BusinessConstant.MINUTES_FORMAT)
);
}
} else {
//计算偏移
DateTime offset = startTime.offset(DateField.MINUTE, between);
if (offset.compareTo(BusinessConstant.DATE_FLAG) > 0) {
//如果时间超过当天,舍弃
continue;
}
this.createOptimizeDuration(durationDTOList, midPeriodId, recordId, wellheadId, null,
offset.toString(BusinessConstant.MINUTES_FORMAT), BaseUtils.getEndTimeString(
DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT)
.offset(DateField.MINUTE, between)
)
);
}
}
}
}
/**
* 并网优化
*
* @param context 上下文
* @param durationMapper 持续时间映射器
* @param wellheadDTOList 井口dtolist
* @param durationDTOList 持续时间dtolist
* @param unOptimizeDurationList 取消优化工期列表
* @param spaceWellheadList 空间井口清单
* @param avgPowerList 平均功率列表
* @param detail 细节
* @param monthNum 月份
* @param detailId 详细信息id
* @param periodId 期间id
* @param lineId 线路id
*/
public void gridConnectedOptimization(XContext context, SpaceInstitutionDurationMapper durationMapper, List<SpaceOptimizeWellheadDTO> wellheadDTOList,
List<SpaceOptimizeDurationDTO> durationDTOList, List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
List<SpaceInstitutionWellheadView> spaceWellheadList, List<DynamicQueryPlantPredictedPowerOutput> avgPowerList,
SpaceInstitutionDetailEnt detail, int monthNum, String detailId, String periodId, String lineId) {
//取光伏出力峰值
BigDecimal powerMax = this.getPowerMax(avgPowerList);
//取当前制度下井口的总功率
BigDecimal wellheadTotalPower = this.getWellheadTotalPower(spaceWellheadList, detailId);
//根据类型过滤井口:大间开,连抽井不优化
List<SpaceInstitutionWellheadView> wellheadViewList = this.getWellheadViewList(spaceWellheadList, detailId);
if (CollUtil.isEmpty(wellheadViewList)) {
return;
}
Map<String, List<SpaceInstitutionDurationEnt>> durationMap = this.getDurationMap(durationMapper, detailId);
if (CollUtil.isEmpty(durationMap)) {
//没有设置时间段,无法优化
return;
}
//光伏出力峰值大于等于井口总功率:绿电消纳优先策略
if (powerMax.compareTo(wellheadTotalPower) >= BusinessConstant.ZERO) {
//---------------------------------绿电消纳策略---------------------------------
this.greenElectricityConsumptionStrategy(wellheadDTOList, unOptimizeDurationList, durationDTOList,
wellheadViewList, avgPowerList, durationMap, detail, periodId);
} else {
//遍历井口,按发电功率大于等于光伏出力峰值条件分组
Map<Boolean, List<SpaceInstitutionWellheadView>> collect = this.getWellheadViewMapByPower(wellheadViewList, powerMax);
List<SpaceInstitutionWellheadView> lowWellheadList = collect.get(false);
int size = spaceWellheadList.size();
int lowWellheadListSize = lowWellheadList.size();
//光伏出力峰值<任何一口井的运行功率:消峰平谷策略
if (size == lowWellheadListSize) {
//---------------------------------消峰平谷策略---------------------------------
this.peakEliminationAndValleyLevelingStrategy(context, wellheadDTOList, unOptimizeDurationList, durationDTOList, wellheadViewList,
durationMap, detail, lineId, monthNum, periodId);
}
//光伏出力峰值>=线路哪部分井口运行功率:满足的部分井口采用绿电消纳优先,不满足的井采用消峰平谷
else {
List<SpaceInstitutionWellheadView> highWellheadList = collect.get(true);
this.greenElectricityConsumptionStrategy(wellheadDTOList, unOptimizeDurationList, durationDTOList,
highWellheadList, avgPowerList, durationMap, detail, periodId);
this.peakEliminationAndValleyLevelingStrategy(context, wellheadDTOList, unOptimizeDurationList, durationDTOList,
lowWellheadList, durationMap, detail, lineId, monthNum, periodId);
}
}
}
}
\ No newline at end of file
......@@ -5,36 +5,25 @@ import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import pps.cloud.base.service.IBasePowerLineCloudService;
import pps.cloud.base.service.IBaseWellheadCloudService;
import pps.cloud.base.service.data.base_power_line_plant.DynamicQueryBasePowerLinePlantInput;
import pps.cloud.base.service.data.base_power_line_plant.DynamicQueryBasePowerLinePlantOutput;
import pps.cloud.base.service.data.base_price_strategy_detail.GetBasePriceStrategyDetailInput;
import pps.cloud.base.service.data.base_price_strategy_detail.GetBasePriceStrategyDetailOutput;
import pps.cloud.base.service.data.base_wellhead.DynamicQueryBaseWellheadInput;
import pps.cloud.base.service.data.base_wellhead.DynamicQueryBaseWellheadOutput;
import pps.cloud.prediction.service.IPlantPredictedPowerCloudService;
import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerInput;
import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerOutput;
import pps.cloud.space.service.ISpaceOptimizeLongCloudService;
import pps.core.common.constant.BusinessConstant;
import pps.core.common.entity.BaseModel;
import pps.core.common.utils.BaseUtils;
import pps.core.space.entity.*;
import pps.core.space.enums.BusinessError;
import pps.core.space.mapper.*;
import pps.core.space.utils.ServiceUtil;
import pps.core.space.mapper.SpaceInstitutionDurationMapper;
import pps.core.space.mapper.SpaceOptimizeViewMapper;
import pps.core.space.service.data.SpaceOptimizeWellheadAndPlant;
import xstartup.annotation.XService;
import xstartup.base.XContext;
import xstartup.data.XListResult;
import xstartup.data.XServiceResult;
import xstartup.helper.XTransactionHelper;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 长期间开优化Cloud模块
......@@ -43,7 +32,7 @@ import java.util.stream.Collectors;
* @date 2023/09/13 14:14
*/
@XService
public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongCloudService {
public class SpaceOptimizeLongCloudServiceImpl extends SpaceOptimizeBaseService implements ISpaceOptimizeLongCloudService {
/**
* 长期间开优化Cloud模块--定时任务
......@@ -53,39 +42,14 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
*/
@Override
public XServiceResult optimizeLongJob(XContext context) {
//取生效中的基础间开
SpaceInstitutionDetailMapper detailMapper = context.getBean(SpaceInstitutionDetailMapper.class);
List<SpaceInstitutionDetailEnt> detailEntList = detailMapper.selectList(new LambdaQueryWrapper<SpaceInstitutionDetailEnt>()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceInstitutionDetailEnt::getIsCurrentBasic, BusinessConstant.ZERO)
.apply(" institution_end_date >= CURDATE() ")
);
if (CollUtil.isEmpty(detailEntList)) {
//未发现可优化基础间开制度
return XServiceResult.error(context, BusinessError.DidNotFindSpace);
}
Set<String> lineIds = new HashSet<>(32);
Set<String> institutionIds = new HashSet<>(32);
for (SpaceInstitutionDetailEnt spaceInstitutionDetailEnt : detailEntList) {
lineIds.add(spaceInstitutionDetailEnt.getLineId());
institutionIds.add(spaceInstitutionDetailEnt.getId());
}
//取生效中间开的所有井口
SpaceInstitutionWellheadViewMapper wellheadMapper = context.getBean(SpaceInstitutionWellheadViewMapper.class);
List<SpaceInstitutionWellheadView> spaceWellheadList = wellheadMapper.selectListByInstitutionIds(institutionIds);
if (CollUtil.isEmpty(spaceWellheadList)) {
//未发现可优化井口
return XServiceResult.error(context, BusinessError.DidNotFindWellhead);
}
this.setServiceRatingForSpaceWellheadList(context, spaceWellheadList);
//取线路关联的所有光伏电站ID
List<DynamicQueryBasePowerLinePlantOutput> plantList = this.getPowerLinePlantListByLineIds(context, lineIds);
if (CollUtil.isEmpty(plantList)) {
//未发现可用光伏电站
return XServiceResult.error(context, BusinessError.DidNotFindPlant);
}
//取当前时间
DateTime date = DateUtil.date();
//取生效中的基础间开
List<SpaceInstitutionDetailEnt> detailEntList = super.getEffectiveSpaceInstitution(context, date.toString(BusinessConstant.DATE_FORMAT_DAY));
SpaceOptimizeWellheadAndPlant wellheadAndPlant = super.getWellheadAndPlant(context, detailEntList);
List<SpaceInstitutionWellheadView> spaceWellheadList = wellheadAndPlant.getSpaceWellheadList();
Map<String, List<String>> plantIdsByLineIdMap = wellheadAndPlant.getPlantIdsByLineIdMap();
//取年份
int year = date.year();
//月份要加一
int monthNum = date.month() + 1;
......@@ -96,10 +60,10 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
month = String.valueOf(monthNum);
}
SpaceInstitutionDurationMapper durationMapper = context.getBean(SpaceInstitutionDurationMapper.class);
List<SpaceOptimizeLongPeriodView> longPeriodList = new ArrayList<>(32);
List<SpaceOptimizeLongWellheadView> longWellheadList = new ArrayList<>(64);
List<SpaceOptimizeLongDurationView> longDurationList = new ArrayList<>(128);
List<SpaceOptimizeLongDurationView> unOptimizeDurationList = new ArrayList<>(128);
List<SpaceOptimizePeriodDTO> periodDTOList = new ArrayList<>(32);
List<SpaceOptimizeWellheadDTO> wellheadDTOList = new ArrayList<>(64);
List<SpaceOptimizeDurationDTO> durationDTOList = new ArrayList<>(128);
List<SpaceOptimizeDurationDTO> unOptimizeDurationList = new ArrayList<>(128);
String executionCycleForMonth = BaseUtils.getExecutionCycleForMonth(date);
DateTime optimizeDeadline = DateUtil.endOfMonth(date);
//优化
......@@ -107,275 +71,43 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
String detailId = detail.getId();
String lineId = detail.getLineId();
//创建记录
String longPeriodId = this.createOptimizeLongPeriod(longPeriodList, detailId, lineId, executionCycleForMonth, optimizeDeadline);
String periodId = super.createOptimizePeriod(periodDTOList, detailId, lineId, executionCycleForMonth, optimizeDeadline);
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList;
switch (detail.getGridTypeKey()) {
//并网型优化
case "1":
//获取当前制度对应的光伏预测数据列表
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList = this.getAveragePowerGenerationListByPlantIds(context,
avgPowerList = super.getAveragePowerGenerationListByPlantIds(context,
DynamicQueryPlantPredictedPowerInput.builder()
.plantIds(
plantList.stream()
.filter(p -> StringUtils.equals(lineId, p.getLineId()))
.map(DynamicQueryBasePowerLinePlantOutput::getPlantId)
.collect(Collectors.toList())
)
.plantIds(plantIdsByLineIdMap.get(lineId))
.yearTime(String.valueOf(year))
.monthTime(month)
.build()
);
//取光伏出力峰值
BigDecimal powerMax = avgPowerList.stream()
.map(DynamicQueryPlantPredictedPowerOutput::getPower)
.max(BigDecimal::compareTo)
.orElse(BigDecimal.ZERO);
//取当前制度下井口的总功率
BigDecimal wellheadTotalPower = spaceWellheadList.stream()
.filter(w -> StringUtils.equals(detailId, w.getInstitutionId()))
.map(SpaceInstitutionWellheadView::getServiceRating)
.reduce(BigDecimal.ZERO, BigDecimal::add);
//根据类型过滤井口:大间开,连抽井不优化
List<SpaceInstitutionWellheadView> wellheadViewList = spaceWellheadList.stream()
.filter(w -> StringUtils.equals(detailId, w.getInstitutionId()) &&
StringUtils.equals("INTERVAL", w.getRunTypeKey()) &&
StringUtils.equals("0", w.getIntervalTypeKey()))
.sorted(Comparator.comparing(SpaceInstitutionWellheadView::getStartSeq))
.collect(Collectors.toList());
if (CollUtil.isEmpty(wellheadViewList)) {
continue;
}
//通过间开ID和井口ID查所有井口时段配置
List<SpaceInstitutionDurationEnt> durationList = durationMapper.selectList(new LambdaQueryWrapper<SpaceInstitutionDurationEnt>()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceInstitutionDurationEnt::getInstitutionId, detailId)
.orderByAsc(SpaceInstitutionDurationEnt::getOpenWellTime)
);
if (CollUtil.isEmpty(durationList)) {
//没有设置时间段,无法优化
continue;
}
Map<String, List<SpaceInstitutionDurationEnt>> durationMap = durationList.stream()
.collect(Collectors.groupingBy(SpaceInstitutionDurationEnt::getWellheadId));
int compare = powerMax.compareTo(wellheadTotalPower);
//光伏出力峰值大于等于井口总功率:绿电消纳优先策略
if (compare >= BusinessConstant.ZERO) {
//---------------------------------绿电消纳策略---------------------------------
this.greenElectricityConsumptionStrategy(longWellheadList, unOptimizeDurationList, longDurationList,
wellheadViewList, avgPowerList, durationMap, detail, longPeriodId);
} else {
//遍历井口,按发电功率大于等于光伏出力峰值条件分组
Map<Boolean, List<SpaceInstitutionWellheadView>> collect = spaceWellheadList.stream()
.filter(w ->
StringUtils.equals(detailId, w.getInstitutionId())
)
.collect(Collectors.partitioningBy(w -> powerMax.compareTo(w.getServiceRating()) >= BusinessConstant.ZERO));
List<SpaceInstitutionWellheadView> lowWellheadList = collect.get(false);
int size = spaceWellheadList.size();
int lowWellheadListSize = lowWellheadList.size();
//光伏出力峰值<任何一口井的运行功率:消峰平谷策略
if (size == lowWellheadListSize) {
//---------------------------------消峰平谷策略---------------------------------
this.peakEliminationAndValleyLevelingStrategy(context, longWellheadList, unOptimizeDurationList, longDurationList, wellheadViewList,
durationMap, detail, lineId, monthNum, longPeriodId);
}
//光伏出力峰值>=线路哪部分井口运行功率:满足的部分井口采用绿电消纳优先,不满足的井采用消峰平谷
else {
List<SpaceInstitutionWellheadView> highWellheadList = collect.get(true);
this.greenElectricityConsumptionStrategy(longWellheadList, unOptimizeDurationList, longDurationList,
highWellheadList, avgPowerList, durationMap, detail, longPeriodId);
this.peakEliminationAndValleyLevelingStrategy(context, longWellheadList, unOptimizeDurationList, longDurationList, lowWellheadList,
durationMap, detail, lineId, monthNum, longPeriodId);
}
}
super.gridConnectedOptimization(context, durationMapper, wellheadDTOList, durationDTOList, unOptimizeDurationList,
spaceWellheadList, avgPowerList, detail, monthNum, detailId, periodId, lineId);
break;
//离网型优化
case "0":
break;
default:
//电网类型不存在
}
}
//开启事务
return XTransactionHelper.begin(context, () -> {
int size;
if (CollUtil.isNotEmpty(longPeriodList)) {
SpaceOptimizeLongPeriodViewMapper longPeriodViewMapper = context.getBean(SpaceOptimizeLongPeriodViewMapper.class);
size = longPeriodList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeLongPeriodView>> subList = BaseUtils.getSubList(longPeriodList);
subList.forEach(b -> longPeriodViewMapper.batchInsertList(b));
} else {
longPeriodViewMapper.batchInsertList(longPeriodList);
}
}
if (CollUtil.isNotEmpty(longWellheadList)) {
SpaceOptimizeLongWellheadViewMapper longWellheadViewMapper = context.getBean(SpaceOptimizeLongWellheadViewMapper.class);
size = longWellheadList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeLongWellheadView>> subList = BaseUtils.getSubList(longWellheadList);
subList.forEach(b -> longWellheadViewMapper.batchInsertList(b));
} else {
longWellheadViewMapper.batchInsertList(longWellheadList);
}
}
if (CollUtil.isNotEmpty(unOptimizeDurationList)) {
SpaceOptimizeLongDurationViewMapper longDurationViewMapper = context.getBean(SpaceOptimizeLongDurationViewMapper.class);
size = unOptimizeDurationList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeLongDurationView>> subList = BaseUtils.getSubList(unOptimizeDurationList);
subList.forEach(b -> longDurationViewMapper.batchInsertList(b));
} else {
longDurationViewMapper.batchInsertList(unOptimizeDurationList);
}
}
if (CollUtil.isNotEmpty(longDurationList)) {
SpaceOptimizeLongDurationViewMapper longDurationViewMapper = context.getBean(SpaceOptimizeLongDurationViewMapper.class);
size = longDurationList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeLongDurationView>> subList = BaseUtils.getSubList(longDurationList);
subList.forEach(b -> longDurationViewMapper.batchInsertList(b));
} else {
longDurationViewMapper.batchInsertList(longDurationList);
}
}
return XServiceResult.OK;
});
}
/*-----------------------------------private-----------------------------------*/
/**
* 消峰平谷策略
*
* @param context 上下文
* @param longWellheadList 长井口列表
* @param unOptimizeDurationList 取消优化工期列表
* @param longDurationList 长期清单
* @param wellheadViewList 井口视图列表
* @param durationMap 持续时间图
* @param detail 细节
* @param lineId 线路id
* @param monthNum 月份
* @param longPeriodId 长周期id
*/
private void peakEliminationAndValleyLevelingStrategy(XContext context, List<SpaceOptimizeLongWellheadView> longWellheadList, List<SpaceOptimizeLongDurationView> unOptimizeDurationList,
List<SpaceOptimizeLongDurationView> longDurationList, List<SpaceInstitutionWellheadView> wellheadViewList,
Map<String, List<SpaceInstitutionDurationEnt>> durationMap, SpaceInstitutionDetailEnt detail,
String lineId, int monthNum, String longPeriodId) {
//通过线路ID和月份获取市电峰谷策略明细配置
List<GetBasePriceStrategyDetailOutput> strategyDetailList = ServiceUtil.getStrategyDetailList(context,
GetBasePriceStrategyDetailInput.builder()
.lineId(lineId)
.strategyMonth(String.valueOf(monthNum))
//获取当前制度对应的光伏预测数据列表
avgPowerList = super.getAveragePowerGenerationListByPlantIds(context,
DynamicQueryPlantPredictedPowerInput.builder()
.plantIds(plantIdsByLineIdMap.get(lineId))
.yearTime(String.valueOf(year))
.monthTime(month)
.build()
);
if (CollUtil.isEmpty(strategyDetailList)) {
//没有配置,不优化
return;
}
//获取第一段谷电阶段的开始时间为第一口井的开井时间
Optional<GetBasePriceStrategyDetailOutput> low = strategyDetailList.stream()
.filter(s -> !StringUtils.isAnyBlank(s.getEndTime(), s.getStartTime()) && StringUtils.equals("LOW", s.getPeriodTypeKey()))
.findFirst();
if (!low.isPresent()) {
//没有谷电,不优化
return;
}
GetBasePriceStrategyDetailOutput strategyDetailOutput = low.get();
//第一口井启动时间
DateTime firstStartTime = DateUtil.parse(strategyDetailOutput.getStartTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
DateTime firstEndTime = DateUtil.parse(strategyDetailOutput.getEndTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
//判断是否第一口井
boolean isFirstWellhead;
//时间差
int between = 0;
//启动间隔累积
int startInterval = 0;
for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) {
SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w);
String wellheadId = wellhead.getWellheadId();
String recordId = this.createOptimizeLongWellhead(longWellheadList, longPeriodId, wellheadId, wellhead.getWellNumber());
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellhead);
if (CollUtil.isEmpty(durationConfigList)) {
//没有设置时间段,无法优化
//根据类型过滤井口:大间开,连抽井不优化
List<SpaceInstitutionWellheadView> wellheadViewList = this.getWellheadViewList(spaceWellheadList, detailId);
if (CollUtil.isEmpty(wellheadViewList)) {
continue;
}
//保存原始记录
for (SpaceInstitutionDurationEnt durationEnt : durationConfigList) {
this.createUnOptimizeLongDuration(unOptimizeDurationList, durationEnt, longPeriodId, recordId, wellheadId);
}
if (w == 0) {
//第一个井口
isFirstWellhead = true;
} else {
//计算启动间隔
startInterval = startInterval + detail.getStartInterval();
isFirstWellhead = false;
}
for (int d = 0, durationSize = durationConfigList.size(); d < durationSize; d++) {
SpaceInstitutionDurationEnt duration = durationConfigList.get(d);
String openWellTime = duration.getOpenWellTime();
DateTime startTime = DateUtil.parse(openWellTime + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
DateTime endTime = DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
//第一次启动
if (d == 0) {
//第一口井的启动时间
if (isFirstWellhead) {
//计算优化后的时间差优化后的第一口井开井时间-优化前第一次开井时间
int startDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
//第一次关井时间按照启动时长顺延
DateTime endTimeOptimize = startTime.offset(DateField.MINUTE, startDuration);
this.createOptimizeLongDuration(longDurationList, longPeriodId, recordId, wellheadId, null,
strategyDetailOutput.getStartTime(), endTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT)
);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(firstEndTime, endTime);
}//其它井口的第一次启动时间
else {
//其它井启动时间:第一口井启动时间+启动间隔
DateTime startTimeOffset = firstStartTime.offset(DateField.MINUTE, startInterval);
DateTime endTimeOffset = firstEndTime.offset(DateField.MINUTE, startInterval);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(firstEndTime, endTime);
this.createOptimizeLongDuration(longDurationList, longPeriodId, recordId, wellheadId, null,
startTimeOffset.toString(BusinessConstant.MINUTES_FORMAT), endTimeOffset.toString(BusinessConstant.MINUTES_FORMAT)
);
}
} else {
//计算偏移
DateTime offset = startTime.offset(DateField.MINUTE, between);
if (offset.compareTo(BusinessConstant.DATE_FLAG) > 0) {
//如果时间超过当天,舍弃
//获取井口间开时间段
Map<String, List<SpaceInstitutionDurationEnt>> durationMap = this.getDurationMap(durationMapper, detailId);
if (CollUtil.isEmpty(durationMap)) {
//没有设置时间段,无法优化
continue;
}
this.createOptimizeLongDuration(longDurationList, longPeriodId, recordId, wellheadId, null,
offset.toString(BusinessConstant.MINUTES_FORMAT), BaseUtils.getEndTimeString(
DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT)
.offset(DateField.MINUTE, between)
)
);
}
}
}
}
/**
* 绿电消纳策略
*
* @param longWellheadList 长井口列表
* @param unOptimizeDurationList 取消优化工期列表
* @param longDurationList 长期清单
* @param wellheadViewList 井口视图列表
* @param avgPowerList 平均功率列表
* @param durationMap 持续时间图
* @param detail 细节
* @param longPeriodId 长周期id
*/
private void greenElectricityConsumptionStrategy(List<SpaceOptimizeLongWellheadView> longWellheadList, List<SpaceOptimizeLongDurationView> unOptimizeDurationList,
List<SpaceOptimizeLongDurationView> longDurationList, List<SpaceInstitutionWellheadView> wellheadViewList,
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList, Map<String, List<SpaceInstitutionDurationEnt>> durationMap,
SpaceInstitutionDetailEnt detail, String longPeriodId) {
//时间差
int between = 0;
//启动间隔累积
......@@ -384,12 +116,16 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
boolean isFirstWellhead;
//第一口井启动时间
DateTime firstStartTime = null;
//第一口井开井时间
int firstIndex = 0;
//井口累积运行总功率
BigDecimal totalOperatingPower = BigDecimal.ZERO;
//离网时间段
List<SpaceOptimizeDurationDTO> offGridPeriodList = new ArrayList<>(32);
for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) {
SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w);
String wellheadId = wellhead.getWellheadId();
String recordId = this.createOptimizeLongWellhead(longWellheadList, longPeriodId, wellheadId, wellhead.getWellNumber());
String recordId = this.createOptimizeWellhead(wellheadDTOList, periodId, wellheadId, wellhead.getWellNumber());
//取当前井口最大发电量
BigDecimal serviceRating = wellhead.getServiceRating();
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellhead);
......@@ -399,15 +135,14 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
}
//保存原始记录
for (SpaceInstitutionDurationEnt durationEnt : durationConfigList) {
this.createUnOptimizeLongDuration(unOptimizeDurationList, durationEnt, longPeriodId, recordId, wellheadId);
this.createUnOptimizeDuration(unOptimizeDurationList, durationEnt, periodId, recordId, wellheadId);
}
totalOperatingPower = totalOperatingPower.add(serviceRating);
if (w == 0) {
//第一个井口
isFirstWellhead = true;
totalOperatingPower.add(serviceRating);
} else {
//累加
totalOperatingPower = totalOperatingPower.add(serviceRating);
startInterval = startInterval + detail.getStartInterval();
isFirstWellhead = false;
}
......@@ -422,23 +157,20 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
if (isFirstWellhead) {
firstStartTime = startTime;
//计算开井时间
int startIndex = 0;
for (int a = 0, avgPowerSize = avgPowerList.size(); a < avgPowerSize; a++) {
DynamicQueryPlantPredictedPowerOutput predictedPower = avgPowerList.get(a);
//当日时间段平均光伏出力>=第一口井运行负荷时,该时间为第一口井运行时间
if (predictedPower.getPower().compareTo(serviceRating) >= BusinessConstant.ZERO) {
startIndex = a;
firstIndex = a;
break;
}
}
DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(startIndex);
DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(firstIndex);
String startTimeString = start.getHourTime() + start.getMinTime();
//计算第一次关井时间,按照间开时间段顺延
int startDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
DateTime endTimeOptimize = startTime.offset(DateField.MINUTE, startDuration);
this.createOptimizeLongDuration(longDurationList, longPeriodId, recordId, wellheadId, null,
startTimeString, endTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT)
);
this.createDurationOffGridPeriod(offGridPeriodList, wellheadId, startTimeString, endTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT));
//计算时间偏移
DateTime startTimeOptimize = DateUtil.parse(startTimeString, BusinessConstant.TIME_FORMAT);
//取时间间隔(分钟)
......@@ -448,13 +180,12 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
else {
DateTime startTimeOffset = firstStartTime.offset(DateField.MINUTE, startInterval);
int startIndex = -1;
BigDecimal add = serviceRating.add(totalOperatingPower);
for (int a = 0, avgPowerSize = avgPowerList.size(); a < avgPowerSize; a++) {
DynamicQueryPlantPredictedPowerOutput predictedPower = avgPowerList.get(a);
if (DateUtil.parse(predictedPower.getHourTime() + predictedPower.getMinTime(), BusinessConstant.TIME_FORMAT)
.compareTo(startTimeOffset) >= 0) {
//判断第一口井启动时间+启动间隔时日平均光伏出力-前两口井的运行功率是否为正数
if (predictedPower.getPower().compareTo(add) >= 0) {
if (predictedPower.getPower().compareTo(totalOperatingPower) >= 0) {
//确定第二口井第一次开井时间为第一口井启动时间+启动间隔
startIndex = a;
break;
......@@ -467,9 +198,7 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
//计算未优化启动间隔
int openDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
DateTime endTimeOptimize = startTimeOptimize.offset(DateField.MINUTE, openDuration);
this.createOptimizeLongDuration(longDurationList, longPeriodId, recordId, wellheadId, null,
openWellTime, BaseUtils.getEndTimeString(endTimeOptimize)
);
this.createDurationOffGridPeriod(offGridPeriodList, wellheadId, openWellTime, BaseUtils.getEndTimeString(endTimeOptimize));
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(endTimeOptimize, endTime);
} else {
......@@ -483,7 +212,7 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
continue;
}
//计算偏移
this.createOptimizeLongDuration(longDurationList, longPeriodId, recordId, wellheadId, null,
this.createDurationOffGridPeriod(offGridPeriodList, wellheadId,
offset.toString(BusinessConstant.MINUTES_FORMAT),
BaseUtils.getEndTimeString(DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT)
.offset(DateField.MINUTE, between))
......@@ -491,155 +220,76 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
}
}
}
//离网优化
if (CollUtil.isNotEmpty(offGridPeriodList)) {
//截取从第一次开井时间往后的时间段
List<DynamicQueryPlantPredictedPowerOutput> subAvgPowerList = CollUtil.sub(avgPowerList, firstIndex + 1, avgPowerList.size());
if (CollUtil.isEmpty(subAvgPowerList)) {
return XServiceResult.error(context, BusinessError.UnableToOptimize);
}
/**
* 创建长期优化信息
*
* @param longPeriodList 长期清单
* @param detailId 详细信息id
* @param lineId 线路id
* @param executionCycleForMonth 月执行周期
* @param optimizeDeadline 优化截止日期
* @return {@link String}
*/
private String createOptimizeLongPeriod(List<SpaceOptimizeLongPeriodView> longPeriodList, String detailId, String lineId, String executionCycleForMonth, Date optimizeDeadline) {
SpaceOptimizeLongPeriodView longPeriod = new SpaceOptimizeLongPeriodView();
BaseUtils.setBaseModelDefaultForJob(longPeriod);
longPeriod.setInstitutionId(detailId);
longPeriod.setLineId(lineId);
longPeriod.setExecutionCycle(executionCycleForMonth);
longPeriod.setOptimizeDeadline(optimizeDeadline);
longPeriodList.add(longPeriod);
return longPeriod.getId();
//逐15分钟计算光伏出力-井场运行功率之和,获得光伏出力不足时间段
for (DynamicQueryPlantPredictedPowerOutput avg : subAvgPowerList) {
avg.setMeetFlag(avg.getPower().compareTo(totalOperatingPower) >= 0);
}
/**
* 创建长期优化井口信息
*
* @param longWellheadList 长井口列表
* @param longPeriodId 长周期id
* @param wellheadId 井口id
* @param wellNumber 井号
* @return {@link String}
*/
private String createOptimizeLongWellhead(List<SpaceOptimizeLongWellheadView> longWellheadList, String longPeriodId, String wellheadId, String wellNumber) {
SpaceOptimizeLongWellheadView wellheadView = new SpaceOptimizeLongWellheadView();
BaseUtils.setBaseModelDefaultForJob(wellheadView);
wellheadView.setLongPeriodId(longPeriodId);
wellheadView.setWellheadId(wellheadId);
wellheadView.setWellNumber(wellNumber);
longWellheadList.add(wellheadView);
return wellheadView.getId();
}
/**
* 创建长期优化井口区间配置信息
*
* @param longDurationList 长期清单
* @param longPeriodId 长周期id
* @param recordId 记录id
* @param wellheadId 井口id
* @param generationTypeKey 生成类型密钥
* @param openWellTime 开井时间
* @param endTimeString 结束时间字符串
*/
private void createOptimizeLongDuration(List<SpaceOptimizeLongDurationView> longDurationList, String longPeriodId,
String recordId, String wellheadId, String generationTypeKey, String openWellTime, String endTimeString) {
SpaceOptimizeLongDurationView durationView = new SpaceOptimizeLongDurationView();
BaseUtils.setBaseModelDefaultForJob(durationView);
durationView.setRecordId(recordId);
durationView.setLongPeriodId(longPeriodId);
durationView.setWellheadId(wellheadId);
durationView.setGenerationTypeKey(generationTypeKey);
durationView.setIsOptimize(BusinessConstant.ZERO);
durationView.setOpenWellTime(openWellTime);
durationView.setCloseWellTime(endTimeString);
longDurationList.add(durationView);
break;
default:
//电网类型不存在
}
/**
* 创建原始间开区间
*
* @param unOptimizeDurationList 取消优化工期列表
* @param durationEnt 持续时间ent
* @param longPeriodId 长周期id
* @param recordId 记录id
* @param wellheadId 井口id
*/
private void createUnOptimizeLongDuration(List<SpaceOptimizeLongDurationView> unOptimizeDurationList, SpaceInstitutionDurationEnt durationEnt,
String longPeriodId, String recordId, String wellheadId) {
SpaceOptimizeLongDurationView durationViewUnOptimize = new SpaceOptimizeLongDurationView();
BaseUtils.setBaseModelDefaultForJob(durationViewUnOptimize);
durationViewUnOptimize.setRecordId(recordId);
durationViewUnOptimize.setLongPeriodId(longPeriodId);
durationViewUnOptimize.setWellheadId(wellheadId);
durationViewUnOptimize.setIsOptimize(BusinessConstant.ONE);
durationViewUnOptimize.setOpenWellTime(durationEnt.getOpenWellTime());
durationViewUnOptimize.setCloseWellTime(durationEnt.getCloseWellTime());
unOptimizeDurationList.add(durationViewUnOptimize);
}
/**
* 条件获取获取光伏预测各时段平均值列表
*
* @param context 上下文
* @param input 输入
* @return {@link List}<{@link DynamicQueryPlantPredictedPowerOutput}>
*/
private List<DynamicQueryPlantPredictedPowerOutput> getAveragePowerGenerationListByPlantIds(XContext context, DynamicQueryPlantPredictedPowerInput input) {
IPlantPredictedPowerCloudService cloudService = context.getBean(IPlantPredictedPowerCloudService.class);
XListResult<DynamicQueryPlantPredictedPowerOutput> result = cloudService.queryAveragePowerGenerationListByParam(context, input);
result.throwIfFail();
return result.getResult();
//开启事务
return XTransactionHelper.begin(context, () -> {
int size;
SpaceOptimizeViewMapper optimizeViewMapper = context.getBean(SpaceOptimizeViewMapper.class);
if (CollUtil.isNotEmpty(periodDTOList)) {
size = periodDTOList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizePeriodDTO>> subList = BaseUtils.getSubList(periodDTOList);
subList.forEach(b -> optimizeViewMapper.longPeriodBatchInsertList(b));
} else {
optimizeViewMapper.longPeriodBatchInsertList(periodDTOList);
}
/**
* 按线路ID集合获取电站列表
*
* @param context 上下文
* @param lineIds 线路ID
* @return {@link List}<{@link DynamicQueryBasePowerLinePlantOutput}>
*/
private List<DynamicQueryBasePowerLinePlantOutput> getPowerLinePlantListByLineIds(XContext context, Set<String> lineIds) {
IBasePowerLineCloudService cloudService = context.getBean(IBasePowerLineCloudService.class);
XListResult<DynamicQueryBasePowerLinePlantOutput> result = cloudService.queryPowerLinePlantListByParam(context,
DynamicQueryBasePowerLinePlantInput.builder()
.lineIds(lineIds)
.build()
);
result.throwIfFail();
return result.getResult();
}
/**
* 为间开井口列表设置发电功率
*
* @param context 上下文
* @param spaceWellheadList 空间井口清单
*/
private void setServiceRatingForSpaceWellheadList(XContext context, List<SpaceInstitutionWellheadView> spaceWellheadList) {
IBaseWellheadCloudService cloudService = context.getBean(IBaseWellheadCloudService.class);
XListResult<DynamicQueryBaseWellheadOutput> result = cloudService.queryBaseWellheadListByParam(context,
DynamicQueryBaseWellheadInput.builder()
.wellheadIds(spaceWellheadList.stream()
.map(SpaceInstitutionWellheadView::getWellheadId)
.collect(Collectors.toList())
)
.build());
result.throwIfFail();
List<DynamicQueryBaseWellheadOutput> wellheadOutputList = result.getResult();
if (CollUtil.isEmpty(wellheadOutputList)) {
return;
}
spaceWellheadList.forEach(s -> {
s.setServiceRating(
wellheadOutputList.stream()
.filter(w -> StringUtils.equals(s.getWellheadId(), w.getId()))
.findAny()
.map(DynamicQueryBaseWellheadOutput::getServiceRating)
.orElse(BigDecimal.ZERO)
);
if (CollUtil.isNotEmpty(wellheadDTOList)) {
size = wellheadDTOList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeWellheadDTO>> subList = BaseUtils.getSubList(wellheadDTOList);
subList.forEach(b -> optimizeViewMapper.longWellheadBatchInsertList(b));
} else {
optimizeViewMapper.longWellheadBatchInsertList(wellheadDTOList);
}
}
if (CollUtil.isNotEmpty(unOptimizeDurationList)) {
size = unOptimizeDurationList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeDurationDTO>> subList = BaseUtils.getSubList(unOptimizeDurationList);
subList.forEach(b -> optimizeViewMapper.longDurationBatchInsertList(b));
} else {
optimizeViewMapper.longDurationBatchInsertList(unOptimizeDurationList);
}
}
if (CollUtil.isNotEmpty(durationDTOList)) {
size = durationDTOList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeDurationDTO>> subList = BaseUtils.getSubList(durationDTOList);
subList.forEach(b -> optimizeViewMapper.longDurationBatchInsertList(b));
} else {
optimizeViewMapper.longDurationBatchInsertList(durationDTOList);
}
}
return XServiceResult.OK;
});
}
/*-----------------------------------private-----------------------------------*/
public void createDurationOffGridPeriod(List<SpaceOptimizeDurationDTO> offGridPeriodList, String wellheadId,
String openWellTime, String endTimeString) {
SpaceOptimizeDurationDTO durationDTO = new SpaceOptimizeDurationDTO();
durationDTO.setWellheadId(wellheadId);
durationDTO.setOpenWellTime(openWellTime);
durationDTO.setCloseWellTime(endTimeString);
offGridPeriodList.add(durationDTO);
}
}
\ No newline at end of file
package pps.core.space.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerInput;
import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerOutput;
import pps.cloud.space.service.ISpaceOptimizeMidCloudService;
import pps.core.common.constant.BusinessConstant;
import pps.core.common.utils.BaseUtils;
import pps.core.space.entity.*;
import pps.core.space.mapper.SpaceInstitutionDurationMapper;
import pps.core.space.mapper.SpaceOptimizeViewMapper;
import pps.core.space.service.data.SpaceOptimizeWellheadAndPlant;
import xstartup.annotation.XService;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
import xstartup.helper.XTransactionHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 中短期间开优化Cloud模块
*
* @author ZWT
* @date 2023/09/18 14:14
*/
@XService
public class SpaceOptimizeMidCloudServiceImpl extends SpaceOptimizeBaseService implements ISpaceOptimizeMidCloudService {
/**
* 中短期间开优化Cloud模块--定时任务
*
* @param context 上下文
* @return {@link XServiceResult}
*/
@Override
public XServiceResult optimizeMidJob(XContext context) {
//取当前时间
DateTime date = DateUtil.date();
String startWeek = date.toString(BusinessConstant.DATE_FORMAT_DAY);
//取生效中的基础间开
List<SpaceInstitutionDetailEnt> detailEntList = super.getEffectiveSpaceInstitution(context, startWeek);
SpaceOptimizeWellheadAndPlant wellheadAndPlant = super.getWellheadAndPlant(context, detailEntList);
List<SpaceInstitutionWellheadView> spaceWellheadList = wellheadAndPlant.getSpaceWellheadList();
Map<String, List<String>> plantIdsByLineIdMap = wellheadAndPlant.getPlantIdsByLineIdMap();
//月份要加一
int monthNum = date.month() + 1;
SpaceInstitutionDurationMapper durationMapper = context.getBean(SpaceInstitutionDurationMapper.class);
List<SpaceOptimizePeriodDTO> periodDTOList = new ArrayList<>(32);
List<SpaceOptimizeWellheadDTO> wellheadDTOList = new ArrayList<>(64);
List<SpaceOptimizeDurationDTO> durationDTOList = new ArrayList<>(128);
List<SpaceOptimizeDurationDTO> unOptimizeDurationList = new ArrayList<>(128);
String executionCycleForWeek = BaseUtils.getExecutionCycleForWeek(date);
//优化截止日期
DateTime optimizeDeadline = DateUtil.endOfWeek(date);
//日期查询范围结束条件,下周一
String nextWeek = DateUtil.beginOfWeek(DateUtil.nextWeek()).toString(BusinessConstant.DATE_FORMAT_DAY);
//优化
for (SpaceInstitutionDetailEnt detail : detailEntList) {
String detailId = detail.getId();
String lineId = detail.getLineId();
//创建记录
String periodId = super.createOptimizePeriod(periodDTOList, detailId, lineId, executionCycleForWeek, optimizeDeadline);
switch (detail.getGridTypeKey()) {
//并网型优化
case "1":
//获取当前制度对应的光伏预测数据列表
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList = super.getAveragePowerGenerationListByPlantIds(context,
DynamicQueryPlantPredictedPowerInput.builder()
.plantIds(plantIdsByLineIdMap.get(lineId))
.startTime(startWeek)
.endTime(nextWeek)
.build()
);
super.gridConnectedOptimization(context, durationMapper, wellheadDTOList, durationDTOList, unOptimizeDurationList,
spaceWellheadList, avgPowerList, detail, monthNum, detailId, periodId, lineId);
break;
//离网型优化
case "0":
break;
default:
//电网类型不存在
}
}
//开启事务
return XTransactionHelper.begin(context, () -> {
int size;
SpaceOptimizeViewMapper optimizeViewMapper = context.getBean(SpaceOptimizeViewMapper.class);
if (CollUtil.isNotEmpty(periodDTOList)) {
size = periodDTOList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizePeriodDTO>> subList = BaseUtils.getSubList(periodDTOList);
subList.forEach(b -> optimizeViewMapper.midPeriodBatchInsertList(b));
} else {
optimizeViewMapper.midPeriodBatchInsertList(periodDTOList);
}
}
if (CollUtil.isNotEmpty(wellheadDTOList)) {
size = wellheadDTOList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeWellheadDTO>> subList = BaseUtils.getSubList(wellheadDTOList);
subList.forEach(b -> optimizeViewMapper.midWellheadBatchInsertList(b));
} else {
optimizeViewMapper.midWellheadBatchInsertList(wellheadDTOList);
}
}
if (CollUtil.isNotEmpty(unOptimizeDurationList)) {
size = unOptimizeDurationList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeDurationDTO>> subList = BaseUtils.getSubList(unOptimizeDurationList);
subList.forEach(b -> optimizeViewMapper.midDurationBatchInsertList(b));
} else {
optimizeViewMapper.midDurationBatchInsertList(unOptimizeDurationList);
}
}
if (CollUtil.isNotEmpty(durationDTOList)) {
size = durationDTOList.size();
if (size > BaseUtils.BATCH_SIZE) {
List<List<SpaceOptimizeDurationDTO>> subList = BaseUtils.getSubList(durationDTOList);
subList.forEach(b -> optimizeViewMapper.midDurationBatchInsertList(b));
} else {
optimizeViewMapper.midDurationBatchInsertList(durationDTOList);
}
}
return XServiceResult.OK;
});
}
/*-----------------------------------private-----------------------------------*/
}
\ No newline at end of file
package pps.core.space.service;
import pps.cloud.space.service.ISpaceOptimizeShortCloudService;
import xstartup.annotation.XService;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
/**
* 短期间开优化Cloud模块
*
* @author ZWT
* @date 2023/09/20 11:44
*/
@XService
public class SpaceOptimizeShortCloudServiceImpl implements ISpaceOptimizeShortCloudService {
/**
* 短期间开优化Cloud模块--定时任务
*
* @param context 上下文
* @return {@link XServiceResult}
*/
@Override
public XServiceResult optimizeShortJob(XContext context) {
return XServiceResult.OK;
}
}
package pps.core.space.service.data;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import pps.core.space.entity.SpaceInstitutionWellheadView;
import java.util.List;
import java.util.Map;
/**
* 间开优化数据集
*
* @author ZWT
* @date 2023/09/18 16:42
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SpaceOptimizeWellheadAndPlant {
/**
* 井口列表
*/
List<SpaceInstitutionWellheadView> spaceWellheadList;
/**
* 电站Map
*/
Map<String, List<String>> plantIdsByLineIdMap;
}
......@@ -175,7 +175,7 @@ public class ServiceUtil {
allList.add(
SpaceOptimizeDateDuration.builder()
.openWellTime("00:00")
.closeWellTime("24:00")
.closeWellTime("23:59")
.isOpen(0)
.build()
);
......@@ -219,11 +219,11 @@ public class ServiceUtil {
}
if (i == last) {
//如果结束时间不是24:00开始,初始化最终关井时间
if (!StringUtils.equals("24:00", closeWellTime)) {
if (!StringUtils.equals("23:59", closeWellTime)) {
allList.add(
SpaceOptimizeDateDuration.builder()
.openWellTime(closeWellTime)
.closeWellTime("24:00")
.closeWellTime("23:59")
.isOpen(0)
.build()
);
......
......@@ -63,4 +63,25 @@
AND h.line_id = #{lineId}
ORDER BY h.calibration_date DESC
</select>
<insert id="batchInsertList" parameterType="list">
INSERT INTO space_calibration_history ( id, create_by_id, create_by_name, create_time, modify_by_id,
modify_by_name, modify_time, line_id, institution_id, execution_cycle, calibration_date )
VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.id},
#{item.createById},
#{item.createByName},
#{item.createTime},
#{item.modifyById},
#{item.modifyByName},
#{item.modifyTime},
#{item.lineId},
#{item.institutionId},
#{item.executionCycle},
#{item.calibrationDate}
)
</foreach>
</insert>
</mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pps.core.space.mapper.SpaceOptimizeViewMapper">
<insert id="longPeriodBatchInsertList" parameterType="list">
INSERT INTO space_optimize_long_period ( id, create_by_id, create_by_name, create_time,
modify_by_id, modify_by_name, modify_time, line_id, institution_id, execution_cycle, optimize_state,
optimize_deadline )
VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.id},
#{item.createById},
#{item.createByName},
#{item.createTime},
#{item.modifyById},
#{item.modifyByName},
#{item.modifyTime},
#{item.lineId},
#{item.institutionId},
#{item.executionCycle},
#{item.optimizeState},
#{item.optimizeDeadline}
)
</foreach>
</insert>
<insert id="longWellheadBatchInsertList" parameterType="list">
INSERT INTO space_optimize_long_wellhead ( id, create_by_id, create_by_name, create_time,
modify_by_id, modify_by_name, modify_time, long_period_id, wellhead_id, well_number )
VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.id},
#{item.createById},
#{item.createByName},
#{item.createTime},
#{item.modifyById},
#{item.modifyByName},
#{item.modifyTime},
#{item.periodId},
#{item.wellheadId},
#{item.wellNumber}
)
</foreach>
</insert>
<insert id="longDurationBatchInsertList" parameterType="list">
INSERT INTO space_optimize_long_duration (
id,
create_by_id,
create_by_name,
create_time,
modify_by_id,
modify_by_name,
modify_time,
record_id,
long_period_id,
wellhead_id,
is_optimize,
generation_type_key,
open_well_time,
close_well_time
)
VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.id},
#{item.createById},
#{item.createByName},
#{item.createTime},
#{item.modifyById},
#{item.modifyByName},
#{item.modifyTime},
#{item.recordId},
#{item.periodId},
#{item.wellheadId},
#{item.isOptimize},
<choose>
<when test="item.generationTypeKey != null and item.generationTypeKey != ''">
#{item.generationTypeKey},
</when>
<otherwise>
NULL,
</otherwise>
</choose>
#{item.openWellTime},
#{item.closeWellTime}
)
</foreach>
</insert>
<insert id="midPeriodBatchInsertList" parameterType="list">
INSERT INTO space_optimize_mid_period ( id, create_by_id, create_by_name, create_time,
modify_by_id, modify_by_name, modify_time, line_id, institution_id, execution_cycle, optimize_state,
optimize_deadline )
VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.id},
#{item.createById},
#{item.createByName},
#{item.createTime},
#{item.modifyById},
#{item.modifyByName},
#{item.modifyTime},
#{item.lineId},
#{item.institutionId},
#{item.executionCycle},
#{item.optimizeState},
#{item.optimizeDeadline}
)
</foreach>
</insert>
<insert id="midWellheadBatchInsertList" parameterType="list">
INSERT INTO space_optimize_mid_wellhead ( id, create_by_id, create_by_name, create_time,
modify_by_id, modify_by_name, modify_time, mid_period_id, wellhead_id, well_number )
VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.id},
#{item.createById},
#{item.createByName},
#{item.createTime},
#{item.modifyById},
#{item.modifyByName},
#{item.modifyTime},
#{item.periodId},
#{item.wellheadId},
#{item.wellNumber}
)
</foreach>
</insert>
<insert id="midDurationBatchInsertList" parameterType="list">
INSERT INTO space_optimize_mid_duration (
id,
create_by_id,
create_by_name,
create_time,
modify_by_id,
modify_by_name,
modify_time,
record_id,
mid_period_id,
wellhead_id,
is_optimize,
generation_type_key,
open_well_time,
close_well_time
)
VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.id},
#{item.createById},
#{item.createByName},
#{item.createTime},
#{item.modifyById},
#{item.modifyByName},
#{item.modifyTime},
#{item.recordId},
#{item.periodId},
#{item.wellheadId},
#{item.isOptimize},
<choose>
<when test="item.generationTypeKey != null and item.generationTypeKey != ''">
#{item.generationTypeKey},
</when>
<otherwise>
NULL,
</otherwise>
</choose>
#{item.openWellTime},
#{item.closeWellTime}
)
</foreach>
</insert>
</mapper>
\ No newline at end of file
package pps.cloud.prediction.service;
import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerOutput;
import pps.cloud.prediction.service.data.storage_predicted_power_data.DynamicQueryStoragePredictedPowerInput;
import pps.cloud.prediction.service.data.storage_predicted_power_data.DynamicQueryStoragePredictedPowerOutput;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.data.XListResult;
import xstartup.feature.api.annotation.XApiPost;
/**
* 储能预测电量数据Cloud模块(模拟数据测试用)
*
* @author ZWT
* @date 2023/09/20 15:40
*/
@XService
@XText("储能预测Cloud模块")
public interface IStoragePredictedPowerCloudService {
/**
* 储能预测Cloud模块--条件查询时段储能电量平均值
*
* @param context 上下文
* @param input 输入
* @return {@link XListResult}<{@link DynamicQueryPlantPredictedPowerOutput}>
*/
@XText("储能预测Cloud模块--条件查询时段储能电量平均值")
@XApiPost
XListResult<DynamicQueryStoragePredictedPowerOutput> queryAverageEnergyStorageListByParam(XContext context, DynamicQueryStoragePredictedPowerInput input);
}
......@@ -31,4 +31,10 @@ public class DynamicQueryPlantPredictedPowerInput {
@XText("月")
private String monthTime;
@XText("开始时间")
private String startTime;
@XText("结束时间")
private String endTime;
}
......@@ -14,18 +14,12 @@ import java.math.BigDecimal;
@Data
public class DynamicQueryPlantPredictedPowerOutput {
@XText("日期")
private String dataDate;
@XText("年")
private String yearTime;
@XText("月")
private String monthTime;
@XText("日")
private String dayTime;
@XText("时")
private String hourTime;
......@@ -34,4 +28,7 @@ public class DynamicQueryPlantPredictedPowerOutput {
@XText("预测功率")
private BigDecimal power;
@XText("是否满足")
private boolean meetFlag;
}
package pps.cloud.prediction.service.data.storage_predicted_power_data;
import lombok.Data;
import xstartup.annotation.XText;
import java.util.List;
/**
* 储能预测电量数据(模拟数据测试用)
*
* @author ZWT
* @date 2023/09/20
*/
@Data
public class DynamicQueryStoragePredictedPowerInput {
@XText("储能设备id")
private String storageId;
@XText("储能设备ID集合")
private List<String> storageIds;
@XText("年")
private String yearTime;
@XText("月")
private String monthTime;
@XText("开始时间")
private String startTime;
@XText("结束时间")
private String endTime;
}
package pps.cloud.prediction.service.data.storage_predicted_power_data;
import lombok.Data;
import xstartup.annotation.XText;
import java.math.BigDecimal;
/**
* 储能预测电量数据(模拟数据测试用)
*
* @author ZWT
* @date 2023/09/20
*/
@Data
public class DynamicQueryStoragePredictedPowerOutput {
@XText("年")
private String yearTime;
@XText("月")
private String monthTime;
@XText("时")
private String hourTime;
@XText("分")
private String minTime;
@XText("预测功率")
private BigDecimal power;
}
package pps.core.prediction.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import xstartup.annotation.XText;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 储能预测电量数据(模拟数据测试用)
*
* @author ZWT
* @date 2023/09/20
*/
@Data
@TableName("storage_predicted_power_data")
public class StoragePredictedPowerDataEnt implements Serializable {
@TableId(type = IdType.AUTO)
private Integer id;
@XText("储能设备id")
@TableField
private String storageId;
@XText("日期")
@TableField
private String dataDate;
@XText("年")
@TableField
private String yearTime;
@XText("月")
@TableField
private String monthTime;
@XText("日")
@TableField
private String dayTime;
@XText("时")
@TableField
private String hourTime;
@XText("分")
@TableField
private String minTime;
@XText("预测功率")
@TableField
private BigDecimal power;
@XText("创建时间")
@TableField
private Date createTime;
}
package pps.core.prediction.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import xstartup.annotation.XText;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 储能预测电量数据(模拟数据测试用)
*
* @author ZWT
* @date 2023/09/20
*/
@Data
public class StoragePredictedPowerDataView implements Serializable {
@TableField
private Integer id;
@XText("储能设备id")
@TableField
private String storageId;
@XText("日期")
@TableField
private String dataDate;
@XText("年")
@TableField
private String yearTime;
@XText("月")
@TableField
private String monthTime;
@XText("日")
@TableField
private String dayTime;
@XText("时")
@TableField
private String hourTime;
@XText("分")
@TableField
private String minTime;
@XText("预测功率")
@TableField
private BigDecimal power;
@XText("创建时间")
@TableField
private Date createTime;
}
package pps.core.prediction.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
import pps.core.prediction.entity.StoragePredictedPowerDataEnt;
/**
* 储能预测电量数据(模拟数据测试用)
*
* @author ZWT
* @date 2023/09/20
*/
@Repository(value = "pps.core.prediction.mapper.StoragePredictedPowerDataMapper")
public interface StoragePredictedPowerDataMapper extends BaseMapper<StoragePredictedPowerDataEnt> {
}
package pps.core.prediction.mapper;
import org.springframework.stereotype.Repository;
import pps.core.prediction.entity.StoragePredictedPowerDataView;
import java.util.List;
/**
* 储能预测电量数据(模拟数据测试用)
*
* @author ZWT
* @date 2023/09/20
*/
@Repository(value = "pps.core.prediction.mapper.StoragePredictedPowerDataViewMapper")
public interface StoragePredictedPowerDataViewMapper {
StoragePredictedPowerDataView selectOne(StoragePredictedPowerDataView record);
List<StoragePredictedPowerDataView> selectList(StoragePredictedPowerDataView record);
}
......@@ -38,6 +38,8 @@ public class PlantPredictedPowerCloudServiceImpl implements IPlantPredictedPower
List<String> plantIds = input.getPlantIds();
String yearTime = input.getYearTime();
String monthTime = input.getMonthTime();
String startTime = input.getStartTime();
String endTime = input.getEndTime();
PlantPredictedPowerDataMapper mapper = context.getBean(PlantPredictedPowerDataMapper.class);
List<PlantPredictedPowerDataEnt> list = mapper.selectList(
new QueryWrapper<PlantPredictedPowerDataEnt>()
......@@ -51,6 +53,7 @@ public class PlantPredictedPowerCloudServiceImpl implements IPlantPredictedPower
.in(CollUtil.isNotEmpty(plantIds), PlantPredictedPowerDataEnt::getPlantId, plantIds)
.eq(StringUtils.isNotBlank(yearTime), PlantPredictedPowerDataEnt::getYearTime, yearTime)
.eq(StringUtils.isNotBlank(monthTime), PlantPredictedPowerDataEnt::getMonthTime, monthTime)
.between(!StringUtils.isAnyBlank(startTime, endTime), PlantPredictedPowerDataEnt::getDataDate, startTime, endTime)
.groupBy(PlantPredictedPowerDataEnt::getYearTime,
PlantPredictedPowerDataEnt::getMonthTime,
PlantPredictedPowerDataEnt::getHourTime,
......
package pps.core.prediction.service;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
import pps.cloud.prediction.service.IStoragePredictedPowerCloudService;
import pps.cloud.prediction.service.data.storage_predicted_power_data.DynamicQueryStoragePredictedPowerInput;
import pps.cloud.prediction.service.data.storage_predicted_power_data.DynamicQueryStoragePredictedPowerOutput;
import pps.core.prediction.entity.StoragePredictedPowerDataEnt;
import pps.core.prediction.mapper.StoragePredictedPowerDataMapper;
import xstartup.annotation.XService;
import xstartup.base.XContext;
import xstartup.base.util.XCopyUtils;
import xstartup.data.XListResult;
import java.util.ArrayList;
import java.util.List;
/**
* 储能预测电量数据Cloud模块(模拟数据测试用)
*
* @author ZWT
* @date 2023/09/20 15:44
*/
@XService
public class StoragePredictedPowerCloudServiceImpl implements IStoragePredictedPowerCloudService {
/**
* 储能预测Cloud模块--条件查询时段储能电量平均值
*
* @param context 上下文
* @param input 输入
* @return {@link XListResult}<{@link DynamicQueryStoragePredictedPowerOutput}>
*/
@Override
public XListResult<DynamicQueryStoragePredictedPowerOutput> queryAverageEnergyStorageListByParam(XContext context, DynamicQueryStoragePredictedPowerInput input) {
String storageId = input.getStorageId();
List<String> storageIds = input.getStorageIds();
String yearTime = input.getYearTime();
String monthTime = input.getMonthTime();
String startTime = input.getStartTime();
String endTime = input.getEndTime();
StoragePredictedPowerDataMapper mapper = context.getBean(StoragePredictedPowerDataMapper.class);
List<StoragePredictedPowerDataEnt> list = mapper.selectList(
new QueryWrapper<StoragePredictedPowerDataEnt>()
.select("year_time",
"month_time",
"hour_time",
"min_time",
"AVG( power ) AS power")
.lambda()
.eq(StringUtils.isNotBlank(storageId), StoragePredictedPowerDataEnt::getStorageId, storageId)
.in(CollUtil.isNotEmpty(storageIds), StoragePredictedPowerDataEnt::getStorageId, storageIds)
.eq(StringUtils.isNotBlank(yearTime), StoragePredictedPowerDataEnt::getYearTime, yearTime)
.eq(StringUtils.isNotBlank(monthTime), StoragePredictedPowerDataEnt::getMonthTime, monthTime)
.between(!StringUtils.isAnyBlank(startTime, endTime), StoragePredictedPowerDataEnt::getDataDate, startTime, endTime)
.groupBy(StoragePredictedPowerDataEnt::getYearTime,
StoragePredictedPowerDataEnt::getMonthTime,
StoragePredictedPowerDataEnt::getHourTime,
StoragePredictedPowerDataEnt::getMinTime)
);
List<DynamicQueryStoragePredictedPowerOutput> outputs;
if (CollUtil.isEmpty(list)) {
outputs = new ArrayList<>(0);
} else {
outputs = XCopyUtils.copyNewList(list, DynamicQueryStoragePredictedPowerOutput.class);
}
return XListResult.success(outputs);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pps.core.prediction.mapper.StoragePredictedPowerDataViewMapper">
<resultMap id="BaseResultMap" type="pps.core.prediction.entity.StoragePredictedPowerDataView">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="storage_id" property="storageId" jdbcType="VARCHAR"/>
<result column="data_date" property="dataDate" jdbcType="VARCHAR"/>
<result column="year_time" property="yearTime" jdbcType="VARCHAR"/>
<result column="month_time" property="monthTime" jdbcType="VARCHAR"/>
<result column="day_time" property="dayTime" jdbcType="VARCHAR"/>
<result column="hour_time" property="hourTime" jdbcType="VARCHAR"/>
<result column="min_time" property="minTime" jdbcType="VARCHAR"/>
<result column="power" property="power" jdbcType="DECIMAL"/>
<result column="create_time" property="createTime" jdbcType="DATE"/>
</resultMap>
<sql id="Base_Column_List">
id
,
storage_id,
data_date,
year_time,
month_time,
day_time,
hour_time,
min_time,
power,
create_time
</sql>
<select id="selectOne" parameterType="pps.core.prediction.entity.StoragePredictedPowerDataView"
resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from storage_predicted_power_data
where
id=#{id}
</select>
<select id="selectList" parameterType="pps.core.prediction.entity.StoragePredictedPowerDataView"
resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from storage_predicted_power_data
where
id=#{id}
</select>
</mapper>
\ No newline at end of file
......@@ -33,8 +33,8 @@ public class DeployPpsAllApplication {
startup.enable(XJobFeature.class).config(new XJobServiceConf(WeatherJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(SpaceOptimizeLongJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(SpaceOptimizeMidJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(PlantPredictedPowerLongTermDataJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(SpaceCalibrationJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(SpaceOptimizeShortJob.class));
//startup.enable(XCloudHuaweiCseFeature.class);
startup.run(args);
}
......
......@@ -56,8 +56,9 @@ x.server.host=127.0.0.1
x.job.service=pps.core.task.job.TestJob,\
pps.core.task.job.SpaceOptimizeLongJob,\
pps.core.task.job.SpaceOptimizeMidJob,\
pps.core.task.job.WeatherJob,\
pps.core.task.job.PlantPredictedPowerLongTermDataJob
pps.core.task.job.SpaceCalibrationJob,\
pps.core.task.job.SpaceOptimizeShortJob,\
pps.core.task.job.WeatherJob
# redis
x.cache.type=@x.cache.type@
......
package app;
//import pps.core.common.job.CounterJob;
import pps.core.common.utils.CounterBuilder;
import pps.core.task.job.*;
import xstartup.base.XStartup;
......@@ -26,22 +27,22 @@ public class DeployPpsTaskApplication {
startup.config(new XServerConf(22062).naming("pps-task"))
.config(new XServiceConf("pps"));
startup.enable(XApiFeature.class)
.config(new XApiCookieConf("%4bH8s9&",43200));
.config(new XApiCookieConf("%4bH8s9&", 43200));
startup.enable(XCorsFeature.class);
startup.enable(XMybatisFeature.class);
startup.enable(XJobFeature.class).config(new XJobServiceConf(TestJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(WeatherJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(SpaceOptimizeLongJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(SpaceOptimizeMidJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(PlantPredictedPowerLongTermDataJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(SpaceCalibrationJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(SpaceOptimizeShortJob.class));
startup.enable(XRpcFeature.class);
startup.enable(XCloudHuaweiCseFeature.class)
.config(XCloudBundlesConf.with(
// XCloudBundle.naming("pps-workflow").addModule("pps", "cloud", "task"),
XCloudBundle.naming("pps-base-info").addModule("pps", "cloud", "system"),
XCloudBundle.naming("pps-base-info").addModule("pps", "cloud", "system"),
XCloudBundle.naming("pps-base-prediction").addModule("pps", "cloud", "prediction")));
XCloudBundle.naming("pps-base-info").addModule("pps", "cloud", "base")));
startup.run(args);
}
......
......@@ -10,8 +10,9 @@ pps.core.common.mq-config.ackImsMq=@pps.core.common.mq-config.ackImsMq@
x.job.service=pps.core.task.job.TestJob,\
pps.core.task.job.SpaceOptimizeLongJob,\
pps.core.task.job.SpaceOptimizeMidJob,\
pps.core.task.job.WeatherJob,\
pps.core.task.job.PlantPredictedPowerLongTermDataJob
pps.core.task.job.SpaceCalibrationJob,\
pps.core.task.job.SpaceOptimizeShortJob,\
pps.core.task.job.WeatherJob
#\uFFFD\uFFFD\u05BE\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD
x.log.level=@x.log.level@
......
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