Showing
4 changed files
with
121 additions
and
12 deletions
| ... | @@ -6,6 +6,7 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper; | ... | @@ -6,6 +6,7 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper; |
| 6 | import com.infoloop.tianting.server.StorageService; | 6 | import com.infoloop.tianting.server.StorageService; |
| 7 | import com.infoloop.tianting.server.StorageServiceFactory; | 7 | import com.infoloop.tianting.server.StorageServiceFactory; |
| 8 | import com.infoloop.tianting.store.LoginCodeStore; | 8 | import com.infoloop.tianting.store.LoginCodeStore; |
| 9 | +import com.infoloop.tianting.store.WeeklyTaskStore; | ||
| 9 | import com.infoloop.tianting.utils.SmsUtil; | 10 | import com.infoloop.tianting.utils.SmsUtil; |
| 10 | import io.lettuce.core.api.StatefulRedisConnection; | 11 | import io.lettuce.core.api.StatefulRedisConnection; |
| 11 | import org.springframework.beans.factory.annotation.Autowired; | 12 | import org.springframework.beans.factory.annotation.Autowired; |
| ... | @@ -16,6 +17,8 @@ import org.springframework.context.annotation.Configuration; | ... | @@ -16,6 +17,8 @@ import org.springframework.context.annotation.Configuration; |
| 16 | import org.springframework.context.annotation.Import; | 17 | import org.springframework.context.annotation.Import; |
| 17 | import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; | 18 | import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; |
| 18 | 19 | ||
| 20 | +import java.time.Duration; | ||
| 21 | + | ||
| 19 | import static com.infoloop.tianting.constant.ConfigConstants.REDIS_CONNECTION; | 22 | import static com.infoloop.tianting.constant.ConfigConstants.REDIS_CONNECTION; |
| 20 | 23 | ||
| 21 | @Configuration | 24 | @Configuration |
| ... | @@ -29,6 +32,13 @@ public class AppConfig { | ... | @@ -29,6 +32,13 @@ public class AppConfig { |
| 29 | return new LoginCodeStore(commands, 300); | 32 | return new LoginCodeStore(commands, 300); |
| 30 | } | 33 | } |
| 31 | 34 | ||
| 35 | + @Bean | ||
| 36 | + public WeeklyTaskStore weeklyTaskStore(@Autowired @Qualifier(REDIS_CONNECTION) final StatefulRedisConnection<String, String> connection) { | ||
| 37 | + final var commands = connection.sync(); | ||
| 38 | + final var expireSeconds = Duration.ofDays(7).getSeconds(); | ||
| 39 | + return new WeeklyTaskStore(commands, expireSeconds); | ||
| 40 | + } | ||
| 41 | + | ||
| 32 | // init bean | 42 | // init bean |
| 33 | @Bean | 43 | @Bean |
| 34 | public SmsUtil smsUtil(@Autowired SmsConfig smsConfig) { | 44 | public SmsUtil smsUtil(@Autowired SmsConfig smsConfig) { | ... | ... |
| ... | @@ -10,8 +10,11 @@ import com.infoloop.tianting.mealorderservice.SingleDinerRpcResponse; | ... | @@ -10,8 +10,11 @@ import com.infoloop.tianting.mealorderservice.SingleDinerRpcResponse; |
| 10 | import com.infoloop.tianting.mealorderservice.SingleGradeClassRpcResponse; | 10 | import com.infoloop.tianting.mealorderservice.SingleGradeClassRpcResponse; |
| 11 | import com.infoloop.tianting.mealorderservice.SingleMealMenuRecordRpcResponse; | 11 | import com.infoloop.tianting.mealorderservice.SingleMealMenuRecordRpcResponse; |
| 12 | import com.infoloop.tianting.mealorderservice.SingleMealOrderRpcResponse; | 12 | import com.infoloop.tianting.mealorderservice.SingleMealOrderRpcResponse; |
| 13 | +import com.infoloop.tianting.mealorderservice.SingleMpAccountDinerRefRpcResponse; | ||
| 13 | import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient; | 14 | import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient; |
| 15 | +import com.infoloop.tianting.service.client.DeliveryRuleServiceRpcClient; | ||
| 14 | import com.infoloop.tianting.service.client.MealOrderServiceRpcClient; | 16 | import com.infoloop.tianting.service.client.MealOrderServiceRpcClient; |
| 17 | +import com.infoloop.tianting.store.WeeklyTaskStore; | ||
| 15 | import com.infoloop.tianting.utils.DateUtil; | 18 | import com.infoloop.tianting.utils.DateUtil; |
| 16 | import lombok.RequiredArgsConstructor; | 19 | import lombok.RequiredArgsConstructor; |
| 17 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
| ... | @@ -21,9 +24,12 @@ import org.springframework.stereotype.Component; | ... | @@ -21,9 +24,12 @@ import org.springframework.stereotype.Component; |
| 21 | import java.time.DayOfWeek; | 24 | import java.time.DayOfWeek; |
| 22 | import java.time.Instant; | 25 | import java.time.Instant; |
| 23 | import java.time.LocalDate; | 26 | import java.time.LocalDate; |
| 27 | +import java.time.LocalDateTime; | ||
| 24 | import java.time.LocalTime; | 28 | import java.time.LocalTime; |
| 25 | import java.time.ZonedDateTime; | 29 | import java.time.ZonedDateTime; |
| 26 | import java.time.temporal.TemporalAdjusters; | 30 | import java.time.temporal.TemporalAdjusters; |
| 31 | +import java.util.ArrayList; | ||
| 32 | +import java.util.Collections; | ||
| 27 | import java.util.List; | 33 | import java.util.List; |
| 28 | import java.util.Map; | 34 | import java.util.Map; |
| 29 | import java.util.Objects; | 35 | import java.util.Objects; |
| ... | @@ -40,10 +46,42 @@ public class AutoCreateMealOrderTask { | ... | @@ -40,10 +46,42 @@ public class AutoCreateMealOrderTask { |
| 40 | 46 | ||
| 41 | private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient; | 47 | private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient; |
| 42 | 48 | ||
| 43 | - @Scheduled(cron = "59 59 23 ? * SUN") | 49 | + private final DeliveryRuleServiceRpcClient deliveryRuleServiceRpcClient; |
| 50 | + | ||
| 51 | + private final WeeklyTaskStore weeklyTaskStore; | ||
| 52 | + | ||
| 53 | + @Scheduled(cron = "0 * * ? * *") | ||
| 44 | public void executeTask() { | 54 | public void executeTask() { |
| 45 | final int enterpriseId = 449; | 55 | final int enterpriseId = 449; |
| 46 | - final var today = LocalDate.now(); | 56 | + final var now = LocalDateTime.now(); |
| 57 | + final var today = now.toLocalDate(); | ||
| 58 | + // 判断是否本周已执行 | ||
| 59 | + final var keyPrefix = "create-meal-order-task"; | ||
| 60 | + if (weeklyTaskStore.isExecutedThisWeek(keyPrefix, enterpriseId, today)) return; | ||
| 61 | + | ||
| 62 | + final var rules = deliveryRuleServiceRpcClient.getDefaultDeliveryTemplateAndRule(enterpriseId).getRule(); | ||
| 63 | + if (rules.getConfigJson().getRulesList().isEmpty()) { | ||
| 64 | + return; | ||
| 65 | + } | ||
| 66 | + final var rule = rules.getConfigJson().getRules(0); | ||
| 67 | + final var endTime = LocalTime.parse(rule.getEndTime(), DateUtil.HH_MM_SS); | ||
| 68 | + final var enabledDays = new ArrayList<DayOfWeek>(); | ||
| 69 | + if (Boolean.TRUE.equals(rule.getMonday())) enabledDays.add(DayOfWeek.MONDAY); | ||
| 70 | + if (Boolean.TRUE.equals(rule.getTuesday())) enabledDays.add(DayOfWeek.TUESDAY); | ||
| 71 | + if (Boolean.TRUE.equals(rule.getWednesday())) enabledDays.add(DayOfWeek.WEDNESDAY); | ||
| 72 | + if (Boolean.TRUE.equals(rule.getThursday())) enabledDays.add(DayOfWeek.THURSDAY); | ||
| 73 | + if (Boolean.TRUE.equals(rule.getFriday())) enabledDays.add(DayOfWeek.FRIDAY); | ||
| 74 | + if (Boolean.TRUE.equals(rule.getSaturday())) enabledDays.add(DayOfWeek.SATURDAY); | ||
| 75 | + if (Boolean.TRUE.equals(rule.getSunday())) enabledDays.add(DayOfWeek.SUNDAY); | ||
| 76 | + if (enabledDays.isEmpty()) { | ||
| 77 | + return; | ||
| 78 | + } | ||
| 79 | + final var maxDay = Collections.max(enabledDays); | ||
| 80 | + final var endDateTime = getThisWeekDay(today, maxDay).atTime(endTime); | ||
| 81 | + if (now.isBefore(endDateTime)) { | ||
| 82 | + log.info("当前时间小于订餐结束时间:{},跳过自动订餐任务", endDateTime); | ||
| 83 | + return; | ||
| 84 | + } | ||
| 47 | final var thisWeekStart = today.with(DayOfWeek.MONDAY).atStartOfDay().atZone(DateUtil.CHINA_ZONE); | 85 | final var thisWeekStart = today.with(DayOfWeek.MONDAY).atStartOfDay().atZone(DateUtil.CHINA_ZONE); |
| 48 | final var thisWeekEnd = today.with(DayOfWeek.SUNDAY).atTime(LocalTime.MAX).atZone(DateUtil.CHINA_ZONE); | 86 | final var thisWeekEnd = today.with(DayOfWeek.SUNDAY).atTime(LocalTime.MAX).atZone(DateUtil.CHINA_ZONE); |
| 49 | final var nextWeekStart = today.with(TemporalAdjusters.next(DayOfWeek.MONDAY)).atStartOfDay().atZone(DateUtil.CHINA_ZONE); | 87 | final var nextWeekStart = today.with(TemporalAdjusters.next(DayOfWeek.MONDAY)).atStartOfDay().atZone(DateUtil.CHINA_ZONE); |
| ... | @@ -59,6 +97,9 @@ public class AutoCreateMealOrderTask { | ... | @@ -59,6 +97,9 @@ public class AutoCreateMealOrderTask { |
| 59 | log.info("无未订餐学生,跳过自动订餐任务"); | 97 | log.info("无未订餐学生,跳过自动订餐任务"); |
| 60 | return; | 98 | return; |
| 61 | } | 99 | } |
| 100 | + | ||
| 101 | + final var mpAccountDinerRefMap = mealOrderServiceRpcClient.queryMpAccountDinerRefsByCondition(enterpriseId, Collections.emptyList(), notReservedDiners.stream().map(SingleDinerRpcResponse::getId).toList()).stream().collect(Collectors.toMap(SingleMpAccountDinerRefRpcResponse::getDinerId, Function.identity(), (v1, v2) -> v1)); | ||
| 102 | + | ||
| 62 | // 所需关联数据查询 | 103 | // 所需关联数据查询 |
| 63 | final var clientIds = notReservedDiners.stream().map(SingleDinerRpcResponse::getClientId).distinct().toList(); | 104 | final var clientIds = notReservedDiners.stream().map(SingleDinerRpcResponse::getClientId).distinct().toList(); |
| 64 | final var classIds = notReservedDiners.stream().map(SingleDinerRpcResponse::getClassId).distinct().toList(); | 105 | final var classIds = notReservedDiners.stream().map(SingleDinerRpcResponse::getClassId).distinct().toList(); |
| ... | @@ -66,7 +107,7 @@ public class AutoCreateMealOrderTask { | ... | @@ -66,7 +107,7 @@ public class AutoCreateMealOrderTask { |
| 66 | final var gradeClassMap = mealOrderServiceRpcClient.getGradeClassesByIds(enterpriseId, classIds).stream().collect(Collectors.toMap(SingleGradeClassRpcResponse::getId, Function.identity())); | 107 | final var gradeClassMap = mealOrderServiceRpcClient.getGradeClassesByIds(enterpriseId, classIds).stream().collect(Collectors.toMap(SingleGradeClassRpcResponse::getId, Function.identity())); |
| 67 | final var latestMealMenuRecordMap = mealOrderServiceRpcClient.queryLatestMealMenuRecordsByClientIds(enterpriseId, clientIds).stream().collect(Collectors.toMap(SingleMealMenuRecordRpcResponse::getClientId, Function.identity())); | 108 | final var latestMealMenuRecordMap = mealOrderServiceRpcClient.queryLatestMealMenuRecordsByClientIds(enterpriseId, clientIds).stream().collect(Collectors.toMap(SingleMealMenuRecordRpcResponse::getClientId, Function.identity())); |
| 68 | // 构建创建请求 | 109 | // 构建创建请求 |
| 69 | - final var creations = notReservedDiners.stream().map(diner -> toMealOrderCreation(diner, clientMap, gradeClassMap, latestMealMenuRecordMap, nextWeekStart)).filter(Objects::nonNull).toList(); | 110 | + final var creations = notReservedDiners.stream().map(diner -> toMealOrderCreation(diner, clientMap, gradeClassMap, latestMealMenuRecordMap, mpAccountDinerRefMap, nextWeekStart)).filter(Objects::nonNull).toList(); |
| 70 | if (creations.isEmpty()) { | 111 | if (creations.isEmpty()) { |
| 71 | log.info("无可创建自动订餐项,跳过任务"); | 112 | log.info("无可创建自动订餐项,跳过任务"); |
| 72 | return; | 113 | return; |
| ... | @@ -78,21 +119,25 @@ public class AutoCreateMealOrderTask { | ... | @@ -78,21 +119,25 @@ public class AutoCreateMealOrderTask { |
| 78 | .build(); | 119 | .build(); |
| 79 | mealOrderServiceRpcClient.batchCreateMealOrders(loginInfo, creations); | 120 | mealOrderServiceRpcClient.batchCreateMealOrders(loginInfo, creations); |
| 80 | log.info("本周未订餐学生已自动补单 {} 条", creations.size()); | 121 | log.info("本周未订餐学生已自动补单 {} 条", creations.size()); |
| 122 | + // 标记本周已执行 | ||
| 123 | + weeklyTaskStore.markExecuted(keyPrefix, enterpriseId, today); | ||
| 81 | } | 124 | } |
| 82 | 125 | ||
| 83 | private MealOrderCreation toMealOrderCreation(SingleDinerRpcResponse diner, | 126 | private MealOrderCreation toMealOrderCreation(SingleDinerRpcResponse diner, |
| 84 | Map<Integer, SingleClientRpcResponse> clientMap, | 127 | Map<Integer, SingleClientRpcResponse> clientMap, |
| 85 | Map<Integer, SingleGradeClassRpcResponse> classMap, | 128 | Map<Integer, SingleGradeClassRpcResponse> classMap, |
| 86 | Map<Integer, SingleMealMenuRecordRpcResponse> menuMap, | 129 | Map<Integer, SingleMealMenuRecordRpcResponse> menuMap, |
| 130 | + Map<Integer, SingleMpAccountDinerRefRpcResponse> mpAccountDinerRefMap, | ||
| 87 | ZonedDateTime startOfNextWeek) { | 131 | ZonedDateTime startOfNextWeek) { |
| 88 | final var menu = menuMap.get(diner.getClientId()); | 132 | final var menu = menuMap.get(diner.getClientId()); |
| 89 | final var client = clientMap.get(diner.getClientId()); | 133 | final var client = clientMap.get(diner.getClientId()); |
| 90 | final var gradeClass = classMap.get(diner.getClassId()); | 134 | final var gradeClass = classMap.get(diner.getClassId()); |
| 91 | - if (menu == null || client == null || gradeClass == null) return null; | 135 | + final var mpAccountDinerRef = mpAccountDinerRefMap.get(diner.getId()); |
| 136 | + if (menu == null || client == null || gradeClass == null || mpAccountDinerRef == null) return null; | ||
| 92 | return MealOrderCreation.newBuilder() | 137 | return MealOrderCreation.newBuilder() |
| 93 | .setClientId(diner.getClientId()) | 138 | .setClientId(diner.getClientId()) |
| 94 | .setMenuId(menu.getId()) | 139 | .setMenuId(menu.getId()) |
| 95 | - .setAccountId(0) | 140 | + .setAccountId(mpAccountDinerRef.getId()) |
| 96 | .setOrderMethod(MealOrderOrderMethodEnum.MEAL_ORDER_METHOD_SYSTEM) | 141 | .setOrderMethod(MealOrderOrderMethodEnum.MEAL_ORDER_METHOD_SYSTEM) |
| 97 | .setDinerId(diner.getId()) | 142 | .setDinerId(diner.getId()) |
| 98 | .setDinerName(diner.getName()) | 143 | .setDinerName(diner.getName()) |
| ... | @@ -105,6 +150,11 @@ public class AutoCreateMealOrderTask { | ... | @@ -105,6 +150,11 @@ public class AutoCreateMealOrderTask { |
| 105 | .build(); | 150 | .build(); |
| 106 | } | 151 | } |
| 107 | 152 | ||
| 153 | + private LocalDate getThisWeekDay(LocalDate now, DayOfWeek target) { | ||
| 154 | + LocalDate monday = now.with(DayOfWeek.MONDAY); | ||
| 155 | + return monday.plusDays(target.getValue() - 1L); | ||
| 156 | + } | ||
| 157 | + | ||
| 108 | private List<MenuSchedule> buildNextWeekMeals(ZonedDateTime nextWeekStart) { | 158 | private List<MenuSchedule> buildNextWeekMeals(ZonedDateTime nextWeekStart) { |
| 109 | return IntStream.range(0, 5) | 159 | return IntStream.range(0, 5) |
| 110 | .mapToObj(i -> MenuSchedule.newBuilder() | 160 | .mapToObj(i -> MenuSchedule.newBuilder() | ... | ... |
| ... | @@ -26,7 +26,6 @@ import java.time.DayOfWeek; | ... | @@ -26,7 +26,6 @@ import java.time.DayOfWeek; |
| 26 | import java.time.LocalDate; | 26 | import java.time.LocalDate; |
| 27 | import java.time.LocalDateTime; | 27 | import java.time.LocalDateTime; |
| 28 | import java.time.LocalTime; | 28 | import java.time.LocalTime; |
| 29 | -import java.time.temporal.TemporalAdjusters; | ||
| 30 | import java.util.ArrayList; | 29 | import java.util.ArrayList; |
| 31 | import java.util.Collections; | 30 | import java.util.Collections; |
| 32 | import java.util.List; | 31 | import java.util.List; |
| ... | @@ -50,14 +49,23 @@ public class MealOrderServiceImpl implements MealOrderService { | ... | @@ -50,14 +49,23 @@ public class MealOrderServiceImpl implements MealOrderService { |
| 50 | final var lastWeekStart = today.minusWeeks(1).with(DayOfWeek.MONDAY).atStartOfDay().atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli(); | 49 | final var lastWeekStart = today.minusWeeks(1).with(DayOfWeek.MONDAY).atStartOfDay().atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli(); |
| 51 | final var lastWeekEnd = today.minusWeeks(1).with(DayOfWeek.SUNDAY).atTime(LocalTime.MAX).atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli(); | 50 | final var lastWeekEnd = today.minusWeeks(1).with(DayOfWeek.SUNDAY).atTime(LocalTime.MAX).atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli(); |
| 52 | final var thisWeekStart = today.with(DayOfWeek.MONDAY).atStartOfDay().atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli(); | 51 | final var thisWeekStart = today.with(DayOfWeek.MONDAY).atStartOfDay().atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli(); |
| 52 | + final var thisWeekEnd = today.with(DayOfWeek.SUNDAY).atTime(LocalTime.MAX).atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli(); | ||
| 53 | if (queryMealOrderDTO.getStatus() == QueryMealOrderStatusEnum.COMPLETED) { | 53 | if (queryMealOrderDTO.getStatus() == QueryMealOrderStatusEnum.COMPLETED) { |
| 54 | - mealOrderRpcResponses = mealOrderRpcResponses.stream().filter(e -> e.getReserveDate() < lastWeekStart).toList(); | 54 | + mealOrderRpcResponses = mealOrderRpcResponses.stream() |
| 55 | + .filter(e -> e.getReserveDate() < lastWeekStart) | ||
| 56 | + .toList(); | ||
| 55 | } else if (queryMealOrderDTO.getStatus() == QueryMealOrderStatusEnum.UNDER_WAY) { | 57 | } else if (queryMealOrderDTO.getStatus() == QueryMealOrderStatusEnum.UNDER_WAY) { |
| 56 | - mealOrderRpcResponses = mealOrderRpcResponses.stream().filter(e -> e.getReserveDate() >= lastWeekStart && e.getReserveDate() <= lastWeekEnd).toList(); | 58 | + mealOrderRpcResponses = mealOrderRpcResponses.stream() |
| 59 | + .filter(e -> e.getReserveDate() >= lastWeekStart && e.getReserveDate() <= lastWeekEnd) | ||
| 60 | + .toList(); | ||
| 57 | } else if (queryMealOrderDTO.getStatus() == QueryMealOrderStatusEnum.BE_BOOKED) { | 61 | } else if (queryMealOrderDTO.getStatus() == QueryMealOrderStatusEnum.BE_BOOKED) { |
| 58 | - mealOrderRpcResponses = mealOrderRpcResponses.stream().filter(e -> e.getReserveDate() > thisWeekStart).toList(); | 62 | + mealOrderRpcResponses = mealOrderRpcResponses.stream() |
| 63 | + .filter(e -> e.getReserveDate() >= thisWeekStart && e.getReserveDate() <= thisWeekEnd) | ||
| 64 | + .toList(); | ||
| 59 | } | 65 | } |
| 60 | - return mealOrderRpcResponses.stream().map(this::getMealOrderById).toList(); | 66 | + return mealOrderRpcResponses.stream() |
| 67 | + .map(this::getMealOrderById) | ||
| 68 | + .toList(); | ||
| 61 | } | 69 | } |
| 62 | 70 | ||
| 63 | @Override | 71 | @Override |
| ... | @@ -170,8 +178,13 @@ public class MealOrderServiceImpl implements MealOrderService { | ... | @@ -170,8 +178,13 @@ public class MealOrderServiceImpl implements MealOrderService { |
| 170 | final var minDay = Collections.min(enabledDays); | 178 | final var minDay = Collections.min(enabledDays); |
| 171 | final var maxDay = Collections.max(enabledDays); | 179 | final var maxDay = Collections.max(enabledDays); |
| 172 | final var today = now.toLocalDate(); | 180 | final var today = now.toLocalDate(); |
| 173 | - final var startDateTime = today.with(TemporalAdjusters.previousOrSame(minDay)).atTime(startTime); | 181 | + final var startDateTime = getThisWeekDate(today, minDay).atTime(startTime); |
| 174 | - final var endDateTime = today.with(TemporalAdjusters.nextOrSame(maxDay)).atTime(endTime); | 182 | + final var endDateTime = getThisWeekDate(today,maxDay).atTime(endTime); |
| 175 | return !now.isBefore(startDateTime) && !now.isAfter(endDateTime); | 183 | return !now.isBefore(startDateTime) && !now.isAfter(endDateTime); |
| 176 | } | 184 | } |
| 185 | + | ||
| 186 | + private static LocalDate getThisWeekDate(LocalDate now, DayOfWeek day) { | ||
| 187 | + LocalDate monday = now.with(DayOfWeek.MONDAY); | ||
| 188 | + return monday.plusDays(day.getValue() - 1L); // MONDAY 是 1,SUNDAY 是 7 | ||
| 189 | + } | ||
| 177 | } | 190 | } | ... | ... |
| 1 | +package com.infoloop.tianting.store; | ||
| 2 | + | ||
| 3 | +import io.lettuce.core.SetArgs; | ||
| 4 | +import io.lettuce.core.api.sync.RedisCommands; | ||
| 5 | + | ||
| 6 | +import java.time.DayOfWeek; | ||
| 7 | +import java.time.LocalDate; | ||
| 8 | +import java.time.temporal.WeekFields; | ||
| 9 | + | ||
| 10 | +public class WeeklyTaskStore { | ||
| 11 | + | ||
| 12 | + private final RedisCommands<String, String> commands; | ||
| 13 | + private final long expire; // 过期时间(秒) | ||
| 14 | + | ||
| 15 | + public WeeklyTaskStore(final RedisCommands<String, String> commands, final long expire) { | ||
| 16 | + this.commands = commands; | ||
| 17 | + this.expire = expire; | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + public boolean isExecutedThisWeek(String keyPrefix, int enterpriseId, LocalDate date) { | ||
| 21 | + String key = getWeeklyKey(keyPrefix, enterpriseId, date); | ||
| 22 | + return commands.exists(key) > 0; | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + public void markExecuted(String keyPrefix, int enterpriseId, LocalDate date) { | ||
| 26 | + String key = getWeeklyKey(keyPrefix, enterpriseId, date); | ||
| 27 | + commands.set(key, "1", new SetArgs().ex(expire)); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + private String getWeeklyKey(String keyPrefix, int enterpriseId, LocalDate date) { | ||
| 31 | + WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY, 1); | ||
| 32 | + int year = date.getYear(); | ||
| 33 | + int week = date.get(weekFields.weekOfWeekBasedYear()); | ||
| 34 | + return String.format("%s:%d:%d-W%d", keyPrefix, enterpriseId, year, week); | ||
| 35 | + } | ||
| 36 | +} |
-
Please register or login to post a comment