Bläddra i källkod

收银台功能 优惠券 校验

liudongzhi 2 veckor sedan
förälder
incheckning
e7e689eea5

+ 66 - 7
alien-store/src/main/java/shop/alien/store/service/impl/StoreServiceFeeRuleServiceImpl.java

@@ -426,10 +426,10 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
                 return "开始日期不能大于结束日期";
             }
         }
-        for (StoreServiceFeeRuleSlotDto slot : dto.getSlots()) {
-            if (slot.getWeekdayMask() == null || slot.getWeekdayMask() <= 0) {
-                return "生效星期不能为空";
-            }
+
+        // 校验每个时段的时间合法性(星期可选填)
+        List<StoreServiceFeeRuleSlotDto> slots = dto.getSlots();
+        for (StoreServiceFeeRuleSlotDto slot : slots) {
             if (!StringUtils.hasText(slot.getStartTime()) || !StringUtils.hasText(slot.getEndTime())) {
                 return "生效时间不能为空";
             }
@@ -439,6 +439,25 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
                 return "生效开始时间必须早于结束时间";
             }
         }
+        // 校验同一次提交内的时段互不重叠(星期为空时视为“全周”)
+        for (int i = 0; i < slots.size(); i++) {
+            StoreServiceFeeRuleSlotDto a = slots.get(i);
+            LocalTime aStart = LocalTime.parse(a.getStartTime(), TIME_FORMATTER);
+            LocalTime aEnd = LocalTime.parse(a.getEndTime(), TIME_FORMATTER);
+            for (int j = i + 1; j < slots.size(); j++) {
+                StoreServiceFeeRuleSlotDto b = slots.get(j);
+                int aMask = (a.getWeekdayMask() == null || a.getWeekdayMask() <= 0) ? 127 : a.getWeekdayMask();
+                int bMask = (b.getWeekdayMask() == null || b.getWeekdayMask() <= 0) ? 127 : b.getWeekdayMask();
+                if ( (aMask & bMask) <= 0 ) {
+                    continue;
+                }
+                LocalTime bStart = LocalTime.parse(b.getStartTime(), TIME_FORMATTER);
+                LocalTime bEnd = LocalTime.parse(b.getEndTime(), TIME_FORMATTER);
+                if (isTimeOverlap(aStart, aEnd, bStart, bEnd)) {
+                    return "同一次提交的生效时段之间存在重叠,请调整后再提交";
+                }
+            }
+        }
         return null;
     }
 
@@ -456,6 +475,30 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
             return null;
         }
 
+        // 永久生效规则(无起止日期)与同桌台下任意其他开启规则互斥
+        boolean newIsPermanent = MODE_PERMANENT.equals(dto.getEffectiveMode());
+        if (newIsPermanent) {
+            Integer conflictTableId = existRules.stream()
+                    .map(StoreServiceFeeRule::getTableId)
+                    .filter(tableIds::contains)
+                    .findFirst()
+                    .orElse(null);
+            if (conflictTableId != null) {
+                String tableName = getTableName(conflictTableId);
+                return "桌台[" + tableName + "]已存在开启的服务费规则,永久生效规则不允许与其他规则共存";
+            }
+        }
+        Integer conflictPermanentTableId = existRules.stream()
+                .filter(rule -> MODE_PERMANENT.equals(rule.getEffectiveMode()))
+                .map(StoreServiceFeeRule::getTableId)
+                .filter(tableIds::contains)
+                .findFirst()
+                .orElse(null);
+        if (conflictPermanentTableId != null) {
+            String tableName = getTableName(conflictPermanentTableId);
+            return "桌台[" + tableName + "]已存在永久生效服务费规则,不允许再创建或编辑其他服务费规则";
+        }
+
         Date newStartDate = MODE_CUSTOM.equals(dto.getEffectiveMode()) ? parseDate(dto.getStartDate()) : toDate(LocalDate.of(1970, 1, 1));
         Date newEndDate = MODE_CUSTOM.equals(dto.getEffectiveMode()) ? parseDate(dto.getEndDate()) : toDate(LocalDate.of(2099, 12, 31));
         List<StoreServiceFeeRuleSlotDto> newSlots = dto.getSlots();
@@ -469,16 +512,21 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
             for (StoreServiceFeeRuleSlotDto ns : newSlots) {
                 LocalTime nsStart = LocalTime.parse(ns.getStartTime(), TIME_FORMATTER);
                 LocalTime nsEnd = LocalTime.parse(ns.getEndTime(), TIME_FORMATTER);
-                if ((ns.getWeekdayMask() & (existRule.getWeekdayMask() == null ? 0 : existRule.getWeekdayMask())) <= 0) {
+                int newMask = (ns.getWeekdayMask() == null || ns.getWeekdayMask() <= 0) ? 127 : ns.getWeekdayMask();
+                int oldMask = (existRule.getWeekdayMask() == null || existRule.getWeekdayMask() <= 0) ? 127 : existRule.getWeekdayMask();
+                if ( (newMask & oldMask) <= 0 ) {
                     continue;
                 }
                 if (isTimeOverlap(nsStart, nsEnd, existRule.getStartTime(), existRule.getEndTime())) {
                     Integer tableId = existRule.getTableId();
+                    String tableName = getTableName(tableId);
                     if (tableId != null && tableIds.contains(tableId)) {
                         if (!dto.getFeeType().equals(existRule.getFeeType())) {
-                            return "桌台[" + tableId + "]在该时间段已配置其他类型服务费";
+                            return "桌台[" + tableName + "]在该时间段已配置其他类型服务费";
+//                            return "桌台[" + tableId + "]在该时间段已配置其他类型服务费";
                         }
-                        return "桌台[" + tableId + "]服务费时间重叠,请调整生效日期/星期/时间";
+                        return "桌台[" + tableName + "]服务费时间重叠,请调整生效日期/星期/时间";
+//                        return "桌台[" + tableId + "]服务费时间重叠,请调整生效日期/星期/时间";
                     }
                 }
             }
@@ -486,6 +534,17 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
         return null;
     }
 
+    private String getTableName(Integer tableId) {
+        if (tableId == null) {
+            return "";
+        }
+        shop.alien.entity.store.StoreTable table = storeBookingTableService.getById(tableId);
+        if (table == null || !StringUtils.hasText(table.getTableNumber())) {
+            return String.valueOf(tableId);
+        }
+        return table.getTableNumber();
+    }
+
     private boolean isDateOverlap(Date s1, Date e1, Date s2, Date e2) {
         return !s1.after(e2) && !s2.after(e1);
     }