Quellcode durchsuchen

商家端 信息设置 效验预约时间不能超出门店时间

qinxuyang vor 1 Monat
Ursprung
Commit
6a54ce0a2b

+ 230 - 0
alien-store/src/main/java/shop/alien/store/service/impl/StoreBookingSettingsServiceImpl.java

@@ -13,10 +13,12 @@ import org.springframework.util.StringUtils;
 import shop.alien.entity.store.EssentialHolidayComparison;
 import shop.alien.entity.store.StoreBookingBusinessHours;
 import shop.alien.entity.store.StoreBookingSettings;
+import shop.alien.entity.store.StoreBusinessInfo;
 import shop.alien.entity.store.dto.StoreBookingBusinessHoursDTO;
 import shop.alien.entity.store.dto.StoreBookingSettingsDTO;
 import shop.alien.mapper.EssentialHolidayComparisonMapper;
 import shop.alien.mapper.StoreBookingSettingsMapper;
+import shop.alien.mapper.StoreBusinessInfoMapper;
 import shop.alien.store.service.StoreBookingBusinessHoursService;
 import shop.alien.store.service.StoreBookingSettingsService;
 import shop.alien.util.common.JwtUtil;
@@ -40,6 +42,7 @@ public class StoreBookingSettingsServiceImpl extends ServiceImpl<StoreBookingSet
 
     private final StoreBookingBusinessHoursService storeBookingBusinessHoursService;
     private final EssentialHolidayComparisonMapper essentialHolidayComparisonMapper;
+    private final StoreBusinessInfoMapper storeBusinessInfoMapper;
 
     // 时间格式正则:HH:mm
     private static final Pattern TIME_PATTERN = Pattern.compile("^([0-1][0-9]|2[0-3]):[0-5][0-9]$");
