Commit d4c2ac6a by 刘鑫

fix(工程师全天容量): 修改工程师全天容量计算逻辑

1 parent 632d4f41
......@@ -6,14 +6,11 @@ import com.dituhui.pea.order.common.OccupyInfo;
import com.dituhui.pea.order.common.OccupyInfoDetail;
import com.dituhui.pea.order.common.jackson.DateTimeUtil;
import com.dituhui.pea.order.common.jackson.DateUtil;
import com.dituhui.pea.order.dao.CapacityEngineerCalendarDao;
import com.dituhui.pea.order.dao.CapacityEngineerStatDao;
import com.dituhui.pea.order.dao.EngineerBusinessDao;
import com.dituhui.pea.order.dao.EngineerInfoDao;
import com.dituhui.pea.order.dao.EngineerSliceUsedCapacityDao;
import com.dituhui.pea.order.dao.OrderInfoDao;
import com.dituhui.pea.order.dao.TimeSliceDao;
import com.dituhui.pea.order.entity.CapacityEngineerCalendarEntity;
import com.dituhui.pea.order.entity.CapacityEngineerSliceUsedEntity;
import com.dituhui.pea.order.entity.CapacityEngineerStatEntity;
import com.dituhui.pea.order.entity.EngineerBusinessEntity;
......@@ -32,9 +29,7 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
......@@ -54,14 +49,10 @@ public class CalcEngineerCapacityScheduler {
@Autowired
private OrderInfoDao orderInfoDao;
@Autowired
private CapacityEngineerCalendarDao capacityEngineerCalendarDao;
@Autowired
private EngineerBusinessDao engineerBusinessDao;
@Autowired
private EngineerInfoDao engineerInfoDao;
@Autowired
private TimeSliceDao timeSliceDao;
@Autowired
private EngineerSliceUsedCapacityDao engineerSliceUsedCapacityDao;
@Autowired
private EngineerCalendarService engineerCalendarService;
......@@ -105,25 +96,29 @@ public class CalcEngineerCapacityScheduler {
.stream()
.filter(e -> !ss.contains(e.getOrderStatus()))
.collect(Collectors.toList());
initOneEngineerTimeSlot(date, engineerCode, configs, orders);
caculateEngineerOneDay(date, businessEntity, orders, configs, statEntity);
capacityEngineerStatDao.save(statEntity);
}
int used = orders.stream().map(e -> {
if (ss.contains(e.getOrderStatus())) {
return 0;
} else {
return e.getTakeTime();
}
}).mapToInt(Integer::intValue).sum();
long cnt = orders.size();
long max = getMaxRemainBlock(date, engineerCode, orders, businessEntity);
log.info("正在处理: 日期[{}]技术员[{}]容量相关信息 ==> used:{}, orderCnt:{}, maxDuration:{}", date, engineerCode, used, cnt, max);
statEntity.setOrderCount((int) cnt);
statEntity.setCapUsed(used);
statEntity.setCapLeft(statEntity.getCapTotal() - used);
statEntity.setMaxDuration((int) max);
private static void caculateEngineerOneDay(String date, EngineerBusinessEntity businessEntity, List<OrderInfoEntity> orders,
List<OccupyInfoDetail> configs, CapacityEngineerStatEntity statEntity) {
final LocalDateTime startTime = DateUtils.localDateTimeFromStr(String.format("%s %s:00", date, businessEntity.getWorkOn()));
final LocalDateTime endTime = DateUtils.localDateTimeFromStr(String.format("%s %s:00", date, businessEntity.getWorkOff()));
List<OccupyInfo> occupyInfo = CapacityUtils.caculate(startTime, endTime, orders, configs);
//已用容量
long totalUseTime = occupyInfo.stream().mapToLong(t -> Duration.between(t.getEndTime(), t.getBeginTime()).abs().toMinutes()).sum();
//最大连续时长
List<OccupyInfoDetail> durationTime = CapacityUtils.getMaxRemainBlock(startTime, endTime, occupyInfo);
long maxRemainBlock = durationTime.stream().mapToLong(OccupyInfoDetail::getDuration).max().orElse(0L);
statEntity.setOrderCount(orders.size());
statEntity.setCapUsed((int) totalUseTime);
statEntity.setCapLeft(statEntity.getCapTotal() - (int) totalUseTime);
statEntity.setMaxDuration((int) maxRemainBlock);
statEntity.setUpdateTime(LocalDateTime.now());
capacityEngineerStatDao.save(statEntity);
}
//添加工程师日历参数
......@@ -158,45 +153,4 @@ public class CalcEngineerCapacityScheduler {
engineerSliceUsedCapacityDao.saveAll(engineerTimeSlice);
}
private long getMaxRemainBlock(String date, String engineerCode, List<OrderInfoEntity> orders, EngineerBusinessEntity businessEntity) {
// 根据capacity_engineer_calendar和order_info,来确定当天剩下的最大连续时间区块;
LocalDateTime startTime = DateUtils.localDateTimeFromStr(String.format("%s %s:00", date, businessEntity.getWorkOn()));
LocalDateTime endTime = DateUtils.localDateTimeFromStr(String.format("%s %s:00", date, businessEntity.getWorkOff()));
List<OccupyInfo> occupyInfos = new ArrayList<>();
List<CapacityEngineerCalendarEntity> configs = capacityEngineerCalendarDao.findCalendarByWorkdayAndEngineerCode(date, engineerCode);
if (!configs.isEmpty()) {
occupyInfos.addAll(
configs.stream().map(e -> new OccupyInfo().setBeginTime(e.getStartTime()).setEndTime(e.getEndTime())).collect(Collectors.toList())
);
}
if (!orders.isEmpty()) {
occupyInfos.addAll(
orders.stream().map(e -> new OccupyInfo().setBeginTime(e.getPlanStartTime()).setEndTime(e.getPlanEndTime())).collect(Collectors.toList())
);
}
if (occupyInfos.isEmpty()) {
return Duration.between(startTime, endTime).toMinutes();
}
occupyInfos.sort(Comparator.comparing(OccupyInfo::getBeginTime));
// 从 occupyInfos的配置间隙中,获取最大的闲时段,理论上,上面的配置段之间,是不会交叉的,如果交叉,那是存在问题的!
List<Long> idlePeriods = new ArrayList<>();
LocalDateTime preLast = startTime;
for (OccupyInfo o : occupyInfos) {
if (o.getBeginTime().isAfter(preLast)) {
idlePeriods.add(Duration.between(startTime, o.getBeginTime()).toMinutes());
}
preLast = o.getEndTime();
}
if (preLast.isBefore(endTime)) {
idlePeriods.add(Duration.between(preLast, endTime).toMinutes());
}
if (idlePeriods.isEmpty()) {
return Duration.between(startTime, endTime).toMinutes();
} else {
return Collections.max(idlePeriods);
}
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!