qmj 1 неделя назад
Родитель
Сommit
8039dfe703

+ 25 - 9
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PromotionActivityServiceImpl.java

@@ -49,15 +49,8 @@ public class PromotionActivityServiceImpl extends ServiceImpl<BaseMapper<Promoti
         {
             activity.setStatus(0);
         }
-        // 校验:同一门店同一促销类型只允许一个进行中的活动
-        LambdaQueryWrapper<PromotionActivity> dupCheck = new LambdaQueryWrapper<>();
-        dupCheck.eq(PromotionActivity::getStoreId, activity.getStoreId())
-                .eq(PromotionActivity::getType, activity.getType())
-                .eq(PromotionActivity::getStatus, 1);
-        if (promotionActivityMapper.selectCount(dupCheck) > 0)
-        {
-            throw new ServiceException("该门店已存在进行中的同类型活动");
-        }
+        // 校验:同一门店同一促销类型,同一时间段内只允许一个活动(时间段重叠即拒绝)
+        checkTimeOverlap(activity, null);
         int rows = promotionActivityMapper.insert(activity);
         Long activityId = activity.getId();
         // 逐条插入规则
@@ -69,6 +62,27 @@ public class PromotionActivityServiceImpl extends ServiceImpl<BaseMapper<Promoti
         return rows > 0;
     }
 
+    /**
+     * 校验:同一门店同一促销类型,时间段不与其他活动重叠(排除 excludeId)。
+     * 重叠判定:existing.start &le; newEnd 且 existing.end &ge; newStart(端点相接也视为重叠,禁止 06-16 当天两个活动都进行中)
+     */
+    private void checkTimeOverlap(PromotionActivity activity, Long excludeId)
+    {
+        LambdaQueryWrapper<PromotionActivity> w = new LambdaQueryWrapper<>();
+        w.eq(PromotionActivity::getStoreId, activity.getStoreId())
+                .eq(PromotionActivity::getType, activity.getType())
+                .le(PromotionActivity::getStartTime, activity.getEndTime())
+                .ge(PromotionActivity::getEndTime, activity.getStartTime());
+        if (excludeId != null)
+        {
+            w.ne(PromotionActivity::getId, excludeId);
+        }
+        if (promotionActivityMapper.selectCount(w) > 0)
+        {
+            throw new ServiceException("该门店该类型活动在该时间段内已存在,请调整活动时间");
+        }
+    }
+
     /**
      * 查询活动详情(含规则)
      */
@@ -108,6 +122,8 @@ public class PromotionActivityServiceImpl extends ServiceImpl<BaseMapper<Promoti
         {
             activity.setStatus(0);
         }
+        // 校验:同一门店同一促销类型,同一时间段内只允许一个活动(排除自身)
+        checkTimeOverlap(activity, activityId);
         int rows = promotionActivityMapper.updateById(activity);
         // 删除旧规则
         ruleMapper.delete(new LambdaQueryWrapper<PromotionActivityRule>().eq(PromotionActivityRule::getActivityId, activityId));

+ 73 - 1
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PromotionCouponBatchServiceImpl.java

@@ -1,7 +1,12 @@
 package com.ruoyi.system.service.impl;
 
+import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -152,7 +157,17 @@ public class PromotionCouponBatchServiceImpl extends ServiceImpl<BaseMapper<Prom
         }
         if (existing.getReceivedCount() != null && existing.getReceivedCount() > 0)
         {
-            // 已有人领取,只更新批次级别字段,不修改规则
+            // 已有人领取:只更新批次级别字段;若试图修改规则则拒绝
+            if (rule != null)
+            {
+                List<PromotionCouponRule> existingRules = ruleMapper.selectRulesByBatchId(batch.getId());
+                List<PromotionCouponRule> newRules = new ArrayList<>();
+                newRules.add(rule);
+                if (couponRulesDifferent(existingRules, newRules))
+                {
+                    throw new ServiceException("该优惠券已被领取,无法修改适用商品/规则");
+                }
+            }
             promotionCouponBatchMapper.updateById(batch);
         }
         else
@@ -195,6 +210,15 @@ public class PromotionCouponBatchServiceImpl extends ServiceImpl<BaseMapper<Prom
         }
         if (existing.getReceivedCount() != null && existing.getReceivedCount() > 0)
         {
+            // 已有人领取:只更新批次级别字段;若试图修改规则则拒绝
+            if (rules != null && !rules.isEmpty())
+            {
+                List<PromotionCouponRule> existingRules = ruleMapper.selectRulesByBatchId(batch.getId());
+                if (couponRulesDifferent(existingRules, rules))
+                {
+                    throw new ServiceException("该优惠券已被领取,无法修改适用商品/规则");
+                }
+            }
             promotionCouponBatchMapper.updateById(batch);
         }
         else
@@ -240,4 +264,52 @@ public class PromotionCouponBatchServiceImpl extends ServiceImpl<BaseMapper<Prom
         promotionCouponBatchMapper.deleteById(id);
         return true;
     }
+
+    /**
+     * 比较新旧优惠券规则是否一致(用于判断已领取券是否在尝试修改规则)。
+     * 按 productId 对齐逐条比较 discountRate/threshold/amount/isMutex,与顺序无关。
+     */
+    private boolean couponRulesDifferent(List<PromotionCouponRule> oldRules, List<PromotionCouponRule> newRules)
+    {
+        int oldSize = oldRules == null ? 0 : oldRules.size();
+        int newSize = newRules == null ? 0 : newRules.size();
+        if (oldSize != newSize)
+        {
+            return true;
+        }
+        Map<Long, PromotionCouponRule> oldMap = new HashMap<>();
+        if (oldRules != null)
+        {
+            for (PromotionCouponRule r : oldRules)
+            {
+                oldMap.put(r.getProductId(), r);
+            }
+        }
+        if (newRules != null)
+        {
+            for (PromotionCouponRule n : newRules)
+            {
+                PromotionCouponRule o = oldMap.get(n.getProductId());
+                if (o == null)
+                {
+                    return true;
+                }
+                if (compareDecimal(o.getDiscountRate(), n.getDiscountRate()) != 0
+                        || compareDecimal(o.getThreshold(), n.getThreshold()) != 0
+                        || compareDecimal(o.getAmount(), n.getAmount()) != 0
+                        || !Objects.equals(o.getIsMutex(), n.getIsMutex()))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private int compareDecimal(BigDecimal a, BigDecimal b)
+    {
+        BigDecimal x = a == null ? BigDecimal.ZERO : a;
+        BigDecimal y = b == null ? BigDecimal.ZERO : b;
+        return x.compareTo(y);
+    }
 }