chen.yinxiang

Merge branch 'feat/nongxin-notifications' of http://git.infoloop.cn/jiujian/clie…

…nt-customer-order-api into feat/nongxin-notifications

# Conflicts:
#	src/main/java/com/infoloop/tianting/logic/task/OrderReminderTask.java
#	src/main/java/com/infoloop/tianting/service/OrderReminderService.java
#	src/main/java/com/infoloop/tianting/service/impl/OrderReminderServiceImpl.java
package com.infoloop.tianting.logic.task;
import com.infoloop.tianting.deliveryruleservice.Rule;
import com.infoloop.tianting.mealorderservice.PendingOrderSubscriptionMessageRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMpAccountRpcResponse;
import com.infoloop.tianting.model.dto.WxUserDto.SendSubscriptionMessageResponse;
......@@ -13,8 +12,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
......@@ -46,14 +43,19 @@ public class OrderReminderTask {
private static final int ENTERPRISE_ID = 449;
/**
* 用餐类型
*/
private static final String MEAL_TYPE = "下次订餐即将开启";
/**
* 温馨提醒内容
*/
private static final String TIPS = "请点击卡片,准时进入小程序完成预订";
/**
* 订餐时间配置
* 订餐时间配置(格式:HH:mm~HH:mm)
*/
private record OrderTimeConfig(String startTime, String endTime) {}
private record OrderTimeConfig(String orderTime) {}
private final MealOrderServiceRpcClient mealOrderServiceRpcClient;
private final DeliveryRuleServiceRpcClient deliveryRuleServiceRpcClient;
......@@ -83,9 +85,9 @@ public class OrderReminderTask {
OrderTimeConfig orderTimeConfig = getOrderTimeConfigFromRule();
if (orderTimeConfig == null) {
log.warn("Failed to get order time config from rule, using default");
orderTimeConfig = new OrderTimeConfig("请查看小程序", "请查看小程序");
orderTimeConfig = new OrderTimeConfig("请查看小程序");
}
log.info("Order time config: startTime={}, endTime={}", orderTimeConfig.startTime(), orderTimeConfig.endTime());
log.info("Order time config: orderTime={}", orderTimeConfig.orderTime());
// 2. 查询所有待发送的订阅消息(未删除的记录)
List<PendingOrderSubscriptionMessageRpcResponse> pendingMessages =
......@@ -176,7 +178,7 @@ public class OrderReminderTask {
/**
* 从配送规则配置中获取订餐时间配置
* 返回开始时间和结束时间,格式:周x xx:xx
* 返回订餐时间,格式:yyyy年MM月dd日 HH:mm~HH:mm
*/
private OrderTimeConfig getOrderTimeConfigFromRule() {
try {
......@@ -195,37 +197,19 @@ public class OrderReminderTask {
return null;
}
// 获取启用的日期
List<DayOfWeek> enabledDays = getEnabledDays(cfg);
if (enabledDays.isEmpty()) {
log.warn("No enabled days in delivery rule");
return null;
}
// 格式化时间(去掉秒)
String startTime = formatTime(startTimeStr);
String endTime = formatTime(endTimeStr);
// 获取第一个和最后一个启用日
DayOfWeek firstDay = enabledDays.get(0);
DayOfWeek lastDay = enabledDays.get(enabledDays.size() - 1);
// 计算本周的实际日期(微信time类型需要具体日期格式)
LocalDate today = LocalDate.now();
LocalDate startDate = today.with(java.time.temporal.TemporalAdjusters.nextOrSame(firstDay));
LocalDate endDate = today.with(java.time.temporal.TemporalAdjusters.nextOrSame(lastDay));
// 如果结束日期在开始日期之前,说明跨周了,结束日期加一周
if (endDate.isBefore(startDate)) {
endDate = endDate.plusWeeks(1);
}
// 格式化为微信接受的格式:yyyy年MM月dd日 HH:mm
// 获取当前日期,格式化为 yyyy年MM月dd日 HH:mm
java.time.LocalDate today = java.time.LocalDate.now();
java.time.format.DateTimeFormatter dateFormatter = java.time.format.DateTimeFormatter.ofPattern("yyyy年MM月dd日");
String formattedStartTime = startDate.format(dateFormatter) + " " + startTime;
String formattedEndTime = endDate.format(dateFormatter) + " " + endTime;
String dateStr = today.format(dateFormatter);
// 返回订餐时间,格式:yyyy年MM月dd日 HH:mm~yyyy年MM月dd日 HH:mm
String orderTime = dateStr + " " + startTime + "~" + dateStr + " " + endTime;
return new OrderTimeConfig(formattedStartTime, formattedEndTime);
return new OrderTimeConfig(orderTime);
} catch (Exception e) {
log.error("Failed to get order time config from rule", e);
......@@ -234,21 +218,6 @@ public class OrderReminderTask {
}
/**
* 获取启用的日期列表(按周一到周日排序)
*/
private List<DayOfWeek> getEnabledDays(Rule cfg) {
List<DayOfWeek> enabledDays = new ArrayList<>();
if (Boolean.TRUE.equals(cfg.getMonday())) enabledDays.add(DayOfWeek.MONDAY);
if (Boolean.TRUE.equals(cfg.getTuesday())) enabledDays.add(DayOfWeek.TUESDAY);
if (Boolean.TRUE.equals(cfg.getWednesday())) enabledDays.add(DayOfWeek.WEDNESDAY);
if (Boolean.TRUE.equals(cfg.getThursday())) enabledDays.add(DayOfWeek.THURSDAY);
if (Boolean.TRUE.equals(cfg.getFriday())) enabledDays.add(DayOfWeek.FRIDAY);
if (Boolean.TRUE.equals(cfg.getSaturday())) enabledDays.add(DayOfWeek.SATURDAY);
if (Boolean.TRUE.equals(cfg.getSunday())) enabledDays.add(DayOfWeek.SUNDAY);
return enabledDays;
}
/**
* 格式化时间字符串(HH:mm:ss -> HH:mm)
*/
private String formatTime(String timeStr) {
......@@ -275,10 +244,10 @@ public class OrderReminderTask {
/**
* 发送单条提醒消息
*
* 小程序模板字段:
* - time4: 开始时间(周x xx:xx
* - time5: 结束时间(周x xx:xx
* - thing1: 温馨提醒
* 小程序模板字段(模板ID: BCROwaS_oj1_b0fzc_qrgvtSeCtfxctghcLMu-Obkfw)
* - thing8: 用餐类型(如:下次订单即将开始
* - time1: 订餐时间(如:13:00~21:00
* - thing2: 温馨提示
*/
private boolean sendReminderMessage(String openId, PendingOrderSubscriptionMessageRpcResponse message, OrderTimeConfig orderTimeConfig) {
String jumpPath = message.getJumpPath();
......@@ -287,9 +256,9 @@ public class OrderReminderTask {
SendSubscriptionMessageResponse response = orderReminderService.sendOrderReminder(
openId,
jumpPath,
orderTimeConfig.startTime(), // time4: 开始时间
orderTimeConfig.endTime(), // time5: 结束时间
TIPS // thing1: 温馨提醒
MEAL_TYPE, // thing8: 用餐类型
orderTimeConfig.orderTime(), // time1: 订餐时间
TIPS // thing2: 温馨提示
);
// 判断发送结果
......
......@@ -10,18 +10,18 @@ public interface OrderReminderService {
/**
* 发送订餐提醒消息
*
* 小程序模板字段(模板ID: LtCsW7ciF0edUwNwt3h5C_ZCIRzOeO7MnvozRl2CxlE):
* - time4: 开始时间
* - time5: 结束时间
* - thing1: 温馨提醒
* 小程序模板字段(模板ID: BCROwaS_oj1_b0fzc_qrgvtSeCtfxctghcLMu-Obkfw):
* - thing8: 用餐类型(如:下次订单即将开始)
* - time1: 订餐时间(如:13:00~21:00)
* - thing2: 温馨提示(如:为了保证您明日正常用餐,立即订餐!)
*
* @param openId 用户 OpenID(小程序的 openId)
* @param page 点击跳转小程序页面路径
* @param startTime 开始时间,例如:"周一 09:00"
* @param endTime 结束时间,例如:"周四 18:00"
* @param tips 温馨提醒,例如:"请点击卡片,准时进入小程序完成预订"
* @param mealType 用餐类型,例如:"下次订单即将开始"
* @param orderTime 订餐时间,例如:"13:00~21:00"
* @param tips 温馨提示,例如:"为了保证您明日正常用餐,立即订餐!"
* @return 发送结果
*/
SendSubscriptionMessageResponse sendOrderReminder(String openId, String page,
String startTime, String endTime, String tips);
String mealType, String orderTime, String tips);
}
......
......@@ -18,10 +18,10 @@ import static com.infoloop.tianting.constant.ConfigConstants.MINI_PROGRAM_ORDER_
* 订餐提醒服务实现
* 使用小程序订阅消息接口发送提醒
*
* 小程序模板字段(模板ID: LtCsW7ciF0edUwNwt3h5C_ZCIRzOeO7MnvozRl2CxlE):
* - time4: 开始时间
* - time5: 结束时间
* - thing1: 温馨提醒
* 小程序模板字段(模板ID: BCROwaS_oj1_b0fzc_qrgvtSeCtfxctghcLMu-Obkfw):
* - thing8: 用餐类型(如:下次订单即将开始)
* - time1: 订餐时间(如:13:00~21:00)
* - thing2: 温馨提示(如:为了保证您明日正常用餐,立即订餐!)
*
* 注意:
* 1. 使用的是小程序的 access_token 和 template_id
......@@ -40,29 +40,29 @@ public class OrderReminderServiceImpl implements OrderReminderService {
@Override
public SendSubscriptionMessageResponse sendOrderReminder(String openId,
String page,
String startTime,
String endTime,
String mealType,
String orderTime,
String tips) {
log.info("Sending order reminder via MiniProgram to openId: {}, page: {}, startTime: {}, endTime: {}, tips: {}",
openId, page, startTime, endTime, tips);
log.info("Sending order reminder via MiniProgram to openId: {}, page: {}, mealType: {}, orderTime: {}, tips: {}",
openId, page, mealType, orderTime, tips);
// 构建小程序订阅消息模板数据
Map<String, Object> data = new HashMap<>();
// time4: 开始时间
Map<String, String> time4Value = new HashMap<>();
time4Value.put("value", startTime);
data.put("time4", time4Value);
// thing8: 用餐类型(如:下次订单即将开始)
Map<String, String> thing8Value = new HashMap<>();
thing8Value.put("value", mealType);
data.put("thing8", thing8Value);
// time5: 结束时间
Map<String, String> time5Value = new HashMap<>();
time5Value.put("value", endTime);
data.put("time5", time5Value);
// time1: 订餐时间(如:13:00~21:00)
Map<String, String> time1Value = new HashMap<>();
time1Value.put("value", orderTime);
data.put("time1", time1Value);
// thing1: 温馨提醒
Map<String, String> thing1Value = new HashMap<>();
thing1Value.put("value", tips);
data.put("thing1", thing1Value);
// thing2: 温馨提示
Map<String, String> thing2Value = new HashMap<>();
thing2Value.put("value", tips);
data.put("thing2", thing2Value);
try {
// 使用小程序订阅消息接口
......