@@ -225,12 +228,18 @@ public class StoreBookingSettingsServiceImpl extends ServiceImpl<StoreBookingSet
         
         // 3.1 处理正常营业时间(business_type=1)
         if (dto.getNormalBusinessHours() != null) {
+            // 校验正常营业时间:预约时间的正常时间不能大于门店营业时间的正常时间
+            validateNormalBusinessHours(dto.getStoreId(), dto.getNormalBusinessHours());
+            
             StoreBookingBusinessHours normalHours = convertToBusinessHours(dto.getNormalBusinessHours(), settingsId, 1);
             businessHoursList.add(normalHours);
         }
         
         // 3.2 处理特殊营业时间列表(business_type=2)
         if (dto.getSpecialBusinessHoursList() != null && !dto.getSpecialBusinessHoursList().isEmpty()) {
+            // 校验特殊营业时间:预约时间的特殊时间不能大于门店营业时间的特殊时间
+            validateSpecialBusinessHours(dto.getStoreId(), dto.getSpecialBusinessHoursList());
+            
             int sort = 1;
             for (StoreBookingBusinessHoursDTO specialDto : dto.getSpecialBusinessHoursList()) {
                 StoreBookingBusinessHours specialHours = convertToBusinessHours(specialDto, settingsId, 2);
@@ -361,6 +370,227 @@ public class StoreBookingSettingsServiceImpl extends ServiceImpl<StoreBookingSet
     }
 
     /**
+     * 校验正常营业时间:预约时间的正常时间不能大于门店营业时间的正常时间
+     *
+     * @param storeId 门店ID
+     * @param normalBusinessHours 预约时间的正常营业时间
+     */
+    private void validateNormalBusinessHours(Integer storeId, StoreBookingBusinessHoursDTO normalBusinessHours) {
+        log.info("开始校验正常营业时间,storeId={}", storeId);
+        
+        if (storeId == null || normalBusinessHours == null) {
+            return;
+        }
+        
+        // 如果是全天营业,跳过校验
+        if (normalBusinessHours.getBookingTimeType() != null && normalBusinessHours.getBookingTimeType() == 1) {
+            return;
+        }
+        
+        // 如果没有开始时间和结束时间,跳过校验
+        if (!StringUtils.hasText(normalBusinessHours.getStartTime()) || 
+            !StringUtils.hasText(normalBusinessHours.getEndTime())) {
+            return;
+        }
+        
+        // 查询门店的正常营业时间(store_business_info,business_type=1)
+        List<StoreBusinessInfo> storeNormalBusinessHours = storeBusinessInfoMapper.selectList(
+                new LambdaQueryWrapper<StoreBusinessInfo>()
+                        .eq(StoreBusinessInfo::getStoreId, storeId)
+                        .eq(StoreBusinessInfo::getBusinessType, 1) // 正常营业时间
+                        .eq(StoreBusinessInfo::getDeleteFlag, 0)
+        );
+        
+        if (storeNormalBusinessHours == null || storeNormalBusinessHours.isEmpty()) {
+            log.warn("门店未配置正常营业时间,无法校验,storeId={}", storeId);
+            return;
+        }
+        
+        // 查找匹配的门店正常营业时间(正常营业时间通常只有一条,或者按 business_date 匹配)
+        StoreBusinessInfo matchedStoreHours = null;
+        
+        // 如果有 holiday_date,尝试通过 business_date 匹配
+        if (StringUtils.hasText(normalBusinessHours.getHolidayDate())) {
+            matchedStoreHours = storeNormalBusinessHours.stream()
+                    .filter(h -> normalBusinessHours.getHolidayDate().equals(h.getBusinessDate()))
+                    .findFirst()
+                    .orElse(null);
+        }
+        
+        // 如果没有匹配到,使用第一条正常营业时间(通常正常营业时间只有一条)
+        if (matchedStoreHours == null && !storeNormalBusinessHours.isEmpty()) {
+            matchedStoreHours = storeNormalBusinessHours.get(0);
+        }
+        
+        // 如果没有匹配到门店正常营业时间,跳过校验
+        if (matchedStoreHours == null) {
+            log.warn("未找到匹配的门店正常营业时间,跳过校验");
+            return;
+        }
+        
+        // 如果门店正常营业时间没有开始时间和结束时间,跳过校验
+        if (!StringUtils.hasText(matchedStoreHours.getStartTime()) || 
+            !StringUtils.hasText(matchedStoreHours.getEndTime())) {
+            return;
+        }
+        
+        // 比较时间范围
+        String bookingStartTime = normalBusinessHours.getStartTime().trim();
+        String bookingEndTime = normalBusinessHours.getEndTime().trim();
+        String storeStartTime = matchedStoreHours.getStartTime().trim();
+        String storeEndTime = matchedStoreHours.getEndTime().trim();
+        
+        // 比较开始时间:预约时间的开始时间不能早于门店营业时间的开始时间
+        if (compareTime(bookingStartTime, storeStartTime) < 0) {
+            log.error("预约时间的正常时间开始时间早于门店营业时间的正常时间,storeId={}, bookingStartTime={}, storeStartTime={}", 
+                    storeId, bookingStartTime, storeStartTime);
+            throw new RuntimeException("预订时间与营业时间冲突,请重新设置");
+        }
+        
+        // 比较结束时间:预约时间的结束时间不能晚于门店营业时间的结束时间
+        if (compareTime(bookingEndTime, storeEndTime) > 0) {
+            log.error("预约时间的正常时间结束时间晚于门店营业时间的正常时间,storeId={}, bookingEndTime={}, storeEndTime={}", 
+                    storeId, bookingEndTime, storeEndTime);
+            throw new RuntimeException("预订时间与营业时间冲突,请重新设置");
+        }
+        
+        log.info("正常营业时间校验通过,storeId={}", storeId);
+    }
+    
+    /**
+     * 校验特殊营业时间:预约时间的特殊时间不能大于门店营业时间的特殊时间
+     *
+     * @param storeId 门店ID
+     * @param specialBusinessHoursList 预约时间的特殊营业时间列表
+     */
+    private void validateSpecialBusinessHours(Integer storeId, List<StoreBookingBusinessHoursDTO> specialBusinessHoursList) {
+        log.info("开始校验特殊营业时间,storeId={}, specialBusinessHoursList.size={}", 
+                storeId, specialBusinessHoursList != null ? specialBusinessHoursList.size() : 0);
+        
+        if (storeId == null || specialBusinessHoursList == null || specialBusinessHoursList.isEmpty()) {
+            return;
+        }
+        
+        // 查询门店的特殊营业时间(store_business_info,business_type=2)
+        List<StoreBusinessInfo> storeSpecialBusinessHours = storeBusinessInfoMapper.selectList(
+                new LambdaQueryWrapper<StoreBusinessInfo>()
+                        .eq(StoreBusinessInfo::getStoreId, storeId)
+                        .eq(StoreBusinessInfo::getBusinessType, 2) // 特殊营业时间
+                        .eq(StoreBusinessInfo::getDeleteFlag, 0)
+        );
+        
+        if (storeSpecialBusinessHours == null || storeSpecialBusinessHours.isEmpty()) {
+            log.warn("门店未配置特殊营业时间,无法校验,storeId={}", storeId);
+            return;
+        }
+        
+        // 遍历预约时间的特殊营业时间,与门店特殊营业时间进行匹配和比较
+        for (StoreBookingBusinessHoursDTO bookingSpecialHours : specialBusinessHoursList) {
+            // 如果是全天营业,跳过校验
+            if (bookingSpecialHours.getBookingTimeType() != null && bookingSpecialHours.getBookingTimeType() == 1) {
+                continue;
+            }
+            
+            // 如果没有开始时间和结束时间,跳过校验
+            if (!StringUtils.hasText(bookingSpecialHours.getStartTime()) || 
+                !StringUtils.hasText(bookingSpecialHours.getEndTime())) {
+                continue;
+            }
+            
+            // 查找匹配的门店特殊营业时间
+            StoreBusinessInfo matchedStoreHours = null;
+            
+            // 优先通过 essential_id 匹配
+            if (bookingSpecialHours.getEssentialId() != null) {
+                matchedStoreHours = storeSpecialBusinessHours.stream()
+                        .filter(h -> {
+                            if (h.getEssentialId() == null || h.getEssentialId().trim().isEmpty()) {
+                                return false;
+                            }
+                            try {
+                                Integer essentialId = Integer.parseInt(h.getEssentialId().trim());
+                                return essentialId.equals(bookingSpecialHours.getEssentialId());
+                            } catch (NumberFormatException e) {
+                                return false;
+                            }
+                        })
+                        .findFirst()
+                        .orElse(null);
+            }
+            
+            // 如果没有通过 essential_id 匹配到,尝试通过 holiday_date 匹配
+            if (matchedStoreHours == null && StringUtils.hasText(bookingSpecialHours.getHolidayDate())) {
+                matchedStoreHours = storeSpecialBusinessHours.stream()
+                        .filter(h -> bookingSpecialHours.getHolidayDate().equals(h.getBusinessDate()))
+                        .findFirst()
+                        .orElse(null);
+            }
+            
+            // 如果没有匹配到门店特殊营业时间,跳过校验(可能是新增的特殊时间)
+            if (matchedStoreHours == null) {
+                log.warn("未找到匹配的门店特殊营业时间,跳过校验,essentialId={}, holidayDate={}", 
+                        bookingSpecialHours.getEssentialId(), bookingSpecialHours.getHolidayDate());
+                continue;
+            }
+            
+            // 如果门店特殊营业时间没有开始时间和结束时间,跳过校验
+            if (!StringUtils.hasText(matchedStoreHours.getStartTime()) || 
+                !StringUtils.hasText(matchedStoreHours.getEndTime())) {
+                continue;
+            }
+            
+            // 比较时间范围
+            String bookingStartTime = bookingSpecialHours.getStartTime().trim();
+            String bookingEndTime = bookingSpecialHours.getEndTime().trim();
+            String storeStartTime = matchedStoreHours.getStartTime().trim();
+            String storeEndTime = matchedStoreHours.getEndTime().trim();
+            
+            // 比较开始时间:预约时间的开始时间不能早于门店营业时间的开始时间
+            if (compareTime(bookingStartTime, storeStartTime) < 0) {
+                log.error("预约时间的特殊时间开始时间早于门店营业时间的特殊时间,storeId={}, bookingStartTime={}, storeStartTime={}", 
+                        storeId, bookingStartTime, storeStartTime);
+                throw new RuntimeException("预订时间与营业时间冲突,请重新设置");
+            }
+            
+            // 比较结束时间:预约时间的结束时间不能晚于门店营业时间的结束时间
+            if (compareTime(bookingEndTime, storeEndTime) > 0) {
+                log.error("预约时间的特殊时间结束时间晚于门店营业时间的特殊时间,storeId={}, bookingEndTime={}, storeEndTime={}", 
+                        storeId, bookingEndTime, storeEndTime);
+                throw new RuntimeException("预订时间与营业时间冲突,请重新设置");
+            }
+        }
+        
+        log.info("特殊营业时间校验通过,storeId={}", storeId);
+    }
+    
+    /**
+     * 比较两个时间(HH:mm格式)
+     * 
+     * @param time1 时间1
+     * @param time2 时间2
+     * @return 负数表示time1 < time2,0表示相等,正数表示time1 > time2
+     */
+    private int compareTime(String time1, String time2) {
+        try {
+            String[] parts1 = time1.split(":");
+            String[] parts2 = time2.split(":");
+            
+            int hour1 = Integer.parseInt(parts1[0]);
+            int minute1 = Integer.parseInt(parts1[1]);
+            int hour2 = Integer.parseInt(parts2[0]);
+            int minute2 = Integer.parseInt(parts2[1]);
+            
+            int totalMinutes1 = hour1 * 60 + minute1;
+            int totalMinutes2 = hour2 * 60 + minute2;
+            
+            return totalMinutes1 - totalMinutes2;
+        } catch (Exception e) {
+            log.error("比较时间失败,time1={}, time2={}", time1, time2, e);
+            throw new RuntimeException("时间格式错误");
+        }
+    }
+    
+    /**
      * 从JWT获取当前登录用户ID
      *
      * @return 用户ID,如果未登录返回null