package com.whyc.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.whyc.constant.WorkflowDischargePlanEnum;
|
import com.whyc.constant.WorkflowEnum;
|
import com.whyc.dto.Response;
|
import com.whyc.mapper.BattDischargePlanTempMapper;
|
import com.whyc.pojo.*;
|
import com.whyc.util.ActionUtil;
|
import com.whyc.util.DateUtil;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.context.annotation.Lazy;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import javax.annotation.Resource;
|
import javax.servlet.ServletContext;
|
import java.text.ParseException;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
@Service
|
public class BattDischargePlanTempService {
|
|
@Resource
|
private BattDischargePlanTempMapper mapper;
|
|
@Resource
|
private BaoJiGroupBattGroupService baoJiGroupBattGroupService;
|
|
@Autowired
|
private BaoJiGroupUserService baoJiGroupUserService;
|
|
@Autowired
|
private UserService userService;
|
|
@Autowired
|
@Lazy
|
private BattdischargePlanService planService;
|
|
@Autowired
|
private HolidaysService holidaysService;
|
|
@Autowired
|
@Lazy
|
private WorkflowMainService mainService;
|
|
@Autowired
|
@Lazy
|
private WorkflowLinkService linkService;
|
|
public void insertBatch(List<BattDischargePlanTemp> tempList) {
|
mapper.insertBatchSomeColumn(tempList);
|
}
|
|
public Response getReplaceBattGroupList(int num) {
|
List<BattDischargePlanTemp> tempList = mapper.selectList(null);
|
List<BattDischargePlanTemp> recommendList = new LinkedList<>();
|
List<BattDischargePlanTemp> list = new LinkedList<>();
|
BattDischargePlanTemp currentTemp = null;
|
for (BattDischargePlanTemp temp : tempList) {
|
if(temp.getId()==num){
|
currentTemp = temp;
|
break;
|
}
|
}
|
//同类型替换,并且不能是同一天的
|
for (BattDischargePlanTemp temp : tempList) {
|
assert currentTemp != null;
|
if(temp.getId()!=num &&temp.getDischargeStartTime().compareTo(currentTemp.getDischargeStartTime())!=0 && temp.getNodeStation().equals(currentTemp.getNodeStation())){
|
if(temp.getGroupId().equals(currentTemp.getGroupId())){ //同班组,推荐
|
recommendList.add(temp);
|
}else{
|
list.add(temp);
|
}
|
}
|
}
|
return new Response().setII(1,recommendList,list,null);
|
}
|
|
public Response getDisabledDischargeTime(int num) {
|
List<BattDischargePlanTemp> tempList = mapper.selectList(null);
|
BattDischargePlanTemp currentTemp = null;
|
for (BattDischargePlanTemp temp : tempList) {
|
if(temp.getId()==num){
|
currentTemp = temp;
|
break;
|
}
|
}
|
//不可用的时间,三种方式,层层筛选:1.当前电池组时间 2.其他 满足每天3个站点的时间 3.如果当前为节点站,再其他,存在节点站的时间
|
List<Date> disabledDischargeTimeList = new LinkedList<>();
|
Date dischargeStartTime = currentTemp.getDischargeStartTime();
|
disabledDischargeTimeList.add(dischargeStartTime);
|
Integer nodeStation = currentTemp.getNodeStation();
|
Map<Date, List<BattDischargePlanTemp>> dischargeMap = tempList.stream().collect(Collectors.groupingBy(BattDischargePlanTemp::getDischargeStartTime));
|
Set<Date> dates = dischargeMap.keySet();
|
for (Date date : dates) {
|
if(dischargeStartTime.compareTo(date)==0){
|
continue;
|
}
|
List<BattDischargePlanTemp> dailyTempList = dischargeMap.get(date);
|
if (dailyTempList.size()==3){
|
disabledDischargeTimeList.add(date);
|
}else{ //当天不足3个站点
|
if(nodeStation == 1){ //如果需要插入的站点是节点站,当天存在节点站,也不可用
|
for (BattDischargePlanTemp temp : dailyTempList) {
|
if(temp.getNodeStation()==1){
|
disabledDischargeTimeList.add(date);
|
break;
|
}
|
}
|
}
|
}
|
}
|
disabledDischargeTimeList = disabledDischargeTimeList.stream().sorted().collect(Collectors.toList());
|
return new Response().set(1,disabledDischargeTimeList);
|
}
|
|
public Response exchangeDischargeTime(int numOriginal, int numReplaced) {
|
BattDischargePlanTemp original = mapper.selectById(numOriginal);
|
BattDischargePlanTemp replaced = mapper.selectById(numReplaced);
|
|
UpdateWrapper<BattDischargePlanTemp> update = Wrappers.update();
|
update.set("discharge_starttime",replaced.getDischargeStartTime()).eq("id",numOriginal);
|
mapper.update(null,update);
|
|
UpdateWrapper<BattDischargePlanTemp> update2 = Wrappers.update();
|
update2.set("discharge_starttime",original.getDischargeStartTime()).eq("id",numReplaced);
|
mapper.update(null,update2);
|
return new Response().setII(1,"放电时间互换");
|
}
|
|
/**
|
* 原则:
|
* 0.每个站点只取第一组电池参与放电计划
|
* 1.每天最多1个节点站,每天最多3个放电站点
|
* 2.各班组尽量扁平,尽量保证各个组完全放电完成时间接近
|
* @return
|
* @param resetCapPercent
|
* @param startTimeStr
|
*/
|
@Transactional
|
public Response generateDischargePlan(Float resetCapPercent, String startTimeStr) throws ParseException {
|
List<BattDischargePlanTemp> tempList = new LinkedList<>();
|
Date startTime = DateUtil.YYYY_MM_DD_HH_MM_SS.parse(startTimeStr);
|
Calendar planTime = Calendar.getInstance();
|
planTime.setTime(startTime);
|
//一年度只能生成一次审核通过的放电计划,校验
|
int planYear = planTime.get(Calendar.YEAR);
|
BattDischargePlanTemp tempDB = getValidOneByYear(planYear);
|
if(tempDB!=null){
|
return new Response().set(1,false,"当前年度已存在计划审批清单,无法重复生成");
|
}
|
//查询所有可用的组以及每个组的站点
|
//planTime校验,避开节假日和周六日
|
planTime = checkAndGetPlanTime(planTime);
|
List<BaojiGroupBattGroup> baoJiGroupListWithinBattGroupList = baoJiGroupBattGroupService.getBaoJiGroupListWithinBattGroupList();
|
//List<BattdischargePlan> planList = new LinkedList<>();
|
List<Battinf> planList = new LinkedList<>();
|
int prePlanSize = 3;
|
int planSize = 0;
|
while (prePlanSize != planSize && baoJiGroupListWithinBattGroupList.size()>0) { //当相等时,说明每天计划已经为0,计划完结
|
prePlanSize = planSize;
|
//List<BattdischargePlan> subPlanList = getDischargePlanList(baoJiGroupListWithinBattGroupList,planTime);
|
List<Battinf> subPlanList = getDischargePlanList2(baoJiGroupListWithinBattGroupList,planTime);
|
//添加到电池放电计划List
|
planList.addAll(subPlanList);
|
//baoJiGroupListWithinBattGroupList重置为当前baoJiGroupListWithinBattGroupList-battGroupList
|
|
//按日递增计划时间,同时避开节假日和周六日
|
planTime.add(Calendar.DAY_OF_MONTH,1);
|
planTime = checkAndGetPlanTime(planTime);
|
planSize = planList.size();
|
|
//整理数据,为下一天做放电计划做准备
|
//剔除已经不存在的班组
|
for (int i = baoJiGroupListWithinBattGroupList.size() - 1; i >= 0; i--) {
|
if (baoJiGroupListWithinBattGroupList.get(i).getBattGroupList().size() == 0) {
|
baoJiGroupListWithinBattGroupList.remove(i);
|
}
|
}
|
//算法方式1:可以本次安排了放电计划的班组,排序到最后,其他瞬移.
|
//算法方式2:滚动班组顺序,保证扁平.原第一顺位,变为最后顺位
|
List<Integer> existsBaojiGroupList = baoJiGroupListWithinBattGroupList.stream().map(BaojiGroupBattGroup::getBaojiGroupId).collect(Collectors.toList());
|
List<Integer> planedGroupIdExistsList = new LinkedList<>();
|
for (Battinf battinf : subPlanList) {
|
int baojiGroupId = battinf.getNum();
|
if(existsBaojiGroupList.contains(baojiGroupId)) {
|
planedGroupIdExistsList.add(baojiGroupId);
|
}
|
}
|
int planedGroupIdExistsListSize = planedGroupIdExistsList.size();
|
int baoJiGroupListSize = baoJiGroupListWithinBattGroupList.size();
|
if(planedGroupIdExistsListSize >0) {
|
if (baoJiGroupListSize >1){//班组数大于1组时调整排序才有意义
|
//班组<=3时才可能执行的调整逻辑,且执行过上次计划分配后的班组仍都存在可分配站点
|
//上次计划分配后的班组和当时存在的班组完全相同
|
if(baoJiGroupListSize == planedGroupIdExistsListSize) {
|
//如果已经计划且还有站点需要放电的班组数量 = 需要放电的班组数量
|
baoJiGroupListWithinBattGroupList = adjustListMethod2(baoJiGroupListWithinBattGroupList);
|
}else{
|
//必然是需要放电的班组数量>已经计划且还有站点需要放电的班组数量
|
adjustListMethod1(baoJiGroupListWithinBattGroupList, planedGroupIdExistsList);
|
}
|
}
|
}
|
//算法方式2:滚动班组顺序,保证扁平.原第一顺位,变为最后顺位
|
//baoJiGroupListWithinBattGroupList = adjustListMethod2(baoJiGroupListWithinBattGroupList, firstBaojiGroupId);
|
|
}
|
|
Date date = new Date();
|
int userId = ActionUtil.getUser().getUId().intValue();
|
for (Battinf battinf : planList) {
|
BattDischargePlanTemp temp = new BattDischargePlanTemp();
|
temp.setBattGroupId(battinf.getBattGroupId());
|
temp.setBattGroupName(battinf.getBattGroupName());
|
temp.setStationId(battinf.getStationId());
|
temp.setStationName(battinf.getStationName());
|
temp.setNodeStation(battinf.getNodeStation());
|
temp.setGroupId(battinf.getNum().longValue());
|
temp.setGroupName(battinf.getInstallUser());
|
temp.setDischargeStartTime(battinf.getDischargeStartTime());
|
temp.setCreateTime(date);
|
temp.setMonCapStd(battinf.getMonCapStd());
|
temp.setMonVolStd(battinf.getMonVolStd());
|
temp.setCapPercent(resetCapPercent);
|
temp.setCreateUserId(userId);
|
temp.setSubmitStatus(0);
|
tempList.add(temp);
|
}
|
//存入临时表
|
if(tempList.size()>0) {
|
insertBatch(tempList);
|
return new Response().setII(1,true,tempList,null);
|
}else{
|
return new Response().set(1,false,"未找到需要执行放电计划的机房");
|
}
|
|
|
}
|
|
/**查看放电临时表中审核状态有效(包含审批中,审批通过) */
|
private BattDischargePlanTemp getValidOneByYear(int planYear) {
|
return mapper.getValidOneByYear(planYear);
|
}
|
|
/**校验日期,避开节假日和周六日*/
|
private Calendar checkAndGetPlanTime(Calendar planTime) throws ParseException {
|
Calendar planTimeOnce = checkAndGetOnce(planTime);
|
while (true){
|
Calendar planTimeTwice = checkAndGetOnce(planTimeOnce);
|
if(planTimeTwice.compareTo(planTimeOnce) == 0) {
|
break;
|
}else{
|
planTimeOnce = planTimeTwice;
|
}
|
}
|
return planTimeOnce;
|
}
|
|
private Calendar checkAndGetOnce(Calendar planTime) throws ParseException {
|
Calendar planTimeDo = Calendar.getInstance();
|
planTimeDo.setTime(planTime.getTime());
|
int dayOfWeek = planTimeDo.get(Calendar.DAY_OF_WEEK);
|
int saturday = Calendar.SATURDAY;
|
int sunday = Calendar.SUNDAY;
|
//周六日的话,就推到星期一
|
if(dayOfWeek == saturday){
|
planTimeDo.add(Calendar.DAY_OF_MONTH,2);
|
}else if(dayOfWeek == sunday){
|
planTimeDo.add(Calendar.DAY_OF_MONTH,1);
|
}
|
//获取节假日
|
int year = planTimeDo.get(Calendar.YEAR);
|
List<Holidays> holidays = holidaysService.getListByYear(year);
|
List<Date> holidaysDateList = holidays.stream().map(Holidays::getDay).collect(Collectors.toList());
|
while (true){
|
if(holidaysDateList.contains(planTimeDo.getTime())){
|
planTimeDo.add(Calendar.DAY_OF_MONTH,1);
|
}else{
|
break;
|
}
|
}
|
return planTimeDo;
|
}
|
|
/**
|
* 算法方式1:可以本次安排了放电计划的班组,排序到最后,其他瞬移.
|
* @param baoJiGroupListWithinBattGroupList n
|
* @param planedGroupIdExistsList n
|
* @return
|
*/
|
private List<BaojiGroupBattGroup> adjustListMethod1(List<BaojiGroupBattGroup> baoJiGroupListWithinBattGroupList, List<Integer> planedGroupIdExistsList) {
|
List<BaojiGroupBattGroup> planedGroupIdExistsListWithBattGroupList = new LinkedList<>();
|
for (int i = baoJiGroupListWithinBattGroupList.size()-1; i >= 0; i--) {
|
Integer baojiGroupId = baoJiGroupListWithinBattGroupList.get(i).getBaojiGroupId();
|
if (planedGroupIdExistsList.contains(baojiGroupId)){
|
planedGroupIdExistsListWithBattGroupList.add(baoJiGroupListWithinBattGroupList.get(i));
|
baoJiGroupListWithinBattGroupList.remove(i);
|
}
|
}
|
for (int i = planedGroupIdExistsListWithBattGroupList.size()-1; i >= 0; i--) {
|
baoJiGroupListWithinBattGroupList.add(planedGroupIdExistsListWithBattGroupList.get(i));
|
}
|
return baoJiGroupListWithinBattGroupList;
|
}
|
|
/**
|
* 算法方式2:滚动班组顺序,保证扁平.原第一顺位,变为最后顺位
|
* @param baoJiGroupListWithinBattGroupList 要调整顺序的列表
|
* @return
|
*/
|
private List<BaojiGroupBattGroup> adjustListMethod2(List<BaojiGroupBattGroup> baoJiGroupListWithinBattGroupList) {
|
if (baoJiGroupListWithinBattGroupList.size() > 1) { //班组数大于1组时滚动逻辑才有意义
|
List<BaojiGroupBattGroup> newSequenceList = new LinkedList<>();
|
for (int i = 0; i < baoJiGroupListWithinBattGroupList.size(); i++) {
|
if (i != baoJiGroupListWithinBattGroupList.size() - 1) {
|
newSequenceList.add(baoJiGroupListWithinBattGroupList.get(i + 1));
|
} else {
|
newSequenceList.add(baoJiGroupListWithinBattGroupList.get(0));
|
}
|
}
|
baoJiGroupListWithinBattGroupList = newSequenceList;
|
}
|
return baoJiGroupListWithinBattGroupList;
|
}
|
|
/**
|
* 根据逻辑获取一天的
|
* 模型1:
|
* 2组2非节(包含本组情况,只是包含本组情况优先级低)
|
* 1组2非节(包含本组情况,只是包含本组情况优先级低)
|
* 1组1节 1组1非节(包含本组情况,只是包含本组情况优先级低)
|
* 0非节
|
*
|
* 模型2:
|
*
|
* 3组3非节
|
* 2组3非节
|
* 0组1节 1组3非节
|
* 2组2非节
|
* 1组2非节
|
* 1组1非节
|
*
|
*
|
*
|
* @param baoJiGroupListWithinBattGroupList
|
* @param planTime
|
* @return
|
*/
|
private List<BattdischargePlan> getDischargePlanList(List<BaojiGroupBattGroup> baoJiGroupListWithinBattGroupList, Calendar planTime) {
|
List<BattdischargePlan> planList = new LinkedList<>();
|
int nodeStationExists = 0;
|
for (int i = 0; i < baoJiGroupListWithinBattGroupList.size(); i++) {
|
//一条记录就是一组,组内包含了所有性质的站点
|
//先确定是否存在节点,存在则加入到计划. 没有则执行没有节点的模型
|
BaojiGroupBattGroup groupWithBattStationList = baoJiGroupListWithinBattGroupList.get(i);
|
List<Battinf> battStationList = groupWithBattStationList.getBattGroupList();
|
for (int j = 0; j < battStationList.size(); j++) {
|
Battinf battinf = battStationList.get(j);
|
if(battinf.getNodeStation()==1){
|
//找到节点
|
BattdischargePlan plan = new BattdischargePlan();
|
plan.setBattgroupid(battinf.getBattGroupId());
|
plan.setBattGroupName(battinf.getBattGroupName());
|
plan.setNodeStation(1);
|
plan.setNum(groupWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
plan.setNote(String.valueOf(i));//记录计划内的组号对应的索引
|
planList.add(plan);
|
nodeStationExists = 1;
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList.remove(j);
|
baoJiGroupListWithinBattGroupList.get(i).setBattGroupList(battStationList);
|
break; //当前组当前排站点级别降低,只要其他组能排,不会再选择当前组.
|
}
|
}
|
//判断是否找到节点,找到节点则退出此次遍历
|
if(nodeStationExists == 1){
|
break;
|
}
|
}
|
|
//判断是否找到节点,找到则执行模型1
|
if(nodeStationExists == 1){
|
//节点在的组优先级降低
|
Integer planedBaoJiGroupId = planList.get(0).getNum();
|
//模型1-1是否成立
|
for (int i = 0; i < baoJiGroupListWithinBattGroupList.size(); i++) {
|
BaojiGroupBattGroup groupWithBattStationList = baoJiGroupListWithinBattGroupList.get(i);
|
Integer baojiGroupId = groupWithBattStationList.getBaojiGroupId();
|
if(planedBaoJiGroupId.equals(baojiGroupId)){
|
continue; //先看能否满足2组2非节(非本组)
|
}
|
List<Battinf> battStationList = groupWithBattStationList.getBattGroupList();
|
for (int j = 0; j < battStationList.size(); j++) {
|
Battinf battinf = battStationList.get(j);
|
if(battinf.getNodeStation()==0){
|
BattdischargePlan plan = new BattdischargePlan();
|
plan.setBattgroupid(battinf.getBattGroupId());
|
plan.setBattGroupName(battinf.getBattGroupName());
|
plan.setNodeStation(0);
|
plan.setNum(groupWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
plan.setNote(String.valueOf(i));//记录计划内的组号对应的索引
|
planList.add(plan);
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList.remove(j);
|
baoJiGroupListWithinBattGroupList.get(i).setBattGroupList(battStationList);
|
break; //当前组当前排站点级别降低,只要其他组能排,不会再选择当前组.
|
}
|
}
|
//遍历过程中,查看计划是否满足3个站点,已经满足则提前结束计划分配
|
if(planList.size()==3){
|
break;
|
}
|
}
|
//遍历完毕,查看计划是否满足3个站点
|
//如果不满足,则把已排组的站点继续允许分配,优先遍历非节点站所在组
|
//如果还不满足,则继续分配,允许遍历节点站所在组
|
int size = planList.size();
|
if(size!=3){
|
//如果计划站点数是2,说明计划1为节点站,计划2为非节点站,优先计划2所在非节点站所在组去分配
|
int notNodeStationExists = 0;
|
if(size==2){
|
int indexNotNode = Integer.parseInt(planList.get(1).getNote());
|
BaojiGroupBattGroup groupWithBattStationList = baoJiGroupListWithinBattGroupList.get(indexNotNode);
|
List<Battinf> battStationList = groupWithBattStationList.getBattGroupList();
|
for (int j = 0; j < battStationList.size(); j++) {
|
Battinf battinf = battStationList.get(j);
|
if(battinf.getNodeStation()==0){
|
BattdischargePlan plan = new BattdischargePlan();
|
plan.setBattgroupid(battinf.getBattGroupId());
|
plan.setBattGroupName(battinf.getBattGroupName());
|
plan.setNodeStation(0);
|
plan.setNum(groupWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
planList.add(plan);
|
notNodeStationExists = 1;
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList.remove(j);
|
baoJiGroupListWithinBattGroupList.get(indexNotNode).setBattGroupList(battStationList);
|
break;//找到可分配的,终止
|
}
|
}
|
if(notNodeStationExists != 1){ //在非节点站所在组没找到其他非节点,只能从节点站所在组去分配
|
int indexNode = Integer.parseInt(planList.get(0).getNote());
|
BaojiGroupBattGroup groupHavingNodeWithBattStationList = baoJiGroupListWithinBattGroupList.get(indexNode);
|
List<Battinf> battStationList2 = groupHavingNodeWithBattStationList.getBattGroupList();
|
for (int j = 0; j < battStationList2.size(); j++) {
|
Battinf battinf = battStationList2.get(j);
|
if(battinf.getNodeStation()==0){
|
BattdischargePlan plan = new BattdischargePlan();
|
plan.setBattgroupid(battinf.getBattGroupId());
|
plan.setBattGroupName(battinf.getBattGroupName());
|
plan.setNodeStation(0);
|
plan.setNum(groupHavingNodeWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
planList.add(plan);
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList.remove(j);
|
baoJiGroupListWithinBattGroupList.get(indexNotNode).setBattGroupList(battStationList);
|
break;//找到可分配的,终止
|
}
|
}
|
}
|
}
|
//如果计划站点数是1,说明只有1个节点站,继续从节点站所在组去分配
|
else{
|
int indexNode = Integer.parseInt(planList.get(0).getNote());
|
BaojiGroupBattGroup groupHavingNodeWithBattStationList = baoJiGroupListWithinBattGroupList.get(indexNode);
|
List<Battinf> battStationList2 = groupHavingNodeWithBattStationList.getBattGroupList();
|
List<Integer> indexRemoveList = new LinkedList<>();
|
for (int j = 0; j < battStationList2.size(); j++) {
|
Battinf battinf = battStationList2.get(j);
|
if(battinf.getNodeStation()==0){
|
BattdischargePlan plan = new BattdischargePlan();
|
plan.setBattgroupid(battinf.getBattGroupId());
|
plan.setBattGroupName(battinf.getBattGroupName());
|
plan.setNodeStation(0);
|
plan.setNum(groupHavingNodeWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
planList.add(plan);
|
indexRemoveList.add(j);
|
if(planList.size()==3) {
|
break;//找到可分配的,终止
|
}
|
}
|
}
|
for (int i = indexRemoveList.size()-1; i >=0; i--) {
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList2.remove(indexRemoveList.get(i).intValue());
|
//baoJiGroupListWithinBattGroupList.get(indexNode).setBattGroupList(battStationList2);
|
}
|
}
|
}
|
}
|
//未找到节点,执行模型2
|
else{
|
for (int i = 0; i < baoJiGroupListWithinBattGroupList.size(); i++) {
|
BaojiGroupBattGroup groupWithBattStationList = baoJiGroupListWithinBattGroupList.get(i);
|
List<Battinf> battStationList = groupWithBattStationList.getBattGroupList();
|
List<Integer> indexRemoveList = new LinkedList<>();
|
for (int j = 0; j < battStationList.size(); j++) {
|
Battinf battinf = battStationList.get(j);
|
BattdischargePlan plan = new BattdischargePlan();
|
plan.setBattgroupid(battinf.getBattGroupId());
|
plan.setBattGroupName(battinf.getBattGroupName());
|
plan.setNodeStation(0);
|
plan.setNum(groupWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
plan.setNote(String.valueOf(i));//记录计划内的组号对应的索引
|
planList.add(plan);
|
indexRemoveList.add(j);
|
if(planList.size()==3) {
|
break;//找到可分配的,终止
|
}
|
}
|
for (int i1 = indexRemoveList.size()-1; i1 >=0; i1--) {
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList.remove(indexRemoveList.get(i1).intValue());
|
//baoJiGroupListWithinBattGroupList.get(i).setBattGroupList(battStationList);
|
}
|
}
|
//遍历完毕,查看计划是否满足3个站点
|
//如果不满足,则把已排组的站点继续允许分配,遍历非节点站所在组
|
//如果存在1组,说明后续也只能从这1组获取,反复遍历;如果存在2组,那再遍历完一次后无需再遍历,因为如果存在则已经满足要求
|
int size = planList.size();
|
if(size!=3) {
|
if(size==1) { //存在1组,那说明后续也只能从这1组中获取
|
for (int i = 0; i < planList.size(); i++) {
|
BattdischargePlan existsPlan = planList.get(i);
|
int index = Integer.parseInt(existsPlan.getNote());
|
BaojiGroupBattGroup groupWithBattStationList = baoJiGroupListWithinBattGroupList.get(index);
|
List<Battinf> battStationList = groupWithBattStationList.getBattGroupList();
|
List<Integer> indexRemoveList = new LinkedList<>();
|
for (int j = 0; j < battStationList.size(); j++) {
|
Battinf battinf = battStationList.get(j);
|
if (battinf.getNodeStation() == 0) {
|
BattdischargePlan plan = new BattdischargePlan();
|
plan.setBattgroupid(battinf.getBattGroupId());
|
plan.setBattGroupName(battinf.getBattGroupName());
|
plan.setNodeStation(0);
|
plan.setNum(groupWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
indexRemoveList.add(j);
|
planList.add(plan);
|
if(planList.size()==3){
|
break;//找到可分配的,终止
|
}
|
}
|
}
|
//已经加入到计划组的,从原纪录中剔除
|
for (int i1 = indexRemoveList.size()-1; i1 >=0; i1--) {
|
battStationList.remove(indexRemoveList.get(i1).intValue());
|
baoJiGroupListWithinBattGroupList.get(index).setBattGroupList(battStationList);
|
}
|
}
|
}else{ //已经存在2组
|
for (int i = 0; i < planList.size(); i++) {
|
BattdischargePlan existsPlan = planList.get(i);
|
BaojiGroupBattGroup groupWithBattStationList = baoJiGroupListWithinBattGroupList.get(Integer.parseInt(existsPlan.getNote()));
|
List<Battinf> battStationList = groupWithBattStationList.getBattGroupList();
|
for (int j = 0; j < battStationList.size(); j++) {
|
Battinf battinf = battStationList.get(j);
|
if (battinf.getNodeStation() == 0) {
|
BattdischargePlan plan = new BattdischargePlan();
|
plan.setBattgroupid(battinf.getBattGroupId());
|
plan.setBattGroupName(battinf.getBattGroupName());
|
plan.setNodeStation(0);
|
plan.setNum(groupWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
planList.add(plan);
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList.remove(j);
|
baoJiGroupListWithinBattGroupList.get(Integer.parseInt(existsPlan.getNote())).setBattGroupList(battStationList);
|
break;//找到可分配的,终止
|
}
|
}
|
}
|
//完结
|
}
|
}
|
}
|
|
return planList;
|
}
|
|
private List<Battinf> getDischargePlanList2(List<BaojiGroupBattGroup> baoJiGroupListWithinBattGroupList, Calendar planTime) {
|
List<Battinf> planList = new LinkedList<>();
|
int nodeStationExists = 0;
|
for (int i = 0; i < baoJiGroupListWithinBattGroupList.size(); i++) {
|
//一条记录就是一组,组内包含了所有性质的站点
|
//先确定是否存在节点,存在则加入到计划. 没有则执行没有节点的模型
|
BaojiGroupBattGroup groupWithBattStationList = baoJiGroupListWithinBattGroupList.get(i);
|
List<Battinf> battStationList = groupWithBattStationList.getBattGroupList();
|
for (int j = 0; j < battStationList.size(); j++) {
|
Battinf battinf = battStationList.get(j);
|
if(battinf.getNodeStation()==1){
|
//找到节点
|
battinf.setDischargeStartTime(planTime.getTime());;
|
battinf.setNum(groupWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
battinf.setInstallUser(groupWithBattStationList.getBaojiGroupName());
|
battinf.setNote(String.valueOf(i));//记录计划内的组号对应的索引
|
planList.add(battinf);
|
nodeStationExists = 1;
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList.remove(j);
|
baoJiGroupListWithinBattGroupList.get(i).setBattGroupList(battStationList);
|
break; //当前组当前排站点级别降低,只要其他组能排,不会再选择当前组.
|
}
|
}
|
//判断是否找到节点,找到节点则退出此次遍历
|
if(nodeStationExists == 1){
|
break;
|
}
|
}
|
|
//判断是否找到节点,找到则执行模型1
|
if(nodeStationExists == 1){
|
//节点在的组优先级降低
|
Integer planedBaoJiGroupId = planList.get(0).getNum();
|
//模型1-1是否成立
|
for (int i = 0; i < baoJiGroupListWithinBattGroupList.size(); i++) {
|
BaojiGroupBattGroup groupWithBattStationList = baoJiGroupListWithinBattGroupList.get(i);
|
Integer baojiGroupId = groupWithBattStationList.getBaojiGroupId();
|
if(planedBaoJiGroupId.equals(baojiGroupId)){
|
continue; //先看能否满足2组2非节(非本组)
|
}
|
List<Battinf> battStationList = groupWithBattStationList.getBattGroupList();
|
for (int j = 0; j < battStationList.size(); j++) {
|
Battinf battinf = battStationList.get(j);
|
if(battinf.getNodeStation()==0){
|
battinf.setDischargeStartTime(planTime.getTime());;
|
battinf.setNum(groupWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
battinf.setInstallUser(groupWithBattStationList.getBaojiGroupName());
|
battinf.setNote(String.valueOf(i));//记录计划内的组号对应的索引
|
planList.add(battinf);
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList.remove(j);
|
baoJiGroupListWithinBattGroupList.get(i).setBattGroupList(battStationList);
|
break; //当前组当前排站点级别降低,只要其他组能排,不会再选择当前组.
|
}
|
}
|
//遍历过程中,查看计划是否满足3个站点,已经满足则提前结束计划分配
|
if(planList.size()==3){
|
break;
|
}
|
}
|
//遍历完毕,查看计划是否满足3个站点
|
//如果不满足,则把已排组的站点继续允许分配,优先遍历非节点站所在组
|
//如果还不满足,则继续分配,允许遍历节点站所在组
|
int size = planList.size();
|
if(size!=3){
|
//如果计划站点数是2,说明计划1为节点站,计划2为非节点站,优先计划2所在非节点站所在组去分配
|
int notNodeStationExists = 0;
|
if(size==2){
|
int indexNotNode = Integer.parseInt(planList.get(1).getNote());
|
BaojiGroupBattGroup groupWithBattStationList = baoJiGroupListWithinBattGroupList.get(indexNotNode);
|
List<Battinf> battStationList = groupWithBattStationList.getBattGroupList();
|
for (int j = 0; j < battStationList.size(); j++) {
|
Battinf battinf = battStationList.get(j);
|
if(battinf.getNodeStation()==0){
|
battinf.setDischargeStartTime(planTime.getTime());;
|
battinf.setNum(groupWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
battinf.setInstallUser(groupWithBattStationList.getBaojiGroupName());
|
planList.add(battinf);
|
notNodeStationExists = 1;
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList.remove(j);
|
baoJiGroupListWithinBattGroupList.get(indexNotNode).setBattGroupList(battStationList);
|
break;//找到可分配的,终止
|
}
|
}
|
if(notNodeStationExists != 1){ //在非节点站所在组没找到其他非节点,只能从节点站所在组去分配
|
int indexNode = Integer.parseInt(planList.get(0).getNote());
|
BaojiGroupBattGroup groupHavingNodeWithBattStationList = baoJiGroupListWithinBattGroupList.get(indexNode);
|
List<Battinf> battStationList2 = groupHavingNodeWithBattStationList.getBattGroupList();
|
for (int j = 0; j < battStationList2.size(); j++) {
|
Battinf battinf = battStationList2.get(j);
|
if(battinf.getNodeStation()==0){
|
battinf.setDischargeStartTime(planTime.getTime());;
|
battinf.setNum(groupHavingNodeWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
battinf.setInstallUser(groupHavingNodeWithBattStationList.getBaojiGroupName());
|
planList.add(battinf);
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList.remove(j);
|
baoJiGroupListWithinBattGroupList.get(indexNotNode).setBattGroupList(battStationList);
|
break;//找到可分配的,终止
|
}
|
}
|
}
|
}
|
//如果计划站点数是1,说明只有1个节点站,继续从节点站所在组去分配
|
else{
|
int indexNode = Integer.parseInt(planList.get(0).getNote());
|
BaojiGroupBattGroup groupHavingNodeWithBattStationList = baoJiGroupListWithinBattGroupList.get(indexNode);
|
List<Battinf> battStationList2 = groupHavingNodeWithBattStationList.getBattGroupList();
|
List<Integer> indexRemoveList = new LinkedList<>();
|
for (int j = 0; j < battStationList2.size(); j++) {
|
Battinf battinf = battStationList2.get(j);
|
if(battinf.getNodeStation()==0){
|
battinf.setDischargeStartTime(planTime.getTime());;
|
battinf.setNum(groupHavingNodeWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
battinf.setInstallUser(groupHavingNodeWithBattStationList.getBaojiGroupName());
|
planList.add(battinf);
|
indexRemoveList.add(j);
|
if(planList.size()==3) {
|
break;//找到可分配的,终止
|
}
|
}
|
}
|
for (int i = indexRemoveList.size()-1; i >=0; i--) {
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList2.remove(indexRemoveList.get(i).intValue());
|
//baoJiGroupListWithinBattGroupList.get(indexNode).setBattGroupList(battStationList2);
|
}
|
}
|
}
|
}
|
//未找到节点,执行模型2
|
else{
|
for (int i = 0; i < baoJiGroupListWithinBattGroupList.size(); i++) {
|
BaojiGroupBattGroup groupWithBattStationList = baoJiGroupListWithinBattGroupList.get(i);
|
List<Battinf> battStationList = groupWithBattStationList.getBattGroupList();
|
List<Integer> indexRemoveList = new LinkedList<>();
|
for (int j = 0; j < battStationList.size(); j++) {
|
Battinf battinf = battStationList.get(j);
|
battinf.setDischargeStartTime(planTime.getTime());;
|
battinf.setNum(groupWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
battinf.setInstallUser(groupWithBattStationList.getBaojiGroupName());
|
battinf.setNote(String.valueOf(i));//记录计划内的组号对应的索引
|
planList.add(battinf);
|
indexRemoveList.add(j);
|
|
break;//找到可分配的,终止
|
}
|
for (int i1 = indexRemoveList.size()-1; i1 >=0; i1--) {
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList.remove(indexRemoveList.get(i1).intValue());
|
//baoJiGroupListWithinBattGroupList.get(i).setBattGroupList(battStationList);
|
}
|
if(planList.size()==3){
|
break;
|
}
|
}
|
//遍历完毕,查看计划是否满足3个站点
|
//如果不满足,则把已排组的站点继续允许分配,遍历非节点站所在组
|
//如果存在1组,说明后续也只能从这1组获取,反复遍历;如果存在2组,那再遍历完一次后无需再遍历,因为如果存在则已经满足要求
|
int size = planList.size();
|
if(size!=3) {
|
if(size==1) { //存在1组,那说明后续也只能从这1组中获取
|
Battinf existsPlan = planList.get(0);
|
int index = Integer.parseInt(existsPlan.getNote());
|
BaojiGroupBattGroup groupWithBattStationList = baoJiGroupListWithinBattGroupList.get(index);
|
List<Battinf> battStationList = groupWithBattStationList.getBattGroupList();
|
List<Integer> indexRemoveList = new LinkedList<>();
|
for (int j = 0; j < battStationList.size(); j++) {
|
Battinf battinf = battStationList.get(j);
|
if (battinf.getNodeStation() == 0) {
|
battinf.setDischargeStartTime(planTime.getTime());;
|
battinf.setNum(groupWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
battinf.setInstallUser(groupWithBattStationList.getBaojiGroupName());
|
planList.add(battinf);
|
indexRemoveList.add(j);
|
if(planList.size()==3){
|
break;//找到可分配的,终止
|
}
|
}
|
}
|
//已经加入到计划组的,从原纪录中剔除
|
for (int i1 = indexRemoveList.size()-1; i1 >=0; i1--) {
|
battStationList.remove(indexRemoveList.get(i1).intValue());
|
baoJiGroupListWithinBattGroupList.get(index).setBattGroupList(battStationList);
|
}
|
|
}else{ //已经存在2组
|
for (int i = 0; i < planList.size(); i++) {
|
Battinf existsPlan = planList.get(i);
|
BaojiGroupBattGroup groupWithBattStationList = baoJiGroupListWithinBattGroupList.get(Integer.parseInt(existsPlan.getNote()));
|
List<Battinf> battStationList = groupWithBattStationList.getBattGroupList();
|
for (int j = 0; j < battStationList.size(); j++) {
|
Battinf battinf = battStationList.get(j);
|
if (battinf.getNodeStation() == 0) {
|
battinf.setDischargeStartTime(planTime.getTime());;
|
battinf.setNum(groupWithBattStationList.getBaojiGroupId());//记录计划内的组号
|
battinf.setInstallUser(groupWithBattStationList.getBaojiGroupName());
|
planList.add(battinf);
|
//已经加入到计划组的,从原纪录中剔除
|
battStationList.remove(j);
|
baoJiGroupListWithinBattGroupList.get(Integer.parseInt(existsPlan.getNote())).setBattGroupList(battStationList);
|
break;//找到可分配的,终止
|
}
|
}
|
if(planList.size()==3){
|
break;
|
}
|
}
|
//完结
|
}
|
}
|
}
|
|
return planList;
|
}
|
|
@Transactional
|
public Response deleteDischargePlanTemp(String startTimeStr) throws ParseException {
|
Date startTime = DateUtil.YYYY_MM_DD_HH_MM_SS.parse(startTimeStr);
|
Calendar planTime = Calendar.getInstance();
|
planTime.setTime(startTime);
|
//一年只会有一个计划,删除年度的计划. 审核通过的不能删除
|
int planYear = planTime.get(Calendar.YEAR);
|
UpdateWrapper<BattDischargePlanTemp> update = Wrappers.update();
|
update.eq("Year(discharge_start_time)",planYear).ne("approve_status",1);
|
int deleteCount = mapper.delete(update);
|
if(deleteCount>0){
|
return new Response().set(1,true, "删除完成");
|
}else {
|
return new Response().set(1,false, "删除的数据已审核通过,无法删除");
|
}
|
}
|
|
@Transactional
|
public Response updateListAndSubmit(List<BattDischargePlanTemp> list, String taskDesc) {
|
int userId = ActionUtil.getUser().getUId().intValue();
|
Date now = new Date();
|
//1.提交到单据审批流程
|
WorkflowMain main = new WorkflowMain();
|
String orderId = mainService.getNextOrderId("FDJH");
|
String title = "放电计划审批单-"+DateUtil.YYYY_MM_DD_HH_MM_SS_UNION;
|
Integer mainStatus = WorkflowEnum.MAIN_STATUS_DEALING.getValue();
|
Integer mainType = WorkflowEnum.MAIN_TYPE_DISCHARGE_PLAN.getValue();
|
main.setOrderId(orderId);
|
main.setTitle(title);
|
main.setTaskDesc(taskDesc);
|
main.setCreateUserId(userId);
|
main.setCreateTime(now);
|
main.setBeginTime(now);
|
main.setStatus(mainStatus);
|
main.setType(mainType);
|
mainService.add(main);
|
//内存中去除已插入数据库的单号
|
ServletContext application = ActionUtil.getApplication();
|
List<String> orderIdList = (List<String>) application.getAttribute("orderIdList");
|
//校验是否去除
|
boolean remove = orderIdList.remove(orderId);
|
if(!remove){
|
System.err.println("没有去除掉!!!!!!!!!!!!!");
|
}
|
application.setAttribute("orderIdList",orderIdList);
|
|
//查询包机组对应的班组长,并在单据节点表添加记录
|
Set<Long> baoJiGroupIds = list.stream().collect(Collectors.groupingBy(BattDischargePlanTemp::getGroupId)).keySet();
|
List<UserInf> userInfList = baoJiGroupUserService.getUserListByRole(baoJiGroupIds,1);
|
List<WorkflowLink> links = new LinkedList<>();
|
for (UserInf userInf : userInfList) {
|
WorkflowLink link = new WorkflowLink();
|
link.setMainId(main.getId());
|
link.setParentId(0);
|
link.setProcessLevel(WorkflowDischargePlanEnum.PROCESS_MANAGER1SIGN.getProcessLevel());
|
link.setProcessLevelName(WorkflowDischargePlanEnum.PROCESS_MANAGER1SIGN.getProcessLevelName());
|
link.setCreateTime(now);
|
link.setDealUserId(userInf.getUId().intValue());
|
link.setDealType(WorkflowEnum.TYPE_DELIVER.getValue());
|
link.setDealDesc(taskDesc);
|
link.setStatus(WorkflowEnum.STATUS_DEALING.getValue());
|
|
links.add(link);
|
}
|
linkService.addBatch(links);
|
|
//2.更新临时表放电计划数据
|
list.forEach(item-> {
|
item.setCreateTime(now);
|
item.setMainId(main.getId());
|
});
|
updateList(list);
|
|
return new Response().setII(1,"提交完成");
|
}
|
|
public void updateList(List<BattDischargePlanTemp> list) {
|
//化整为零,避免sql拼接太长导致无法执行
|
int step = 20;
|
for (int i = 0; i < list.size(); i = i+step) {
|
if(i+step<list.size()){
|
mapper.updateList(list.subList(i, i + step));
|
}else {
|
mapper.updateList(list.subList(i, list.size()));
|
}
|
}
|
}
|
|
|
/**
|
* 临时表审批状态变为已审批
|
*
|
* @param approveStatus
|
* @param approveReason
|
* @param tempList
|
* @return
|
*/
|
@Transactional
|
public Response updateApproveDischargePlan(int approveStatus, String approveReason, List<BattDischargePlanTemp> tempList) {
|
UserInf user = ActionUtil.getUser();
|
BattDischargePlanTemp temp = tempList.get(0);
|
Date createTime = temp.getCreateTime();
|
Integer createUserId = temp.getCreateUserId();
|
updateApproveStatus(approveStatus,approveReason,createTime,createUserId,user.getUId().intValue());
|
|
if(approveStatus==1) {
|
planService.insertConfirmDischargePlan(tempList);
|
}
|
return new Response().setII(1,"审核完成");
|
}
|
|
|
public void updateApproveStatus(int approveStatus, String approveReason, Date createTime, Integer createUserId, int approveUserId) {
|
UpdateWrapper<BattDischargePlanTemp> update = Wrappers.update();
|
update.set("approve_status",approveStatus).set("approve_reason",approveReason).set("approve_time",new Date()).set("approve_user_id",approveUserId)
|
.eq("create_time",createTime).eq("create_user_id",createUserId);
|
mapper.update(null,update);
|
}
|
|
public Response deleteNotSubmitted() {
|
UserInf user = ActionUtil.getUser();
|
UpdateWrapper<BattDischargePlanTemp> update = Wrappers.update();
|
update.eq("submit_status",0).eq("create_user_id",user.getUId());
|
mapper.delete(update);
|
return new Response().set(1,"删除完成");
|
}
|
|
public List<BattDischargePlanTemp> getListByMainId(Integer mainId) {
|
QueryWrapper<BattDischargePlanTemp> query = Wrappers.query();
|
query.eq("main_id",mainId);
|
return mapper.selectList(query);
|
}
|
}
|