Kaynağa Gözat

收银台功能 优惠设置 功能修改 合表修改

liudongzhi 3 hafta önce
ebeveyn
işleme
ad734c906b

+ 13 - 0
alien-entity/src/main/java/shop/alien/entity/store/StoreProductDiscountRule.java

@@ -7,6 +7,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.math.BigDecimal;
+import java.time.LocalTime;
 import java.util.Date;
 
 @Data
@@ -72,5 +73,17 @@ public class StoreProductDiscountRule {
 
 	@TableField("updated_user_id")
 	private Integer updatedUserId;
+
+	@ApiModelProperty("星期掩码,按位表示周一到周日")
+	@TableField("weekday_mask")
+	private Integer weekdayMask;
+
+	@ApiModelProperty("开始时间")
+	@TableField("start_time")
+	private LocalTime startTime;
+
+	@ApiModelProperty("结束时间")
+	@TableField("end_time")
+	private LocalTime endTime;
 }
 

+ 3 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/StoreProductDiscountRuleDetailVo.java

@@ -24,5 +24,8 @@ public class StoreProductDiscountRuleDetailVo {
 	private String endDate;
 	private Integer status;
 	private List<StoreProductDiscountRuleSlotDto> slots;
+
+	@ApiModelProperty("菜品原价")
+	private java.math.BigDecimal originalPrice;
 }
 

+ 3 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/StoreProductDiscountRuleListVo.java

