AutoCreateMealOrderTask.java
6.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package com.infoloop.tianting.logic.task;
import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.enums.LoginSourceEnum;
import com.infoloop.tianting.mealorderservice.MealOrderCreation;
import com.infoloop.tianting.mealorderservice.MealOrderOrderMethodEnum;
import com.infoloop.tianting.mealorderservice.MenuSchedule;
import com.infoloop.tianting.mealorderservice.SingleDinerRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleGradeClassRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMealMenuRecordRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMealOrderRpcResponse;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.MealOrderServiceRpcClient;
import com.infoloop.tianting.utils.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@Slf4j
@Component
@RequiredArgsConstructor
public class AutoCreateMealOrderTask {
private final MealOrderServiceRpcClient mealOrderServiceRpcClient;
private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
@Scheduled(cron = "59 59 23 ? * SUN")
public void executeTask() {
final int enterpriseId = 449;
final var today = LocalDate.now();
final var thisWeekStart = today.with(DayOfWeek.MONDAY).atStartOfDay().atZone(DateUtil.CHINA_ZONE);
final var thisWeekEnd = today.with(DayOfWeek.SUNDAY).atTime(LocalTime.MAX).atZone(DateUtil.CHINA_ZONE);
final var nextWeekStart = today.with(TemporalAdjusters.next(DayOfWeek.MONDAY)).atStartOfDay().atZone(DateUtil.CHINA_ZONE);
// 查询本周已订餐学生 ID
final var mealOrders = mealOrderServiceRpcClient.queryMealOrdersByCondition(enterpriseId, null, thisWeekStart.toInstant().toEpochMilli(), thisWeekEnd.toInstant().toEpochMilli());
final var dinerIds = mealOrders.stream().map(SingleMealOrderRpcResponse::getDinerId).collect(Collectors.toSet());
// 所有学生 & 未订餐学生
final var allDiners = mealOrderServiceRpcClient.queryDinersByCondition(enterpriseId, null, null, null);
final var notReservedDiners = allDiners.stream().filter(diner -> !dinerIds.contains(diner.getId())).toList();
if (notReservedDiners.isEmpty()) {
log.info("无未订餐学生,跳过自动订餐任务");
return;
}
// 所需关联数据查询
final var clientIds = notReservedDiners.stream().map(SingleDinerRpcResponse::getClientId).distinct().toList();
final var classIds = notReservedDiners.stream().map(SingleDinerRpcResponse::getClassId).distinct().toList();
final var clientMap = clientInventoryServiceRpcClient.getClientsByIds(enterpriseId, clientIds).getClientsList().stream().collect(Collectors.toMap(SingleClientRpcResponse::getId, Function.identity()));
final var gradeClassMap = mealOrderServiceRpcClient.getGradeClassesByIds(enterpriseId, classIds).stream().collect(Collectors.toMap(SingleGradeClassRpcResponse::getId, Function.identity()));
final var latestMealMenuRecordMap = mealOrderServiceRpcClient.queryLatestMealMenuRecordsByClientIds(enterpriseId, clientIds).stream().collect(Collectors.toMap(SingleMealMenuRecordRpcResponse::getClientId, Function.identity()));
// 构建创建请求
final var creations = notReservedDiners.stream().map(diner -> toMealOrderCreation(diner, clientMap, gradeClassMap, latestMealMenuRecordMap, nextWeekStart)).filter(Objects::nonNull).toList();
if (creations.isEmpty()) {
log.info("无可创建自动订餐项,跳过任务");
return;
}
final var loginInfo = LoginContextHolder.LoginInfo.builder()
.id(0)
.enterpriseId(enterpriseId)
.loginSource(LoginSourceEnum.MINI_PROGRAM)
.build();
mealOrderServiceRpcClient.batchCreateMealOrders(loginInfo, creations);
log.info("本周未订餐学生已自动补单 {} 条", creations.size());
}
private MealOrderCreation toMealOrderCreation(SingleDinerRpcResponse diner,
Map<Integer, SingleClientRpcResponse> clientMap,
Map<Integer, SingleGradeClassRpcResponse> classMap,
Map<Integer, SingleMealMenuRecordRpcResponse> menuMap,
ZonedDateTime startOfNextWeek) {
final var menu = menuMap.get(diner.getClientId());
final var client = clientMap.get(diner.getClientId());
final var gradeClass = classMap.get(diner.getClassId());
if (menu == null || client == null || gradeClass == null) return null;
return MealOrderCreation.newBuilder()
.setClientId(diner.getClientId())
.setMenuId(menu.getId())
.setAccountId(0)
.setOrderMethod(MealOrderOrderMethodEnum.MEAL_ORDER_METHOD_SYSTEM)
.setDinerId(diner.getId())
.setDinerName(diner.getName())
.setClientName(client.getName())
.setGradeName(gradeClass.getGradeName())
.setClassName(gradeClass.getClassName())
.setStudentNo(diner.getStudentNo())
.setReserveDate(Instant.now().toEpochMilli())
.addAllMeals(buildNextWeekMeals(startOfNextWeek))
.build();
}
private List<MenuSchedule> buildNextWeekMeals(ZonedDateTime nextWeekStart) {
return IntStream.range(0, 5)
.mapToObj(i -> MenuSchedule.newBuilder()
.setDate(nextWeekStart.plusDays(i).format(DateUtil.YYYY_MM_DD_LEFT_SYMBOL))
.setMenu("A")
.build())
.toList();
}
}