预约订单槽点列表
This commit is contained in:
parent
9b5c618c40
commit
4ff892d09b
@ -0,0 +1,78 @@
|
||||
package com.suisung.mall.common.pojo.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 预订参数DTO实体类
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@ApiModel(value = "预约订单参数DTO", description = "预约订单参数DTO")
|
||||
public class BookingArgDTO {
|
||||
|
||||
/**
|
||||
* 日期标题(如"今天(周二)")
|
||||
*/
|
||||
@ApiModelProperty(value = "日期标题")
|
||||
private String date_title;
|
||||
|
||||
/**
|
||||
* 日期字符串(如"01月09日")
|
||||
*/
|
||||
@ApiModelProperty(value = "日期字符串")
|
||||
private String date_str;
|
||||
|
||||
/**
|
||||
* 日期(如"2025-01-09")
|
||||
*/
|
||||
@ApiModelProperty(value = "日期")
|
||||
private String date;
|
||||
|
||||
/**
|
||||
* 时间项列表
|
||||
*/
|
||||
@ApiModelProperty(value = "时间项列表")
|
||||
private List<BookingArgItem> items;
|
||||
|
||||
/**
|
||||
* 预订时间项实体类
|
||||
*/
|
||||
@Data
|
||||
public static class BookingArgItem {
|
||||
|
||||
/**
|
||||
* 时间标题(如"立即送出"或"09:15-09:45")
|
||||
*/
|
||||
@ApiModelProperty(value = "时间标题")
|
||||
private String time_title;
|
||||
|
||||
/**
|
||||
* 预订时间戳
|
||||
*/
|
||||
@ApiModelProperty(value = "预订时间戳")
|
||||
private Long booking_at;
|
||||
|
||||
/**
|
||||
* 预订状态
|
||||
*/
|
||||
@ApiModelProperty(value = "预订状态:1-立即下单;2-预约下单;")
|
||||
private Integer booking_state;
|
||||
|
||||
/**
|
||||
* 预订开始时间
|
||||
*/
|
||||
@ApiModelProperty(value = "预订开始时间")
|
||||
private String booking_begin_time;
|
||||
|
||||
/**
|
||||
* 预订结束时间
|
||||
*/
|
||||
@ApiModelProperty(value = "预订结束时间")
|
||||
private String booking_end_time;
|
||||
}
|
||||
}
|
||||
@ -178,6 +178,23 @@ public class DateTimeUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据日期获取星期几
|
||||
*
|
||||
* @param date 日期
|
||||
* @return 星期几
|
||||
*/
|
||||
public static String getWeekOfDate(Date date) {
|
||||
String[] weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
|
||||
if (w < 0) {
|
||||
w = 0;
|
||||
}
|
||||
return weekDays[w];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将多种日期格式转换为 yyyy-MM-dd
|
||||
@ -473,6 +490,7 @@ public class DateTimeUtils {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断时间字符串是否与格式模式匹配
|
||||
*
|
||||
|
||||
@ -12,6 +12,7 @@ import com.suisung.mall.common.api.StateCode;
|
||||
import com.suisung.mall.common.domain.UserDto;
|
||||
import com.suisung.mall.common.exception.ApiException;
|
||||
import com.suisung.mall.common.modules.order.*;
|
||||
import com.suisung.mall.common.pojo.dto.BookingArgDTO;
|
||||
import com.suisung.mall.common.service.impl.BaseControllerImpl;
|
||||
import com.suisung.mall.common.utils.CheckUtil;
|
||||
import com.suisung.mall.shop.order.service.*;
|
||||
@ -321,6 +322,13 @@ public class UserOrderController extends BaseControllerImpl {
|
||||
return CommonResult.success(data);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "可预约订单的时间槽", notes = "可预约订单的时间槽")
|
||||
@RequestMapping(value = "/booking_time_args", method = RequestMethod.GET)
|
||||
public CommonResult listInvoice(@RequestParam(name = "store_id", defaultValue = "0") Integer store_id) {
|
||||
List<BookingArgDTO> list = shopOrderInfoService.genBookingOrderArgList(store_id);
|
||||
return CommonResult.success(list);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package com.suisung.mall.shop.order.service;
|
||||
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderInfo;
|
||||
import com.suisung.mall.common.pojo.dto.BookingArgDTO;
|
||||
import com.suisung.mall.core.web.service.IBaseService;
|
||||
import org.springframework.data.util.Pair;
|
||||
|
||||
@ -133,4 +134,13 @@ public interface ShopOrderInfoService extends IBaseService<ShopOrderInfo> {
|
||||
* @return
|
||||
*/
|
||||
Pair<Boolean, String> runBookingOrder2SfExpressOrder(String orderId);
|
||||
|
||||
|
||||
/**
|
||||
* 根据店铺的营业时间范围生成可预约下单的参数
|
||||
*
|
||||
* @param storeId 店铺ID
|
||||
* @return
|
||||
*/
|
||||
List<BookingArgDTO> genBookingOrderArgList(Integer storeId);
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ import com.suisung.mall.common.modules.pay.PayPlantformResource;
|
||||
import com.suisung.mall.common.modules.plantform.ShopPlantformFeedback;
|
||||
import com.suisung.mall.common.modules.product.ShopProductComment;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreInfo;
|
||||
import com.suisung.mall.common.pojo.dto.BookingArgDTO;
|
||||
import com.suisung.mall.common.pojo.res.ThirdApiRes;
|
||||
import com.suisung.mall.common.utils.CheckUtil;
|
||||
import com.suisung.mall.common.utils.CommonUtil;
|
||||
@ -137,6 +138,7 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
@Autowired
|
||||
private ThreadPoolExecutor executor;
|
||||
|
||||
|
||||
@Override
|
||||
public Map dashboard() {
|
||||
|
||||
@ -197,7 +199,6 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
return Convert.toList(String.class, findKey(queryWrapper));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取能自动确认收货的订单号
|
||||
*
|
||||
@ -826,7 +827,6 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getAutoCancelOrderIdByPage(Integer pageNum, Integer pageSize) {
|
||||
QueryWrapper<ShopOrderInfo> queryWrapper = new QueryWrapper<>();
|
||||
@ -1014,5 +1014,201 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据店铺的营业时间范围生成可预约下单的参数
|
||||
*
|
||||
* @param storeId 店铺ID
|
||||
* @return 预约参数列表
|
||||
*/
|
||||
@Override
|
||||
public List<BookingArgDTO> genBookingOrderArgList(Integer storeId) {
|
||||
// 初始化默认营业时间
|
||||
String openingHours = "09:00";
|
||||
String closeHours = "18:00";
|
||||
|
||||
// 如果storeId不为空,则尝试获取店铺信息
|
||||
if (storeId != null) {
|
||||
try {
|
||||
ShopStoreInfo shopStoreInfo = shopStoreInfoService.getShopStoreInfoByStoreId(storeId);
|
||||
if (shopStoreInfo != null) {
|
||||
// 检查并使用店铺设置的营业时间
|
||||
if (StrUtil.isNotBlank(shopStoreInfo.getStore_opening_hours())) {
|
||||
openingHours = shopStoreInfo.getStore_opening_hours();
|
||||
}
|
||||
if (StrUtil.isNotBlank(shopStoreInfo.getStore_close_hours())) {
|
||||
closeHours = shopStoreInfo.getStore_close_hours();
|
||||
}
|
||||
logger.debug("[生成预约参数] 使用店铺营业时间,storeId: {}, opening: {}, close: {}", storeId, openingHours, closeHours);
|
||||
} else {
|
||||
logger.warn("[生成预约参数] 未找到店铺信息,使用默认营业时间,storeId: {}", storeId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("[生成预约参数] 获取店铺信息异常,使用默认营业时间,storeId: {}", storeId, e);
|
||||
}
|
||||
} else {
|
||||
logger.warn("[生成预约参数] 店铺ID为空,使用默认营业时间");
|
||||
}
|
||||
|
||||
List<BookingArgDTO> result = new ArrayList<>();
|
||||
|
||||
// 生成未来7天的数据
|
||||
Date now = new Date();
|
||||
for (int i = 0; i < 7; i++) {
|
||||
Date currentDate = DateUtil.offsetDay(now, i);
|
||||
BookingArgDTO bookingArgDTO = new BookingArgDTO();
|
||||
|
||||
// 设置日期相关信息
|
||||
String dateStr = DateUtil.format(currentDate, "yyyy-MM-dd");
|
||||
String displayDateStr = DateUtil.format(currentDate, "MM月dd日");
|
||||
|
||||
// 安全获取星期信息
|
||||
String weekStr = "未知";
|
||||
try {
|
||||
weekStr = DateTimeUtils.getWeekOfDate(currentDate);
|
||||
} catch (Exception e) {
|
||||
logger.warn("[生成预约参数] 获取星期信息异常,使用默认值,date: {}", dateStr);
|
||||
}
|
||||
|
||||
// 设置date_title
|
||||
if (i == 0) {
|
||||
bookingArgDTO.setDate_title("今天(" + weekStr + ")");
|
||||
} else if (i == 1) {
|
||||
bookingArgDTO.setDate_title("明天(" + weekStr + ")");
|
||||
} else {
|
||||
bookingArgDTO.setDate_title(displayDateStr + "(" + weekStr + ")");
|
||||
}
|
||||
|
||||
bookingArgDTO.setDate_str(displayDateStr);
|
||||
bookingArgDTO.setDate(dateStr);
|
||||
|
||||
// 生成时间项
|
||||
List<BookingArgDTO.BookingArgItem> items = generateTimeSlots(dateStr, openingHours, closeHours, i == 0);
|
||||
bookingArgDTO.setItems(items != null ? items : new ArrayList<>());
|
||||
|
||||
result.add(bookingArgDTO);
|
||||
}
|
||||
|
||||
logger.debug("[生成预约参数] 成功生成预约参数,storeId: {}, opening: {}, close: {}, 参数数量: {}",
|
||||
storeId, openingHours, closeHours, result.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成时间槽列表
|
||||
*
|
||||
* @param dateStr 日期字符串 yyyy-MM-dd
|
||||
* @param openingHours 开始营业时间 HH:mm
|
||||
* @param closeHours 结束营业时间 HH:mm
|
||||
* @param isToday 是否是今天
|
||||
* @return 时间槽列表
|
||||
*/
|
||||
private List<BookingArgDTO.BookingArgItem> generateTimeSlots(String dateStr, String openingHours, String closeHours, boolean isToday) {
|
||||
// 参数校验
|
||||
if (StrUtil.isBlank(dateStr) || StrUtil.isBlank(openingHours) || StrUtil.isBlank(closeHours)) {
|
||||
logger.warn("[生成时间槽] 参数为空,dateStr: {}, openingHours: {}, closeHours: {}", dateStr, openingHours, closeHours);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
try {
|
||||
List<BookingArgDTO.BookingArgItem> items = new ArrayList<>();
|
||||
|
||||
// 添加"立即送出"选项(仅限今天)
|
||||
if (isToday) {
|
||||
BookingArgDTO.BookingArgItem immediateItem = new BookingArgDTO.BookingArgItem();
|
||||
immediateItem.setTime_title("立即送出");
|
||||
immediateItem.setBooking_at(0L);
|
||||
immediateItem.setBooking_state(1);
|
||||
immediateItem.setBooking_begin_time("");
|
||||
immediateItem.setBooking_end_time("");
|
||||
items.add(immediateItem);
|
||||
}
|
||||
|
||||
// 解析营业时间
|
||||
Date openTime = DateUtil.parse(dateStr + " " + openingHours + ":00", "yyyy-MM-dd HH:mm:ss");
|
||||
Date closeTime = DateUtil.parse(dateStr + " " + closeHours + ":00", "yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
// 如果结束时间早于开始时间,说明跨天了,需要调整到第二天
|
||||
if (closeTime.before(openTime)) {
|
||||
closeTime = DateUtil.offsetDay(closeTime, 1);
|
||||
}
|
||||
|
||||
// 验证营业时间有效性
|
||||
if (openTime.after(closeTime)) {
|
||||
logger.warn("[生成时间槽] 营业时间无效,openTime: {}, closeTime: {}", openTime, closeTime);
|
||||
return items;
|
||||
}
|
||||
|
||||
// 对于今天,需要特殊处理:从当前时间+5分钟开始生成时间槽
|
||||
Date startTime = openTime;
|
||||
if (isToday) {
|
||||
// 当前时间+5分钟作为第二个时间槽的开始时间
|
||||
Date nowPlusFive = DateUtil.offsetMinute(new Date(), 5);
|
||||
// 如果当前时间+5分钟在营业时间范围内,则从该时间开始
|
||||
if (nowPlusFive.after(openTime) && nowPlusFive.before(closeTime)) {
|
||||
startTime = nowPlusFive;
|
||||
}
|
||||
// 如果当前时间+5分钟已经超过营业结束时间,则不生成后续时间槽
|
||||
else if (nowPlusFive.after(closeTime)) {
|
||||
logger.debug("[生成时间槽] 当前时间+5分钟已超过营业结束时间,不生成后续时间槽");
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
// 生成30分钟间隔的时间段
|
||||
Date currentTimeSlot = startTime;
|
||||
int slotCount = 0;
|
||||
final int MAX_SLOTS = 48; // 最多生成48个时间段,防止异常循环
|
||||
|
||||
while (currentTimeSlot.before(closeTime) && slotCount < MAX_SLOTS) {
|
||||
Date endTimeSlot = DateUtil.offsetMinute(currentTimeSlot, 30);
|
||||
|
||||
// 如果结束时间超过了营业结束时间,则使用营业结束时间
|
||||
if (endTimeSlot.after(closeTime)) {
|
||||
endTimeSlot = closeTime;
|
||||
}
|
||||
|
||||
// 创建时间段项(跳过"立即送出"项,因为已经添加过了)
|
||||
if (!(isToday && slotCount == 0 && items.size() > 0 && "立即送出".equals(items.get(0).getTime_title()))) {
|
||||
BookingArgDTO.BookingArgItem timeItem = new BookingArgDTO.BookingArgItem();
|
||||
String beginTimeStr = DateUtil.format(currentTimeSlot, "HH:mm");
|
||||
String endTimeStr = DateUtil.format(endTimeSlot, "HH:mm");
|
||||
|
||||
timeItem.setTime_title(beginTimeStr + "-" + endTimeStr);
|
||||
|
||||
// 修正时间戳计算
|
||||
long bookingAt = currentTimeSlot.getTime() / 1000;
|
||||
timeItem.setBooking_at(bookingAt);
|
||||
|
||||
timeItem.setBooking_state(2);
|
||||
timeItem.setBooking_begin_time(DateUtil.format(currentTimeSlot, "yyyy-MM-dd HH:mm:ss"));
|
||||
timeItem.setBooking_end_time(DateUtil.format(DateUtil.offsetMinute(currentTimeSlot, 40), "yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
items.add(timeItem);
|
||||
}
|
||||
|
||||
// 移动到下一个时间段
|
||||
currentTimeSlot = endTimeSlot;
|
||||
slotCount++;
|
||||
|
||||
// 防止时间相同导致的死循环
|
||||
if (currentTimeSlot.equals(startTime)) {
|
||||
logger.warn("[生成时间槽] 检测到时间循环,跳出循环");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (slotCount >= MAX_SLOTS) {
|
||||
logger.warn("[生成时间槽] 时间段数量超过最大限制,date: {}", dateStr);
|
||||
}
|
||||
|
||||
logger.debug("[生成时间槽] 成功生成时间槽,date: {}, 时间段数量: {}", dateStr, items.size());
|
||||
return items;
|
||||
} catch (Exception e) {
|
||||
logger.error("[生成时间槽] 生成时间槽异常,date: {}, openingHours: {}, closeHours: {}", dateStr, openingHours, closeHours, e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user