package com.qianwen.smartman.common.cache.cps;
|
|
import cn.hutool.core.date.DateTime;
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.google.common.collect.Lists;
|
import java.lang.invoke.SerializedLambda;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.Comparator;
|
import java.util.Date;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Optional;
|
import java.util.Set;
|
import java.util.stream.Collectors;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import com.qianwen.smartman.common.constant.ProductionTimeConstant;
|
import com.qianwen.smartman.common.utils.CommonUtil;
|
import com.qianwen.smartman.common.utils.LocalDateUtil;
|
import com.qianwen.smartman.common.utils.MessageUtils;
|
import com.qianwen.core.redis.cache.BladeRedis;
|
import com.qianwen.core.secure.utils.AuthUtil;
|
import com.qianwen.core.tool.support.Kv;
|
import com.qianwen.core.tool.utils.DateUtil;
|
import com.qianwen.core.tool.utils.Func;
|
import com.qianwen.core.tool.utils.SpringUtil;
|
import com.qianwen.smartman.modules.cps.dto.CacheBuildDTO;
|
import com.qianwen.smartman.modules.cps.dto.CalendarShiftTimeSlicesDTO;
|
import com.qianwen.smartman.modules.cps.dto.CurrentShiftInfoDTO;
|
import com.qianwen.smartman.modules.cps.dto.TimestampToProductionTimeCacheDto;
|
import com.qianwen.smartman.modules.cps.entity.ProductionCalendar;
|
import com.qianwen.smartman.modules.cps.entity.ProductionCalendarDay;
|
import com.qianwen.smartman.modules.cps.entity.ProductionCalendarDaytime;
|
import com.qianwen.smartman.modules.cps.entity.ShiftDetail;
|
import com.qianwen.smartman.modules.cps.service.ICalendarDayService;
|
import com.qianwen.smartman.modules.cps.service.ICalendarDaytimeService;
|
import com.qianwen.smartman.modules.cps.service.ICalendarService;
|
import com.qianwen.smartman.modules.cps.service.IShiftDetailService;
|
import org.springframework.data.redis.core.SetOperations;
|
|
public class TimeSliceCache {
|
private static final Logger log = LoggerFactory.getLogger(TimeSliceCache.class);
|
|
public static final String CALENDAR_CACHE = "blade:cps::calendar";
|
|
public static final String CALENDAR = "calendar";
|
|
public static final String CODE = "code:";
|
|
public static final String SHIFT = "shift:";
|
|
public static final String CALENDARS_CODE = "calendars:code:";
|
|
public static final String MINUTE_POINT = "minute-point:";
|
|
private static final ICalendarService CALENDAR_SERVICE;
|
|
private static final ICalendarDayService CALENDAR_DAY_SERVICE;
|
|
private static final ICalendarDaytimeService DAYTIME_SERVICE = (ICalendarDaytimeService)SpringUtil.getBean(ICalendarDaytimeService.class);
|
|
private static final IShiftDetailService SHIFT_DETAIL_SERVICE;
|
|
private static final BladeRedis BLADE_REDIS = (BladeRedis)SpringUtil.getBean(BladeRedis.class);
|
|
static {
|
CALENDAR_SERVICE = (ICalendarService)SpringUtil.getBean(ICalendarService.class);
|
CALENDAR_DAY_SERVICE = (ICalendarDayService)SpringUtil.getBean(ICalendarDayService.class);
|
SHIFT_DETAIL_SERVICE = (IShiftDetailService)SpringUtil.getBean(IShiftDetailService.class);
|
}
|
|
public static List<ShiftDetail> getTimeShiftDetail(String calendarCode, LocalDate date) {
|
if (Func.isNull(calendarCode) || Func.isNull(date))
|
return Lists.newArrayList();
|
String redisKey = CommonUtil.getReallyCacheName("blade:cps::calendar", "code:"
|
.concat(calendarCode).concat(":").concat("shift:"),
|
DateUtil.format(date, "yyyy-MM-dd"));
|
SetOperations<String, Object> setOps = BLADE_REDIS.getSetOps();
|
Set<Object> members = setOps.members(redisKey);
|
if (Func.isEmpty(members)) {
|
ProductionCalendar calendar = (ProductionCalendar)CALENDAR_SERVICE.getOne(Wrappers.<ProductionCalendar>lambdaQuery().eq(ProductionCalendar::getCode, calendarCode));
|
|
return Optional.ofNullable(calendar).map(cal -> {
|
ProductionCalendarDay calendarDay = CALENDAR_DAY_SERVICE.getOne((Wrappers.<ProductionCalendarDay>lambdaQuery().eq((v0) -> {
|
return v0.getCalendarId();
|
}, cal.getId())).eq((v0) -> {
|
return v0.getCalendarDate();
|
}, date));
|
return Optional.ofNullable(calendarDay).map(day -> {
|
Long modelId = day.getModelId();
|
List<ShiftDetail> list = SHIFT_DETAIL_SERVICE.list(Wrappers.<ShiftDetail>lambdaQuery().eq((v0) -> {
|
return v0.getModelId();
|
}, modelId));
|
list.forEach(s -> {
|
if (Func.isBlank(s.getIndexName())) {
|
s.setIndexName(MessageUtils.message("calendar.page.shift.model.shift", new Object[0]) + s.getShiftIndex());
|
}
|
setOps.add(redisKey, new Object[]{s});
|
});
|
BLADE_REDIS.expire(redisKey, 86400L);
|
return list;
|
}).orElse(Lists.newArrayList());
|
}).orElse(Lists.newArrayList());
|
|
}
|
return (List<ShiftDetail>)members.stream()
|
.map(c -> (ShiftDetail)Func.convert(c, ShiftDetail.class))
|
.collect(Collectors.toList());
|
}
|
|
public static CalendarShiftTimeSlicesDTO getTimeSliceShift(String calendarCode, LocalDate data, Integer shift) {
|
String redisKey = CommonUtil.getReallyCacheName("blade:cps::calendar", "code:"
|
.concat(calendarCode).concat(":"),
|
DateUtil.format(data, "yyyy-MM-dd"));
|
final CalendarShiftTimeSlicesDTO timeSliceShift = (CalendarShiftTimeSlicesDTO)TimeSliceCache.BLADE_REDIS.hGet(redisKey, (Object)shift);
|
if (Func.isNotEmpty((Object)timeSliceShift)) {
|
return timeSliceShift;
|
}
|
final ProductionCalendar calendar = (ProductionCalendar)TimeSliceCache.CALENDAR_SERVICE.getOne(Wrappers.<ProductionCalendar>lambdaQuery().eq(ProductionCalendar::getCode, (Object)calendarCode));
|
return (CalendarShiftTimeSlicesDTO) Optional.ofNullable(calendar).map(cal -> {
|
Long id = cal.getId();
|
List<ProductionCalendarDaytime> daytimeList = DAYTIME_SERVICE.list(( Wrappers.<ProductionCalendarDaytime>lambdaQuery().eq((v0) -> {
|
return v0.getCalendarId();
|
}, id).eq((v0) -> {
|
return v0.getCalendarDate();
|
}, data)).ne((v0) -> {
|
return v0.getShiftIndex();
|
}, ProductionTimeConstant.OUT_OF_SHIFT_TIME));
|
|
return (CalendarShiftTimeSlicesDTO) Optional.ofNullable(daytimeList).map(times -> {
|
Map<Integer, List<ProductionCalendarDaytime>> map = times.stream().collect(Collectors.groupingBy((v0) -> {
|
return v0.getShiftIndex();
|
}));
|
Map<Integer, CalendarShiftTimeSlicesDTO> timeSlicesDtoMap = Kv.newMap();
|
map.forEach((k, v) -> {
|
ProductionCalendarDaytime daytime = (ProductionCalendarDaytime) v.stream().min(Comparator.comparing((v0) -> {
|
return v0.getStartTime();
|
})).get();
|
ProductionCalendarDaytime endTimeDay = (ProductionCalendarDaytime) v.stream().max(Comparator.comparing((v0) -> {
|
return v0.getEndTime();
|
})).get();
|
daytime.setEndTime(endTimeDay.getEndTime());
|
timeSlicesDtoMap.put(k, CalendarShiftTimeSlicesDTO.builder().endTime(DateUtil.toDate(daytime.getEndTime())).startTime(DateUtil.toDate(daytime.getStartTime())).shiftIndex(daytime.getShiftIndex()).factoryDate(DateUtil.formatDate(daytime.getCalendarDate())).factoryMonth(daytime.getMonth()).factoryWeek(daytime.getWeek()).factoryYear(daytime.getYear()).build());
|
});
|
BLADE_REDIS.getRedisTemplate().opsForHash().putAll(redisKey, timeSlicesDtoMap);
|
BLADE_REDIS.expire(redisKey, 86400L);
|
return timeSlicesDtoMap.get(shift);
|
}).orElse(null);
|
}).orElse(null);
|
|
}
|
|
public static CalendarShiftTimeSlicesDTO getTimeSliceShift(String calendarCode, Date date) {
|
int minutes = DateTime.of(date).hour(true) * 60 + DateTime.of(date).minute();
|
String redisKey = CommonUtil.getReallyCacheName("blade:cps::calendar", "calendars:code:".concat(calendarCode).concat(":").concat("minute-point:"),
|
DateTime.of(date).toDateStr());
|
CalendarShiftTimeSlicesDTO calendarShiftTimeSlicesDTO = (CalendarShiftTimeSlicesDTO)BLADE_REDIS.hGet(redisKey, Integer.valueOf(minutes));
|
if (Func.isEmpty(calendarShiftTimeSlicesDTO)) {
|
HashSet<String> tenantIdSet = new HashSet<>();
|
tenantIdSet.add(AuthUtil.getTenantId());
|
CacheBuildDTO cacheBuildDTO = CacheBuildDTO.builder().targetDate(LocalDateUtil.dateToLocalDate(date)).tenantIds(tenantIdSet).calendarCode(calendarCode).build();
|
build(cacheBuildDTO);
|
calendarShiftTimeSlicesDTO = (CalendarShiftTimeSlicesDTO)BLADE_REDIS.hGet(redisKey, Integer.valueOf(minutes));
|
}
|
return calendarShiftTimeSlicesDTO;
|
}
|
|
public static Map<String, CurrentShiftInfoDTO> getCurrentShiftInfo(List<String> calendarCodeList) {
|
List<CurrentShiftInfoDTO> currentShiftInfoDTOList = new ArrayList<>();
|
LocalDateTime now = LocalDateTime.now();
|
Integer minute = Integer.valueOf(now.getHour() * 60 + now.getMinute());
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
String str = LocalDate.now().format(formatter);
|
calendarCodeList.forEach(calendarCode -> {
|
String redisKey = CommonUtil.getReallyCacheName("blade:cps::calendar", "calendars:code:".concat(calendarCode).concat(":").concat("minute-point:"), str);
|
CalendarShiftTimeSlicesDTO calendarShiftTimeSlicesDTO = (CalendarShiftTimeSlicesDTO)BLADE_REDIS.hGet(redisKey, minute);
|
if (Func.isNotEmpty(calendarShiftTimeSlicesDTO)) {
|
String shiftIndexName = CALENDAR_SERVICE.getShiftIndexNameByCodeAndYear(calendarCode, calendarShiftTimeSlicesDTO);
|
CurrentShiftInfoDTO currentShiftInfoDTO = CurrentShiftInfoDTO.builder().factoryDay(LocalDate.parse(calendarShiftTimeSlicesDTO.getFactoryDate(), formatter)).shiftIndex(calendarShiftTimeSlicesDTO.getShiftIndex()).startTime(DateUtil.fromDate(calendarShiftTimeSlicesDTO.getStartTime())).endTime(DateUtil.fromDate(calendarShiftTimeSlicesDTO.getEndTime())).calendarCode(calendarCode).shiftIndexName(shiftIndexName).build();
|
currentShiftInfoDTOList.add(currentShiftInfoDTO);
|
}
|
});
|
return (Map<String, CurrentShiftInfoDTO>)currentShiftInfoDTOList.stream().distinct().collect(Collectors.toMap(CurrentShiftInfoDTO::getCalendarCode, v -> v));
|
}
|
|
/**
|
* 构建生产日历切片缓存,从CalendarCacheXxlJob中定时调用
|
* @param cacheBuildDTO
|
*/
|
public static void build(CacheBuildDTO cacheBuildDTO) {
|
String key = cacheBuildDTO.getTargetDate().format(DateTimeFormatter.ISO_LOCAL_DATE);
|
List<TimestampToProductionTimeCacheDto> data = CALENDAR_SERVICE.buildProductionTimeCache(cacheBuildDTO);
|
if (Func.isNotEmpty(data))
|
data.forEach(t -> {
|
String redisKey = CommonUtil.getReallyCacheName("blade:cps::calendar", "calendars:code:".concat(t.getCalendarCode()).concat(":").concat("minute-point:"), key);//key格式:yyyy-MM-dd
|
Map<Integer, CalendarShiftTimeSlicesDTO> timeSlicesDtoMap = t.getTimeSlicesDTOMap();
|
BLADE_REDIS.getRedisTemplate().opsForHash().putAll(redisKey, timeSlicesDtoMap);
|
long oneDaySeconds = 86400L;//24小时的秒数
|
BLADE_REDIS.expire(redisKey, oneDaySeconds * 40L);
|
});
|
}
|
}
|