package com.qianwen.mdc.collect.service; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.qianwen.core.tool.utils.Func; import com.qianwen.mdc.collect.constants.CommonConstant; import com.qianwen.mdc.collect.dto.CacheBuildDTO; import com.qianwen.mdc.collect.dto.CalendarShiftTimeSlicesDTO; import com.qianwen.mdc.collect.dto.TimestampToProductionTimeCacheDto; import com.qianwen.mdc.collect.entity.mgr.ProductionCalendar; import com.qianwen.mdc.collect.entity.mgr.ProductionCalendarDaytime; import com.qianwen.mdc.collect.mapper.mgr.CalendarMapper; import com.qianwen.mdc.collect.utils.LocalDateTimeUtils; @Service public class CalendarService extends ServiceImpl{ private static final Logger log = LoggerFactory.getLogger(CalendarService.class); //@Autowired //private CalendarDayService calendarDayService; @Autowired private CalendarDaytimeService calendarDaytimeService; //private final BladeRedis bladeRedis; //构建生产日历切片(blade_production_calendar) public List buildProductionTimeCache(CacheBuildDTO cacheBuildDTO) { LocalDate targetDate = cacheBuildDTO.getTargetDate(); Set tenantIds = cacheBuildDTO.getTenantIds(); String code = cacheBuildDTO.getCalendarCode(); List timestampToProductionTimeCacheDtos = new ArrayList<>();//返回结果, List calList = list((new QueryWrapper()).lambda() .in(ProductionCalendar::getTenantId, tenantIds) .eq(ProductionCalendar::getStatus, CommonConstant.ENABLE) .eq(StringUtils.isNotBlank(code), ProductionCalendar::getCode, code) .eq(ProductionCalendar::getYear, Integer.valueOf(targetDate.getYear()))); LocalDateTime startTime = LocalDateTime.of(targetDate, LocalTime.MIN);//0分0秒开始 LocalDateTime endTime = LocalDateTime.of(targetDate.plusDays(1L), LocalTime.of(0, 0));//第二天0点 if (Func.isNotEmpty(calList)) { Map> collect = calList.stream().collect(Collectors.groupingBy(ProductionCalendar::getTenantId)); collect.forEach((tenantId, productionCalList) -> { productionCalList.forEach(productionCalendar -> { TimestampToProductionTimeCacheDto timestampToProductionTimeCacheDto = TimestampToProductionTimeCacheDto.builder().TenantId(productionCalendar.getTenantId()).CalendarCode(productionCalendar.getCode()).NaturalDay(targetDate).build(); List dayTimeList = this.calendarDaytimeService.list(new QueryWrapper().lambda() .eq(ProductionCalendarDaytime::getCalendarId, productionCalendar.getId()).or().and(i -> { LambdaQueryWrapper lambdaQueryWrapper = i.between(ProductionCalendarDaytime::getStartTime, startTime, endTime).or() .between(ProductionCalendarDaytime::getEndTime, startTime, endTime); }).orderByAsc(ProductionCalendarDaytime::getStartTime)); //去掉dayTimeList种起止时间=startTime和endTime的数据 List dayTimeList2 = dayTimeList.stream().filter(productionCalendarDaytime -> { return (productionCalendarDaytime.getEndTime().equals(startTime) || productionCalendarDaytime.getStartTime().equals(endTime)) ? false : true; }).collect(Collectors.toList()); Map timeSlicesMap = new HashMap<>(1919);//一天中的分钟序号 -> DTO for (int i2 = 0; i2 <= CommonConstant.MINUTE_STOP.intValue(); i2++) {//MINUTE_STOP=1439,差一分钟23小时59分的分钟数 buildTimeSlicesMap(startTime, endTime, dayTimeList2, timeSlicesMap, i2, targetDate); } timestampToProductionTimeCacheDto.setTimeSlicesDTOMap(timeSlicesMap); timestampToProductionTimeCacheDtos.add(timestampToProductionTimeCacheDto); }); }); } return timestampToProductionTimeCacheDtos; } /** * 构建一天的时间切片数据,保存到timeSlicesDTOMap种 * @param startTime * @param endTime * @param dayTimeList * @param timeSlicesDTOMap 设置值,上层方法直接使用 * @param minutesOfDay 分钟数值 从0点开始的,不是每小时的分钟数 * @param targetDate 日期 */ private void buildTimeSlicesMap(LocalDateTime startTime, LocalDateTime endTime, List dayTimeList, Map timeSlicesDTOMap, int minutesOfDay, LocalDate targetDate) { LocalDateTime localDateTime = LocalDateTime.of(targetDate, LocalTime.MIN).plusMinutes(minutesOfDay).plusSeconds(1L); //在dayTimeList中过滤出在starttime,endtime之间的数据,取第一个 ProductionCalendarDaytime productionCalendarDaytime = dayTimeList.stream().filter(dayTime -> { return (localDateTime.isAfter(dayTime.getStartTime()) || localDateTime.equals(dayTime.getStartTime())) && (localDateTime.isBefore(dayTime.getEndTime()) || localDateTime.equals(dayTime.getEndTime())); }).findFirst().orElse(null); if (Func.isEmpty(productionCalendarDaytime)) { return; } LocalDateTime shiftStartTime = productionCalendarDaytime.getStartTime(); LocalDateTime shiftEndTime = productionCalendarDaytime.getEndTime(); if (shiftStartTime.isBefore(startTime)) { shiftStartTime = startTime; } if (shiftEndTime.isAfter(endTime)) { shiftEndTime = endTime; } CalendarShiftTimeSlicesDTO calendarShiftTimeSlicesDTO = CalendarShiftTimeSlicesDTO.builder().shiftTimeType(productionCalendarDaytime.getShiftType().toString()).endTime(LocalDateTimeUtils.LocalDateTimeToDate(shiftEndTime)).startTime(LocalDateTimeUtils.LocalDateTimeToDate(shiftStartTime)).shiftIndex(productionCalendarDaytime.getShiftIndex()).shiftTimeType(productionCalendarDaytime.getShiftType().toString()).factoryDate(LocalDateTimeUtils.formatTimeLocalDate(productionCalendarDaytime.getCalendarDate(), "yyyy-MM-dd")).factoryMonth(productionCalendarDaytime.getMonth()).factoryWeek(productionCalendarDaytime.getWeek()).factoryYear(productionCalendarDaytime.getYear()).build(); timeSlicesDTOMap.put(minutesOfDay, calendarShiftTimeSlicesDTO); } }