@@ -24,6 +24,9 @@ public class StoreProductDiscountRuleListVo {
 	@ApiModelProperty("菜品名称")
 	private String productName;
 
+	@ApiModelProperty("菜品图片URL")
+	private String productImageUrl;
+
 	@ApiModelProperty("规则名称")
 	private String ruleName;
 

+ 152 - 93
alien-store/src/main/java/shop/alien/store/service/impl/StoreProductDiscountServiceImpl.java

@@ -15,8 +15,10 @@ import shop.alien.entity.store.dto.StoreProductDiscountRuleSlotDto;
 import shop.alien.entity.store.vo.StoreProductDiscountRuleDetailVo;
 import shop.alien.entity.store.vo.StoreProductDiscountRuleListVo;
 import shop.alien.mapper.StoreProductDiscountRuleMapper;
-import shop.alien.mapper.StoreProductDiscountRuleSlotMapper;
+
 import shop.alien.store.service.StoreProductDiscountService;
+import shop.alien.store.service.StoreCuisineService;
+import shop.alien.store.service.StorePriceService;
 
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -41,7 +43,8 @@ public class StoreProductDiscountServiceImpl implements StoreProductDiscountServ
 	private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
 
 	private final StoreProductDiscountRuleMapper ruleMapper;
-	private final StoreProductDiscountRuleSlotMapper ruleSlotMapper;
+	private final StoreCuisineService storeCuisineService;
+	private final StorePriceService storePriceService;
 
 	@Override
 	public R<IPage<StoreProductDiscountRuleListVo>> listRules(Integer storeId, Integer productId, String ruleName, Integer status, Integer pageNum, Integer pageSize) {
@@ -65,27 +68,33 @@ public class StoreProductDiscountServiceImpl implements StoreProductDiscountServ
 		qw.orderByDesc(StoreProductDiscountRule::getUpdatedTime);
 		IPage<StoreProductDiscountRule> rulePage = ruleMapper.selectPage(page, qw);
 
-		Map<Integer, String> productNameMap = buildProductNameMap(storeId);
-		Map<Integer, Integer> slotCountMap = buildSlotCountMap(rulePage.getRecords().stream().map(StoreProductDiscountRule::getId).collect(Collectors.toList()));
+		Map<Integer, ProductInfo> productInfoMap = buildProductInfoMap(storeId, rulePage.getRecords().stream().map(StoreProductDiscountRule::getProductId).collect(Collectors.toList()));
 
-		List<StoreProductDiscountRuleListVo> records = rulePage.getRecords().stream().map(rule -> {
+		// 单表:按“商品+规则头”分组聚合,slotCount 为该组的行数
+		Map<String, List<StoreProductDiscountRule>> grouped = rulePage.getRecords().stream()
+				.collect(Collectors.groupingBy(this::groupKey));
+		List<StoreProductDiscountRuleListVo> records = new ArrayList<>();
+		for (List<StoreProductDiscountRule> group : grouped.values()) {
+			StoreProductDiscountRule head = group.get(0);
 			StoreProductDiscountRuleListVo vo = new StoreProductDiscountRuleListVo();
-			vo.setId(rule.getId());
-			vo.setStoreId(rule.getStoreId());
-			vo.setProductId(rule.getProductId());
-			vo.setProductName(productNameMap.get(rule.getProductId()));
-			vo.setRuleName(rule.getRuleName());
-			vo.setDiscountType(rule.getDiscountType());
-			vo.setDiscountRate(rule.getDiscountRate());
-			vo.setEffectiveMode(rule.getEffectiveMode());
-			vo.setDateRange(formatDateRange(rule.getStartDate(), rule.getEndDate(), rule.getEffectiveMode()));
-			vo.setSlotCount(slotCountMap.getOrDefault(rule.getId(), 0));
-			vo.setStatus(rule.getStatus());
-			vo.setUpdatedTime(rule.getUpdatedTime());
-			return vo;
-		}).collect(Collectors.toList());
+			vo.setId(group.stream().map(StoreProductDiscountRule::getId).min(Integer::compareTo).orElse(head.getId()));
+			vo.setStoreId(head.getStoreId());
+			vo.setProductId(head.getProductId());
+			ProductInfo info = productInfoMap.get(head.getProductId());
+			vo.setProductName(info == null ? null : info.name);
+			vo.setProductImageUrl(info == null ? null : info.imageUrl);
+			vo.setRuleName(head.getRuleName());
+			vo.setDiscountType(head.getDiscountType());
+			vo.setDiscountRate(head.getDiscountRate());
+			vo.setEffectiveMode(head.getEffectiveMode());
+			vo.setDateRange(formatDateRange(head.getStartDate(), head.getEndDate(), head.getEffectiveMode()));
+			vo.setSlotCount(group.size());
+			vo.setStatus(head.getStatus());
+			vo.setUpdatedTime(group.stream().map(StoreProductDiscountRule::getUpdatedTime).filter(Objects::nonNull).max(Date::compareTo).orElse(head.getUpdatedTime()));
+			records.add(vo);
+		}
 
-		Page<StoreProductDiscountRuleListVo> result = new Page<>(pn, ps, rulePage.getTotal());
+		Page<StoreProductDiscountRuleListVo> result = new Page<>(pn, ps, grouped.size());
 		result.setRecords(records);
 		return R.data(result);
 	}
@@ -103,7 +112,9 @@ public class StoreProductDiscountServiceImpl implements StoreProductDiscountServ
 		vo.setId(rule.getId());
 		vo.setStoreId(rule.getStoreId());
 		vo.setProductId(rule.getProductId());
-		vo.setProductName(buildProductNameMap(rule.getStoreId()).get(rule.getProductId()));
+		ProductInfo info = getProductInfo(rule.getStoreId(), rule.getProductId());
+		vo.setProductName(info == null ? null : info.name);
+		vo.setOriginalPrice(info == null ? null : info.price);
 		vo.setRuleName(rule.getRuleName());
 		vo.setDiscountType(rule.getDiscountType());
 		vo.setDiscountRate(rule.getDiscountRate());
@@ -111,8 +122,24 @@ public class StoreProductDiscountServiceImpl implements StoreProductDiscountServ
 		vo.setStartDate(formatDate(rule.getStartDate()));
 		vo.setEndDate(formatDate(rule.getEndDate()));
 		vo.setStatus(rule.getStatus());
-		List<StoreProductDiscountRuleSlot> slots = ruleSlotMapper.selectList(new LambdaQueryWrapper<StoreProductDiscountRuleSlot>().eq(StoreProductDiscountRuleSlot::getRuleId, id));
-		vo.setSlots(slots.stream().map(this::toSlotDto).collect(Collectors.toList()));
+		// 同组(商品+规则头)聚合同桌台下的时段(来自主表行)
+		LambdaQueryWrapper<StoreProductDiscountRule> groupQw = new LambdaQueryWrapper<StoreProductDiscountRule>()
+				.eq(StoreProductDiscountRule::getStoreId, rule.getStoreId())
+				.eq(StoreProductDiscountRule::getProductId, rule.getProductId())
+				.eq(StoreProductDiscountRule::getRuleName, rule.getRuleName())
+				.eq(StoreProductDiscountRule::getDiscountType, rule.getDiscountType())
+				.eq(StoreProductDiscountRule::getDiscountRate, rule.getDiscountRate())
+				.eq(StoreProductDiscountRule::getEffectiveMode, rule.getEffectiveMode());
+		if (rule.getStartDate() == null) groupQw.isNull(StoreProductDiscountRule::getStartDate); else groupQw.eq(StoreProductDiscountRule::getStartDate, rule.getStartDate());
+		if (rule.getEndDate() == null) groupQw.isNull(StoreProductDiscountRule::getEndDate); else groupQw.eq(StoreProductDiscountRule::getEndDate, rule.getEndDate());
+		List<StoreProductDiscountRule> sameGroup = ruleMapper.selectList(groupQw);
+		vo.setSlots(sameGroup.stream().map(r -> {
+			StoreProductDiscountRuleSlotDto s = new StoreProductDiscountRuleSlotDto();
+			s.setWeekdayMask(r.getWeekdayMask());
+			s.setStartTime(r.getStartTime() == null ? null : r.getStartTime().format(TIME_FORMATTER));
+			s.setEndTime(r.getEndTime() == null ? null : r.getEndTime().format(TIME_FORMATTER));
+			return s;
+		}).collect(Collectors.toList()));
 		return R.data(vo);
 	}
 
