| | |
| | | import java.time.temporal.TemporalUnit; |
| | | import java.util.ArrayList; |
| | | import java.util.Calendar; |
| | | import java.util.Collections; |
| | | import java.util.Comparator; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.StringUtils; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.google.common.collect.Lists; |
| | |
| | | |
| | | import cn.hutool.core.lang.Snowflake; |
| | | import cn.hutool.core.util.IdUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | |
| | | @Service |
| | | public class CalendarServiceImpl extends ServiceImpl<CalendarMapper, ProductionCalendar> implements ICalendarService { |
| | |
| | | @Transactional(rollbackFor = {Exception.class}) |
| | | public ProductionCalendar saveCalendar(CalendarSaveVO calendarSaveVO) { |
| | | checkCalendar(calendarSaveVO, AuthUtil.getTenantId()); |
| | | |
| | | checkDateDTOList(calendarSaveVO.getDateDTOList()); |
| | | |
| | | ProductionCalendar productionCalendar = ProductionCalendarConvert.INSTANCE.conver(calendarSaveVO); |
| | | save(productionCalendar); |
| | | saveCalendarDayTime(calendarSaveVO.getDateDTOList(), productionCalendar); |
| | |
| | | return productionCalendar; |
| | | } |
| | | |
| | | @Transactional |
| | | @Override |
| | | public ProductionCalendar updateCalendar(CalendarUpdateVO calendarUpdateVO) { |
| | | |
| | | checkDateDTOList(calendarUpdateVO.getDateDTOList()); |
| | | |
| | | this.calendarDayService.deleteByCalendarId(calendarUpdateVO.getId()); |
| | | this.calendarDaytimeService.deleteByCalendarId(calendarUpdateVO.getId()); |
| | | ProductionCalendar calendar = getById(calendarUpdateVO.getId()); |
| | | updateCalendarDayTime(calendarUpdateVO.getDateDTOList(), calendar); |
| | | return calendar; |
| | | } |
| | | |
| | | /** |
| | | * 检查入参日期列表的重复数据,有重复则抛出错误信息 |
| | | * @param dateDTOList |
| | | */ |
| | | void checkDateDTOList(List<CalendarDateDTO> dateDTOList) { |
| | | List<LocalDate> dupList = dupulicateDate(dateDTOList); |
| | | if(!dupList.isEmpty()) { |
| | | String msg = StringUtils.join(dupList.stream().map(dt -> dt.format(DateTimeFormatter.ISO_DATE)).collect(Collectors.toList()), ","); |
| | | throw new ServiceException("日期数据重复:"+msg); |
| | | } |
| | | } |
| | | /*** |
| | | * 获取dateDTOList里面重复的数据(根据日期),日期一天只有一条 |
| | | * @param dateDTOList |
| | | * @return |
| | | */ |
| | | List<LocalDate> dupulicateDate(List<CalendarDateDTO> dateDTOList) { |
| | | if(ObjectUtil.isEmpty(dateDTOList)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<LocalDate> dupList = new ArrayList<>(); |
| | | |
| | | Map<LocalDate, List<CalendarDateDTO>> map = dateDTOList.stream().collect(Collectors.groupingBy(CalendarDateDTO::getCalendarDate)); |
| | | map.forEach((date,dtoList) -> { |
| | | if(dtoList.size()>1) { |
| | | dupList.add(date); |
| | | } |
| | | }); |
| | | return dupList; |
| | | } |
| | | |
| | | private void saveCalendarDayTime(List<CalendarDateDTO> dateDTOList, ProductionCalendar productionCalendar) { |
| | |
| | | } |
| | | |
| | | private void updateCalendarDayTime(List<CalendarDateDTO> dateDTOList, ProductionCalendar calenadar) { |
| | | |
| | | final LocalDate localDateNow = LocalDate.now(); |
| | | Long calendarId = calenadar.getId(); |
| | | Integer year = calenadar.getYear(); |
| | | Integer currentYear = Integer.valueOf(LocalDate.now().getYear()); |
| | | Set<LocalDate> dateList = dateDTOList.stream().filter(c -> { |
| | | return !Func.isNull(c.getModelId()) && Func.isNull(c.getOffDayId()); |
| | | }).map((v0) -> { |
| | | return v0.getCalendarDate(); |
| | | }).collect(Collectors.toSet()); |
| | | Set<LocalDate> offDay = dateDTOList.stream().filter(c2 -> { |
| | | return !Func.isNull(c2.getOffDayId()); |
| | | }).map((v0) -> { |
| | | return v0.getCalendarDate(); |
| | | }).collect(Collectors.toSet()); |
| | | Integer currentYear = localDateNow.getYear(); |
| | | |
| | | //提取出班制id不是null且不是休息日的 日期 |
| | | Set<LocalDate> dateList = dateDTOList.stream().filter(c -> (!Func.isNull(c.getModelId()) && Func.isNull(c.getOffDayId()))).map(CalendarDateDTO::getCalendarDate).collect(Collectors.toSet()); |
| | | |
| | | //提取所有为休息日的日期 |
| | | /**/ |
| | | Set<LocalDate> offDay = dateDTOList.stream().filter(c -> !Func.isNull(c.getOffDayId())).map(CalendarDateDTO::getCalendarDate).collect(Collectors.toSet()); |
| | | |
| | | //初始化最终要保存的day和daytime列表,等待后面代码填充 |
| | | List<ProductionCalendarDaytime> productionCalendarDaytimeList = new ArrayList<>(); |
| | | List<ProductionCalendarDay> productionCalendarDayList = new ArrayList<>(); |
| | | List<Long> modelIds = dateDTOList.stream().map((v0) -> { |
| | | return v0.getModelId(); |
| | | }).distinct().collect(Collectors.toList()); |
| | | |
| | | //提取所有班制id并去重 |
| | | List<Long> modelIds = dateDTOList.stream().map(CalendarDateDTO::getModelId).distinct().collect(Collectors.toList()); |
| | | |
| | | Map<Long, ShiftVO> shiftDetailMap = this.shiftModelService.getShiftDetail(modelIds); |
| | | Snowflake snowflake = IdUtil.createSnowflake(1L, 1L); |
| | | |
| | | //查询今天的daytime数据列表 |
| | | List<ProductionCalendarDaytime> todayDateTimeList = this.calendarDaytimeService.list(new QueryWrapper<ProductionCalendarDaytime>().lambda() |
| | | .eq(ProductionCalendarDaytime::getCalendarDate, LocalDate.now()) |
| | | .eq(ProductionCalendarDaytime::getCalendarDate, localDateNow) |
| | | .eq(ProductionCalendarDaytime::getCalendarId, calendarId) |
| | | .orderByAsc(ProductionCalendarDaytime::getStartTime)); |
| | | |
| | | |
| | | List<ProductionCalendarDaytime> curProductionCalendarDayTimeList = new ArrayList<>(); |
| | | LocalDate lastDayOfYear = LocalDateTimeUtils.getLastDayOfYear(LocalDate.now()); |
| | | long difference = year.intValue() == LocalDate.now().getYear() ? LocalDateTimeUtils.getDifference(LocalDate.now(), lastDayOfYear).intValue() : LocalDateTimeUtils.getDayOfYear(year).intValue() - 1; |
| | | long j = 0; |
| | | while (true) { |
| | | long i = j; |
| | | if (i <= difference) { |
| | | LocalDate needHandleDate = year.equals(currentYear) ? LocalDate.now().plus(difference - i, ChronoUnit.DAYS) : LocalDate.of(year.intValue(), 1, 1).plus(difference - i, ChronoUnit.DAYS);// (TemporalUnit) ChronoUnit.DAYS |
| | | LocalDate nextNeedHandleDate = needHandleDate.plus(1L, (TemporalUnit) ChronoUnit.DAYS); |
| | | buildCurrentDayTime(dateDTOList, calendarId, year, dateList, offDay, productionCalendarDaytimeList, productionCalendarDayList, shiftDetailMap, snowflake, curProductionCalendarDayTimeList, needHandleDate); |
| | | handleConflietDayTime(calenadar, year, productionCalendarDaytimeList, todayDateTimeList, curProductionCalendarDayTimeList, difference, i, needHandleDate, nextNeedHandleDate); |
| | | j = i + 1; |
| | | } else { |
| | | this.calendarDayService.saveBatchDay(productionCalendarDayList); |
| | | this.calendarDaytimeService.saveBatchDaytime(productionCalendarDaytimeList); |
| | | return; |
| | | } |
| | | LocalDate lastDayOfYear = LocalDateTimeUtils.getLastDayOfYear(localDateNow);//今年最后一天 |
| | | //日历的年份与当前年份相同,则返回: 今年最后一天-今天 的天数差.否则返回:一整年的天数-1 |
| | | //difference 也就是实际需要排班的总天数 |
| | | long difference = year.intValue() == localDateNow.getYear() ? LocalDateTimeUtils.getDifference(localDateNow, lastDayOfYear) : LocalDateTimeUtils.getDayOfYear(year) - 1; |
| | | //计算并生成day和daytime数据 |
| | | for (long i = 0; i < difference; i++) {//修改i<=difference 改为i<difference,下面代码difference - i在最后一次循环difference - i=0,也就是当天了,当天是不能排班的,而且会造成day数据重复 |
| | | //考虑LocalDate.now()实例化,plus改为plusDays |
| | | //LocalDate needHandleDate = year.equals(currentYear) ? localDateNow.plus(difference - i, ChronoUnit.DAYS) : LocalDate.of(year, 1, 1).plus(difference - i, ChronoUnit.DAYS); |
| | | LocalDate needHandleDate = year.equals(currentYear) ? localDateNow.plusDays(difference - i) : LocalDate.of(year, 1, 1).plusDays(difference - i); |
| | | //LocalDate nextNeedHandleDate = needHandleDate.plus(1, ChronoUnit.DAYS); |
| | | LocalDate nextNeedHandleDate = needHandleDate.plusDays(1); |
| | | buildCurrentDayTime(dateDTOList, calendarId, year, dateList, offDay, productionCalendarDaytimeList, productionCalendarDayList, shiftDetailMap, snowflake, curProductionCalendarDayTimeList, needHandleDate); |
| | | handleConflietDayTime(calenadar, year, productionCalendarDaytimeList, todayDateTimeList, curProductionCalendarDayTimeList, difference, i, needHandleDate, nextNeedHandleDate); |
| | | } |
| | | //保存day和daytime数据 |
| | | this.calendarDayService.saveBatchDay(productionCalendarDayList); |
| | | this.calendarDaytimeService.saveBatchDaytime(productionCalendarDaytimeList); |
| | | } |
| | | |
| | | private void handleConflietDayTime(ProductionCalendar calenadar, Integer year, List<ProductionCalendarDaytime> productionCalendarDaytimeList, List<ProductionCalendarDaytime> todayDateTimeList, List<ProductionCalendarDaytime> curProductionCalendarDayTimeList, long difference, long i, LocalDate needHandleDate, LocalDate nextNeedHandleDate) { |