|
|
@@ -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 "该菜品优惠时间重叠,请调整生效日期/星期/时间";
|
|
|
}
|
|
|
}
|
|
|
}
|