@@ -120,10 +147,20 @@ public class StoreProductDiscountServiceImpl implements StoreProductDiscountServ
 	public R<Integer> createRule(StoreProductDiscountRuleSaveDto dto) {
 		String err = validateAndCheckConflict(dto, null);
 		if (err != null) return R.fail(err);
-		StoreProductDiscountRule rule = toEntity(dto, false);
-		ruleMapper.insert(rule);
-		saveSlots(rule.getId(), dto.getSlots());
-		return R.data(rule.getId());
+		// 单表:按时段展开写入多行(无时段则按“全星期/全天”写入一行)
+		Integer firstId = null;
+		List<StoreProductDiscountRuleSlotDto> slots = (dto.getSlots()==null || dto.getSlots().isEmpty())
+				? Collections.singletonList(allWeekAllDaySlotDto())
+				: dto.getSlots();
+		for (StoreProductDiscountRuleSlotDto s : slots) {
+			StoreProductDiscountRule e = toEntity(dto, false);
+			e.setWeekdayMask(s.getWeekdayMask());
+			if (StringUtils.hasText(s.getStartTime())) e.setStartTime(LocalTime.parse(s.getStartTime(), TIME_FORMATTER));
+			if (StringUtils.hasText(s.getEndTime())) e.setEndTime(LocalTime.parse(s.getEndTime(), TIME_FORMATTER));
+			ruleMapper.insert(e);
+			if (firstId == null) firstId = e.getId();
+		}
+		return R.data(firstId);
 	}
 
 	@Override
@@ -132,20 +169,48 @@ public class StoreProductDiscountServiceImpl implements StoreProductDiscountServ
 		if (ruleMapper.selectById(dto.getId()) == null) return R.fail("规则不存在");
 		String err = validateAndCheckConflict(dto, dto.getId());
 		if (err != null) return R.fail(err);
