From 2ab449592029de6a0bf1e02a8c675183ddd24575 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Thu, 6 Nov 2025 00:57:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=B6=E9=97=B4=E6=A7=BD=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/modules/store/ShopStoreBase.java | 3 + .../mall/common/utils/DateTimeUtils.java | 67 ++++------ .../mobile/UserOrderController.java | 2 +- .../impl/ShopOrderInfoServiceImpl.java | 119 ++++++++++-------- .../mapper/store/ShopStoreBaseMapper.xml | 4 +- pom.xml | 27 ++++ 6 files changed, 125 insertions(+), 97 deletions(-) diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreBase.java b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreBase.java index 6d2aeb3b..89c1fa17 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreBase.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreBase.java @@ -83,6 +83,9 @@ public class ShopStoreBase implements Serializable { @ApiModelProperty(value = "店铺营业状态:1-营业中;2-已打烊;3-开业(活动)筹备中;") private Integer store_biz_state; + @ApiModelProperty(value = "开业(活动)筹备具体时间 yyyy-MM-dd HH:mm:ss;") + private Date store_biz_opening_dtime; + @ApiModelProperty(value = "上级店铺编号:创建店铺决定,所属分销商-不可更改! 佣金公平性考虑") private Integer shop_parent_id; diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/DateTimeUtils.java b/mall-common/src/main/java/com/suisung/mall/common/utils/DateTimeUtils.java index 499e9f8f..490c174f 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/utils/DateTimeUtils.java +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/DateTimeUtils.java @@ -1,5 +1,6 @@ package com.suisung.mall.common.utils; +import cn.hutool.core.util.StrUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.data.util.Pair; @@ -10,7 +11,10 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoField; -import java.util.*; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; @Slf4j public class DateTimeUtils { @@ -375,11 +379,11 @@ public class DateTimeUtils { * endTimeStr 结束时间字符串,支持格式如 HH:mm, HH:mm:ss, HH:mm:ss.SSS 等 * @return 返回一个Map,包含交集的时间段(startTimeStr和endTimeStr),如果无交集则返回空Map */ - public static Map findTimeInterSection(List> timeList) { + public static Pair findTimeInterSection(List> timeList) { // 参数校验 if (timeList == null || timeList.isEmpty()) { log.warn("时间段列表为空或null,无法计算交集"); - return new HashMap<>(); + return null; } try { @@ -387,14 +391,14 @@ public class DateTimeUtils { LocalTime earliestEndTime = null; // 遍历所有时间段 - for (Map timeMap : timeList) { - if (timeMap == null || !timeMap.containsKey("startTimeStr") || !timeMap.containsKey("endTimeStr")) { + for (Pair timeMap : timeList) { + if (timeMap == null || StrUtil.hasBlank(timeMap.getFirst(), timeMap.getSecond())) { log.warn("时间段数据不完整或格式不正确: {}", timeMap); continue; } - String startTimeStr = timeMap.get("startTimeStr"); - String endTimeStr = timeMap.get("endTimeStr"); + String startTimeStr = timeMap.getFirst(); + String endTimeStr = timeMap.getSecond(); if (startTimeStr == null || endTimeStr == null) { log.warn("时间段的开始或结束时间为空: startTime={}, endTime={}", startTimeStr, endTimeStr); @@ -416,18 +420,15 @@ public class DateTimeUtils { // 检查是否存在交集 if (latestStartTime != null && earliestEndTime != null && !latestStartTime.isAfter(earliestEndTime)) { - Map result = new HashMap<>(); - result.put("startTimeStr", latestStartTime.toString()); - result.put("endTimeStr", earliestEndTime.toString()); - return result; + return Pair.of(latestStartTime.toString(), earliestEndTime.toString()); } else { // 无交集情况 log.debug("给定的时间段列表无交集"); - return new HashMap<>(); + return null; } } catch (Exception e) { log.error("计算时间段交集时发生异常", e); - return new HashMap<>(); + return null; } } @@ -619,38 +620,24 @@ public class DateTimeUtils { System.out.println("=== 测试 findTimeIntersection ==="); // 测试正常交集情况 - List> timeList1 = new ArrayList<>(); - Map range1 = new HashMap<>(); - range1.put("startTimeStr", "06:00"); - range1.put("endTimeStr", "17:00"); - timeList1.add(range1); + List> timeList1 = new ArrayList<>(); + timeList1.add(Pair.of("06:00", "17:00")); + timeList1.add(Pair.of("10:00", "18:00")); - Map range2 = new HashMap<>(); - range2.put("startTimeStr", "06:00"); - range2.put("endTimeStr", "17:00"); - timeList1.add(range2); - - Map intersection1 = findTimeInterSection(timeList1); + Pair intersection1 = findTimeInterSection(timeList1); System.out.println("交集结果1: " + intersection1); // 应该是 10:00 - 17:00 - // 测试无交集情况 - List> timeList2 = new ArrayList<>(); - Map range3 = new HashMap<>(); - range3.put("startTimeStr", "09:00"); - range3.put("endTimeStr", "12:00"); - timeList2.add(range3); +// 测试无交集情况 + List> timeList2 = new ArrayList<>(); + timeList2.add(Pair.of("09:00", "12:00")); + timeList2.add(Pair.of("13:00", "17:00")); - Map range4 = new HashMap<>(); - range4.put("startTimeStr", "13:00"); - range4.put("endTimeStr", "17:00"); - timeList2.add(range4); + Pair intersection2 = findTimeInterSection(timeList2); + System.out.println("交集结果2: " + intersection2); // 应该是null - Map intersection2 = findTimeInterSection(timeList2); - System.out.println("交集结果2: " + intersection2); // 应该是空Map - - // 测试空列表 - Map intersection3 = findTimeInterSection(null); - System.out.println("交集结果3 (null输入): " + intersection3); // 应该是空Map +// 测试空列表 + Pair intersection3 = findTimeInterSection(null); + System.out.println("交集结果3 (null输入): " + intersection3); // 应该是null } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/controller/mobile/UserOrderController.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/controller/mobile/UserOrderController.java index d45ca781..be5ed351 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/controller/mobile/UserOrderController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/controller/mobile/UserOrderController.java @@ -324,7 +324,7 @@ public class UserOrderController extends BaseControllerImpl { @ApiOperation(value = "可预约订单的时间槽", notes = "结算中心页面,可预约订单的时间槽") @RequestMapping(value = "/booking_time_args", method = RequestMethod.GET) - public CommonResult listInvoice(@RequestParam(name = "store_ids", defaultValue = "") String store_ids) { + public CommonResult genBookingOrderArgList(@RequestParam(name = "store_ids", defaultValue = "") String store_ids) { List list = shopOrderInfoService.genBookingOrderArgList(store_ids); return CommonResult.success(list); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java index fe787058..28eef942 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderInfoServiceImpl.java @@ -1016,93 +1016,104 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl genBookingOrderArgList(String storeIds) { - // 初始化默认营业时间 - Map timesMap = new HashMap<>(); + // 初始化营业时间对象 + Pair timesPair = null; // 如果storeId不为空,则尝试获取店铺信息 if (StrUtil.isNotBlank(storeIds)) { - List> timesMapList = selStoreBizTimeMapList(storeIds); + // 多个店铺的营业时间段集合 + List> timesMapList = selStoreBizTimeMapList(storeIds); if (!CollUtil.isEmpty(timesMapList)) { - timesMap = DateTimeUtils.findTimeInterSection(timesMapList); + // 获取多个店铺的营业时间段的一个交集 + timesPair = DateTimeUtils.findTimeInterSection(timesMapList); } } + if (timesPair == null || StrUtil.isBlank(timesPair.getFirst()) || StrUtil.isBlank(timesPair.getSecond())) { + // 没有具体的营业时间段 + logger.info("[生成预约参数] 未找到营业时间段"); + return Collections.emptyList(); + } + + + // 显示几天的时间槽,默认7天 + int daysCnt = 7; + List result = new ArrayList<>(); - // 生成未来7天的数据 - Date now = new Date(); - for (int i = 0; i < 7; i++) { - Date currentDate = DateUtil.offsetDay(now, i); + // 判断今天还能不能立即下单和预约下单?能:就有今天的时间槽;不能:就没有今天的时间槽 + boolean canBookingToday = DateTimeUtils.isTimeInRange(timesPair.getFirst(), timesPair.getSecond(), new Date()); + + // 生成7天的可预约时间槽数据 + Date startDate = new Date(); + if (!canBookingToday) { + // 如果今天不能下单和预约,则从明天开始生成时间槽 + startDate = DateUtil.offsetDay(new Date(), 1); + } + + for (int i = 0; i < daysCnt; i++) { + startDate = DateUtil.offsetDay(startDate, i); BookingArgDTO bookingArgDTO = new BookingArgDTO(); // 设置日期相关信息 - String dateStr = DateUtil.format(currentDate, "yyyy-MM-dd"); - String displayDateStr = DateUtil.format(currentDate, "MM月dd日"); - + String dateStr = DateUtil.format(startDate, "yyyy-MM-dd"); + String displayDateStr = DateUtil.format(startDate, "MM月dd日"); // 安全获取星期信息 String weekStr = "星期"; try { - weekStr = DateTimeUtils.getWeekOfDate(currentDate); + weekStr = DateTimeUtils.getWeekOfDate(startDate); } catch (Exception e) { logger.warn("[生成预约参数] 获取星期信息异常,使用默认值,date: {}", dateStr); } - // 设置date_title + // 设置date_title - 优化后的代码 + String dateTitle; if (i == 0) { - bookingArgDTO.setDate_title("今天(" + weekStr + ")"); + dateTitle = canBookingToday ? "今天" : "明天"; } else if (i == 1) { - bookingArgDTO.setDate_title("明天(" + weekStr + ")"); + dateTitle = canBookingToday ? "明天" : "后天"; } else { - bookingArgDTO.setDate_title(displayDateStr + "(" + weekStr + ")"); + dateTitle = displayDateStr; } + bookingArgDTO.setDate_title(dateTitle + "(" + weekStr + ")"); bookingArgDTO.setDate_str(displayDateStr); bookingArgDTO.setDate(dateStr); // 生成时间项 - List items = new ArrayList<>(); +// List items = new ArrayList<>(); - // 如果是今天,始终添加"立即送出"选项 - if (i == 0) { - 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); - } + // 如果是今天且在配送时间内,添加"立即送出"选项 +// if (i == 0 && canBookingToday) { +// 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); +// } - // 只有当 timesMap 不为空时才生成其他时间槽 - if (!ObjectUtil.isEmpty(timesMap) && StrUtil.isNotBlank(timesMap.get("startTimeStr")) && StrUtil.isNotBlank(timesMap.get("endTimeStr"))) { - String startTimeStr = timesMap.get("startTimeStr"); - String endTimeStr = timesMap.get("endTimeStr"); - List timeSlots = generateTimeSlots(dateStr, startTimeStr, endTimeStr, i == 0); - if (i == 0) { - // 对于今天,移除除"立即送出"外的所有时间槽 - items.addAll(timeSlots.stream().filter(item -> item.getBooking_state() != 1).collect(Collectors.toList())); - } else { - // 对于其他日期,添加所有时间槽 - items.addAll(timeSlots); - } - bookingArgDTO.setWorking_hours(String.format("%s-%s", startTimeStr, endTimeStr)); - } else if (i == 0) { - // 如果timesMap为空,今天只保留"立即送出"选项 - logger.debug("[生成预约参数] timesMap为空,今天只生成立即送出选项"); - } else { - // 如果timesMap为空,其他日期不生成任何时间槽 - logger.debug("[生成预约参数] timesMap为空,不生成{}的预约时间槽", dateStr); - continue; // 跳过当前日期 - } + String startTimeStr = timesPair.getFirst(); + String endTimeStr = timesPair.getSecond(); + boolean isToday = i == 0 && canBookingToday; + // 生成时间项 + List items = generateTimeSlots(dateStr, startTimeStr, endTimeStr, isToday); +// if (i == 0 && canBookingToday) { +// items.addAll(timeSlots.stream().filter(item -> item.getBooking_state() != 1).collect(Collectors.toList())); +// } else { +// items.addAll(timeSlots); +// } + bookingArgDTO.setWorking_hours(String.format("%s-%s", startTimeStr, endTimeStr)); bookingArgDTO.setItems(items); result.add(bookingArgDTO); } logger.debug("[生成预约参数] 成功生成预约参数,storeId: {}, timesMap: {}, 参数数量: {}", - storeIds, timesMap, result.size()); + storeIds, timesPair, result.size()); return result; } @@ -1221,12 +1232,14 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl 列表list + * 根据 storeIds(一个或多个 storeid,如 34,23,43,23,),先对id去重, + * 再获取多个店铺的营业时间 List 列表list + * 启动如果遇到某个店铺是开业(活动)筹备中的,获取他的开始营业的的日期和营业时间段组合出特有营业时间段 * * @param storeIds 以逗号分隔的店铺ID字符串 * @return 包含店铺营业时间信息的列表,每个元素为包含opening_hours和close_hours的Map */ - private List> selStoreBizTimeMapList(String storeIds) { + private List> selStoreBizTimeMapList(String storeIds) { // 参数校验 if (StrUtil.isBlank(storeIds)) { return Collections.emptyList(); @@ -1257,9 +1270,7 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl { - Map timeSlot = new HashMap<>(); - timeSlot.put("startTimeStr", storeInfo.getStore_opening_hours()); - timeSlot.put("endTimeStr", storeInfo.getStore_close_hours()); + Pair timeSlot = Pair.of(storeInfo.getStore_opening_hours(), storeInfo.getStore_close_hours()); return timeSlot; }) .collect(Collectors.toList()); diff --git a/mall-shop/src/main/resources/mapper/store/ShopStoreBaseMapper.xml b/mall-shop/src/main/resources/mapper/store/ShopStoreBaseMapper.xml index cc6988a1..52529964 100644 --- a/mall-shop/src/main/resources/mapper/store/ShopStoreBaseMapper.xml +++ b/mall-shop/src/main/resources/mapper/store/ShopStoreBaseMapper.xml @@ -5,8 +5,8 @@ store_id , user_id, store_name, store_grade_id, store_logo, store_slogan, store_domain, store_area, store_district_id, - store_address, store_latitude, store_longitude, store_is_selfsupport, store_type, store_is_open, store_biz_state, - ringtone_is_enable, shop_parent_id, store_2nd_category_id, + store_address, store_latitude, store_longitude, store_is_selfsupport, store_type, store_is_open, + store_biz_state, store_biz_opening_dtime, ringtone_is_enable, shop_parent_id, store_2nd_category_id, store_category_id, store_state_id, store_time, store_end_time, product_category_ids, store_o2o_tags, store_o2o_flag, store_o2o_merchant_id, store_circle, subsite_id, lkl_merchant_no, lkl_term_no, wx_qrcode, split_ratio, packing_fee, created_at, updated_at diff --git a/pom.xml b/pom.xml index 854ae63a..e5bda657 100644 --- a/pom.xml +++ b/pom.xml @@ -540,12 +540,39 @@ maven-dependency-plugin + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + + remove-remote-image + clean + + exec + + + curl + + -X + DELETE + ${docker.registry}/mall/${project.artifactId}:${project.version} + + + + + + com.spotify docker-maven-plugin ${docker.maven.plugin.version} + + + build-image package