-		StoreProductDiscountRule update = toEntity(dto, true);
-		update.setId(dto.getId());
-		ruleMapper.updateById(update);
-		ruleSlotMapper.delete(new LambdaQueryWrapper<StoreProductDiscountRuleSlot>().eq(StoreProductDiscountRuleSlot::getRuleId, dto.getId()));
-		saveSlots(dto.getId(), dto.getSlots());
+		// 找到旧记录的“规则头”,删除该组所有行,再按新入参重建
+		StoreProductDiscountRule existing = ruleMapper.selectById(dto.getId());
+		LambdaQueryWrapper<StoreProductDiscountRule> delQw = new LambdaQueryWrapper<StoreProductDiscountRule>()
+				.eq(StoreProductDiscountRule::getStoreId, existing.getStoreId())
+				.eq(StoreProductDiscountRule::getProductId, existing.getProductId())
+				.eq(StoreProductDiscountRule::getRuleName, existing.getRuleName())
+				.eq(StoreProductDiscountRule::getDiscountType, existing.getDiscountType())
+				.eq(StoreProductDiscountRule::getDiscountRate, existing.getDiscountRate())
+				.eq(StoreProductDiscountRule::getEffectiveMode, existing.getEffectiveMode());
+		if (existing.getStartDate() == null) delQw.isNull(StoreProductDiscountRule::getStartDate); else delQw.eq(StoreProductDiscountRule::getStartDate, existing.getStartDate());
+		if (existing.getEndDate() == null) delQw.isNull(StoreProductDiscountRule::getEndDate); else delQw.eq(StoreProductDiscountRule::getEndDate, existing.getEndDate());
+		ruleMapper.delete(delQw);
+		// 无时段则按“全星期/全天”写入一行
+		List<StoreProductDiscountRuleSlotDto> slots = (dto.getSlots()==null || dto.getSlots().isEmpty())
+				? Collections.singletonList(allWeekAllDaySlotDto())
+				: dto.getSlots();
+		for (StoreProductDiscountRuleSlotDto s : slots) {
+			StoreProductDiscountRule e = toEntity(dto, true);
+			e.setWeekdayMask(s.getWeekdayMask());
+			if (StringUtils.hasText(s.getStartTime())) e.setStartTime(LocalTime.parse(s.getStartTime(), TIME_FORMATTER));
+			if (StringUtils.hasText(s.getEndTime())) e.setEndTime(LocalTime.parse(s.getEndTime(), TIME_FORMATTER));
+			ruleMapper.insert(e);
+		}
 		return R.data(true);
 	}
 
 	@Override
 	public R<Boolean> deleteRule(Integer id) {
 		if (id == null) return R.fail("规则ID不能为空");
-		if (ruleMapper.selectById(id) == null) return R.fail("规则不存在");
-		ruleMapper.deleteById(id);
-		ruleSlotMapper.delete(new LambdaQueryWrapper<StoreProductDiscountRuleSlot>().eq(StoreProductDiscountRuleSlot::getRuleId, id));
+		StoreProductDiscountRule existing = ruleMapper.selectById(id);
+		if (existing == null) return R.fail("规则不存在");
+		// 删除同组所有行
+		LambdaQueryWrapper<StoreProductDiscountRule> delQw = new LambdaQueryWrapper<StoreProductDiscountRule>()
+				.eq(StoreProductDiscountRule::getStoreId, existing.getStoreId())
+				.eq(StoreProductDiscountRule::getProductId, existing.getProductId())
+				.eq(StoreProductDiscountRule::getRuleName, existing.getRuleName())
+				.eq(StoreProductDiscountRule::getDiscountType, existing.getDiscountType())
+				.eq(StoreProductDiscountRule::getDiscountRate, existing.getDiscountRate())
+				.eq(StoreProductDiscountRule::getEffectiveMode, existing.getEffectiveMode());
+		if (existing.getStartDate() == null) delQw.isNull(StoreProductDiscountRule::getStartDate); else delQw.eq(StoreProductDiscountRule::getStartDate, existing.getStartDate());
+		if (existing.getEndDate() == null) delQw.isNull(StoreProductDiscountRule::getEndDate); else delQw.eq(StoreProductDiscountRule::getEndDate, existing.getEndDate());
+		ruleMapper.delete(delQw);
 		return R.data(true);
 	}
 
@@ -172,20 +237,13 @@ public class StoreProductDiscountServiceImpl implements StoreProductDiscountServ
 		if (candidates == null || candidates.isEmpty()) {
 			return 0;
 		}
-		List<Integer> ruleIds = candidates.stream().map(StoreProductDiscountRule::getId).collect(Collectors.toList());
-		Map<Integer, List<StoreProductDiscountRuleSlot>> slotMap = ruleSlotMapper.selectList(
-				new LambdaQueryWrapper<StoreProductDiscountRuleSlot>().in(StoreProductDiscountRuleSlot::getRuleId, ruleIds))
-				.stream().collect(Collectors.groupingBy(StoreProductDiscountRuleSlot::getRuleId));
 		int closed = 0;
 		for (StoreProductDiscountRule rule : candidates) {
 			LocalDate endDate = new java.sql.Date(rule.getEndDate().getTime()).toLocalDate();
-			LocalTime maxEnd = slotMap.getOrDefault(rule.getId(), Collections.emptyList()).stream()
-					.map(StoreProductDiscountRuleSlot::getEndTime)
-					.filter(Objects::nonNull)
-					.max(LocalTime::compareTo)
-					.orElse(LocalTime.of(23, 59, 59));
+			LocalTime maxEnd = rule.getEndTime() != null ? rule.getEndTime() : LocalTime.of(23, 59, 59);
 			LocalDateTime expireAt = LocalDateTime.of(endDate, maxEnd);
 			if (!now.isBefore(expireAt)) {
+				// 过期则直接关闭该行
 				StoreProductDiscountRule update = new StoreProductDiscountRule();
 				update.setId(rule.getId());
 				update.setStatus(0);
@@ -202,30 +260,52 @@ public class StoreProductDiscountServiceImpl implements StoreProductDiscountServ
 
 	/* ---------------- private helpers ---------------- */
 
-	private Map<Integer, String> buildProductNameMap(Integer storeId) {
-		// 简单从 store_cuisine 读取菜名(同门店)
-		// 如需跨多产品表,可在此聚合
-		// 这里只取未删除记录
-		// 为了避免全表扫描,真实环境建议按 productId 列表批量查询
-		return new HashMap<>(); // 可按需要补充查询
+	private static class ProductInfo {
+		String name;
+		String imageUrl;
+		java.math.BigDecimal price;
 	}
 
-	private Map<Integer, Integer> buildSlotCountMap(List<Integer> ruleIds) {
-		if (ruleIds == null || ruleIds.isEmpty()) return Collections.emptyMap();
-		List<StoreProductDiscountRuleSlot> slots = ruleSlotMapper.selectList(new LambdaQueryWrapper<StoreProductDiscountRuleSlot>().in(StoreProductDiscountRuleSlot::getRuleId, ruleIds));
-		Map<Integer, Integer> map = new HashMap<>();
-		for (StoreProductDiscountRuleSlot s : slots) {
-			map.put(s.getRuleId(), map.getOrDefault(s.getRuleId(), 0) + 1);
+	private Map<Integer, ProductInfo> buildProductInfoMap(Integer storeId, List<Integer> productIds) {
+		if (productIds == null || productIds.isEmpty()) return Collections.emptyMap();
+		Map<Integer, ProductInfo> result = new HashMap<>();
+		// 优先从美食表取
+		List<StoreCuisine> cuisines = storeCuisineService.list(new LambdaQueryWrapper<StoreCuisine>()
+				.eq(StoreCuisine::getStoreId, storeId)
+				.in(StoreCuisine::getId, productIds));
+		for (StoreCuisine c : cuisines) {
+			ProductInfo pi = new ProductInfo();
+			pi.name = c.getName();
+			pi.imageUrl = c.getImages();
+			pi.price = c.getTotalPrice();
+			result.put(c.getId(), pi);
+		}
+		// 其余从价格表取
+		List<Integer> remain = productIds.stream().filter(id -> !result.containsKey(id)).collect(Collectors.toList());
+		if (!remain.isEmpty()) {
+			List<StorePrice> prices = storePriceService.list(new LambdaQueryWrapper<StorePrice>()
+					.eq(StorePrice::getStoreId, storeId)
+					.in(StorePrice::getId, remain));
+			for (StorePrice p : prices) {
+				ProductInfo pi = new ProductInfo();
+				pi.name = p.getName();
+				pi.imageUrl = p.getImages();
+				pi.price = p.getTotalPrice();
+				result.put(p.getId(), pi);
+			}
 		}
-		return map;
+		return result;
+	}
+
+	private ProductInfo getProductInfo(Integer storeId, Integer productId) {
+		ProductInfo cached = buildProductInfoMap(storeId, java.util.Arrays.asList(productId)).get(productId);
+		return cached;
 	}
 
-	private StoreProductDiscountRuleSlotDto toSlotDto(StoreProductDiscountRuleSlot slot) {
-		StoreProductDiscountRuleSlotDto dto = new StoreProductDiscountRuleSlotDto();
-		dto.setWeekdayMask(slot.getWeekdayMask());
-		dto.setStartTime(slot.getStartTime() == null ? null : slot.getStartTime().format(TIME_FORMATTER));
-		dto.setEndTime(slot.getEndTime() == null ? null : slot.getEndTime().format(TIME_FORMATTER));
-		return dto;
+	private String groupKey(StoreProductDiscountRule r) {
+		return r.getStoreId() + "|" + r.getProductId() + "|" + r.getRuleName() + "|" + r.getDiscountType()
+				+ "|" + (r.getDiscountRate()==null?"":r.getDiscountRate().toPlainString())
+				+ "|" + r.getEffectiveMode() + "|" + formatDate(r.getStartDate()) + "|" + formatDate(r.getEndDate());
 	}
 
 	private StoreProductDiscountRule toEntity(StoreProductDiscountRuleSaveDto dto, boolean isUpdate) {
@@ -244,18 +324,6 @@ public class StoreProductDiscountServiceImpl implements StoreProductDiscountServ
 		return e;
 	}
 
-	private void saveSlots(Integer ruleId, List<StoreProductDiscountRuleSlotDto> slots) {
-		if (slots == null || slots.isEmpty()) return;
-		for (StoreProductDiscountRuleSlotDto s : slots) {
-			StoreProductDiscountRuleSlot entity = new StoreProductDiscountRuleSlot();
-			entity.setRuleId(ruleId);
-			entity.setWeekdayMask(s.getWeekdayMask());
-			if (StringUtils.hasText(s.getStartTime())) entity.setStartTime(LocalTime.parse(s.getStartTime(), TIME_FORMATTER));
-			if (StringUtils.hasText(s.getEndTime())) entity.setEndTime(LocalTime.parse(s.getEndTime(), TIME_FORMATTER));
-			ruleSlotMapper.insert(entity);
-		}
-	}
-
 	private String validateAndCheckConflict(StoreProductDiscountRuleSaveDto dto, Integer excludeId) {
 		// 基础
 		if (dto == null) return "参数不能为空";
@@ -301,7 +369,7 @@ public class StoreProductDiscountServiceImpl implements StoreProductDiscountServ
 		// 开启状态才参与冲突校验
 		if (dto.getStatus() != null && dto.getStatus() == 0) return null;
 
-		// 时间冲突校验(同店同菜品且status=1)
+		// 时间冲突校验(同店同菜品且status=1),单表直接基于已有行判断
 		LambdaQueryWrapper<StoreProductDiscountRule> qw = new LambdaQueryWrapper<>();
 		qw.eq(StoreProductDiscountRule::getStoreId, dto.getStoreId())
 				.eq(StoreProductDiscountRule::getProductId, dto.getProductId())
@@ -309,14 +377,9 @@ public class StoreProductDiscountServiceImpl implements StoreProductDiscountServ
 		if (excludeId != null) qw.ne(StoreProductDiscountRule::getId, excludeId);
 		List<StoreProductDiscountRule> exist = ruleMapper.selectList(qw);
 		if (exist.isEmpty()) return null;
-		List<Integer> existIds = exist.stream().map(StoreProductDiscountRule::getId).collect(Collectors.toList());
-		Map<Integer, List<StoreProductDiscountRuleSlot>> slotMap = ruleSlotMapper.selectList(new LambdaQueryWrapper<StoreProductDiscountRuleSlot>().in(StoreProductDiscountRuleSlot::getRuleId, existIds))
-				.stream().collect(Collectors.groupingBy(StoreProductDiscountRuleSlot::getRuleId));
 
 		Date newStart = MODE_CUSTOM.equals(dto.getEffectiveMode()) ? parseDate(dto.getStartDate()) : toDate(LocalDate.of(1970,1,1));
 		Date newEnd = MODE_CUSTOM.equals(dto.getEffectiveMode()) ? parseDate(dto.getEndDate()) : toDate(LocalDate.of(2099,12,31));
-
-		// 如果新规则没有slots,当作全星期/全天时间
 		List<StoreProductDiscountRuleSlotDto> newSlots = (dto.getSlots()==null || dto.getSlots().isEmpty())
 				? Collections.singletonList(allWeekAllDaySlotDto())
 				: dto.getSlots();
@@ -324,23 +387,19 @@ public class StoreProductDiscountServiceImpl implements StoreProductDiscountServ
 		for (StoreProductDiscountRule old : exist) {
 			Date oldStart = MODE_CUSTOM.equals(old.getEffectiveMode()) ? old.getStartDate() : toDate(LocalDate.of(1970,1,1));
 			Date oldEnd = MODE_CUSTOM.equals(old.getEffectiveMode()) ? old.getEndDate() : toDate(LocalDate.of(2099,12,31));
-			if (!( !newStart.after(oldEnd) && !oldStart.after(newEnd) )) continue; // 日期无交集
-			List<StoreProductDiscountRuleSlot> oldSlots = slotMap.getOrDefault(old.getId(), Collections.emptyList());
-			List<StoreProductDiscountRuleSlot> oldSlotsOrAll = oldSlots.isEmpty() ? Collections.singletonList(allWeekAllDaySlot()) : oldSlots;
+			if (!(!newStart.after(oldEnd) && !oldStart.after(newEnd))) continue;
+			int oMask = old.getWeekdayMask() == null ? 127 : old.getWeekdayMask();
+			LocalTime oSt = old.getStartTime() == null ? LocalTime.MIN : old.getStartTime();
+			LocalTime oEt = old.getEndTime() == null ? LocalTime.MAX : old.getEndTime();
 			for (StoreProductDiscountRuleSlotDto ns : newSlots) {
 				int nMask = ns.getWeekdayMask() == null ? 127 : ns.getWeekdayMask();
 				LocalTime nSt = StringUtils.hasText(ns.getStartTime()) ? LocalTime.parse(ns.getStartTime(), TIME_FORMATTER) : LocalTime.MIN;
 				LocalTime nEt = StringUtils.hasText(ns.getEndTime()) ? LocalTime.parse(ns.getEndTime(), TIME_FORMATTER) : LocalTime.MAX;
-				for (StoreProductDiscountRuleSlot os : oldSlotsOrAll) {
-					int oMask = os.getWeekdayMask() == null ? 127 : os.getWeekdayMask();
-					LocalTime oSt = os.getStartTime() == null ? LocalTime.MIN : os.getStartTime();
-					LocalTime oEt = os.getEndTime() == null ? LocalTime.MAX : os.getEndTime();
-					if ( (nMask & oMask) > 0 && nSt.isBefore(oEt) && oSt.isBefore(nEt) ) {
-						if (!dto.getDiscountType().equals(old.getDiscountType())) {
-							return "该菜品在该时间段已配置其他类型优惠";
-						}
-						return "该菜品优惠时间重叠,请调整生效日期/星期/时间";
+				if ( (nMask & oMask) > 0 && nSt.isBefore(oEt) && oSt.isBefore(nEt) ) {
+					if (!dto.getDiscountType().equals(old.getDiscountType())) {
+						return "该菜品在该时间段已配置其他类型优惠";
 					}
+					return "该菜品优惠时间重叠,请调整生效日期/星期/时间";
 				}
 			}
 		}