Просмотр исходного кода

好评赠券维护代码 商家端数量扣除 活动按数量发送

lutong 2 дней назад
Родитель
Сommit
a1047d7672

+ 6 - 1
alien-store/src/main/java/shop/alien/store/service/LifeDiscountCouponStoreFriendService.java

@@ -98,7 +98,12 @@ public interface LifeDiscountCouponStoreFriendService extends IService<LifeDisco
     int issueCouponForGoodRating(Integer userId, Integer storeId);
     int issueCouponForGoodRating(Integer userId, Integer storeId);
     
     
     /**
     /**
-     * 好评送券:按优惠券模板 ID(life_discount_coupon)发放到用户券包。
+     * 好评送券:按优惠券模板 ID(life_discount_coupon)发放到用户券包(默认 1 张)
      */
      */
     int issueCouponForGoodRating(Integer userId, Integer storeId, Integer couponId);
     int issueCouponForGoodRating(Integer userId, Integer storeId, Integer couponId);
+
+    /**
+     * 好评送券:按运营活动 {@code couponQuantity} 写入对应张数用户券;{@code null} 按 1 张(兼容旧数据),{@code 0} 或负数表示不发。
+     */
+    int issueCouponForGoodRating(Integer userId, Integer storeId, Integer couponId, Integer couponQuantity);
 }
 }

+ 8 - 10
alien-store/src/main/java/shop/alien/store/service/impl/CommonRatingServiceImpl.java

@@ -508,23 +508,21 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
                             continue;
                             continue;
                         }
                         }
                         
                         
-                        // 检查参与次数限制(每个活动单独计算
+                        // 参与次数限制(每条活动单独计;统计含本次已过审好评
                         Integer limit = activity.getParticipationLimit();
                         Integer limit = activity.getParticipationLimit();
-                        Integer couponQuantity = activity.getCouponQuantity();
-                        if (limit != null && limit > 0 && couponQuantity != null && couponQuantity > 0) {
-                            // 审核成功之前的评论不计算在参与次数中(只统计审核成功时间在活动审核时间之后的评论)
+                        if (limit != null && limit > 0) {
                             int passedCount = commonRatingMapper.countPassedGoodRatingsByUserAndStore(
                             int passedCount = commonRatingMapper.countPassedGoodRatingsByUserAndStore(
                                     commonRating.getUserId(), businessId, activity.getAuditTime());
                                     commonRating.getUserId(), businessId, activity.getAuditTime());
-                            if (passedCount > limit && passedCount > couponQuantity) {
-                                log.info("CommonRatingService 好评送券跳过:超过运营活动参与次数 activityId={}, participation_limit={}, count={}, userId={}, storeId={}, activityStartTime={}",
-                                        activity.getId(), limit, passedCount, commonRating.getUserId(), businessId, activity.getStartTime());
-                                continue; // 跳过该活动,继续处理下一个
+                            if (passedCount > limit) {
+                                log.info("CommonRatingService 好评送券跳过:超过运营活动参与次数 activityId={}, participation_limit={}, count={}, userId={}, storeId={}",
+                                        activity.getId(), limit, passedCount, commonRating.getUserId(), businessId);
+                                continue;
                             }
                             }
                         }
                         }
-                        
+
                         int issuedCount = lifeDiscountCouponStoreFriendService.issueCouponForGoodRating(
                         int issuedCount = lifeDiscountCouponStoreFriendService.issueCouponForGoodRating(
                                 Integer.valueOf(Math.toIntExact(commonRating.getUserId())), businessId,
                                 Integer.valueOf(Math.toIntExact(commonRating.getUserId())), businessId,
-                                activity.getCouponId());
+                                activity.getCouponId(), activity.getCouponQuantity());
                         
                         
                         if (issuedCount > 0) {
                         if (issuedCount > 0) {
                             totalIssuedCount += issuedCount;
                             totalIssuedCount += issuedCount;

+ 25 - 2
alien-store/src/main/java/shop/alien/store/service/impl/LifeDiscountCouponServiceImpl.java

@@ -11,6 +11,7 @@ import lombok.RequiredArgsConstructor;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.BeansException;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import shop.alien.entity.store.*;
 import shop.alien.entity.store.*;
 import shop.alien.entity.store.dto.LifeDiscountCouponDto;
 import shop.alien.entity.store.dto.LifeDiscountCouponDto;
 import shop.alien.entity.store.vo.LifeCouponStatusVo;
 import shop.alien.entity.store.vo.LifeCouponStatusVo;
@@ -1799,12 +1800,25 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
      * @return boolean
      * @return boolean
      */
      */
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public boolean issuePlatformCoupon(List<Integer> userIds, Integer couponId) {
     public boolean issuePlatformCoupon(List<Integer> userIds, Integer couponId) {
+        if (userIds == null || userIds.isEmpty()) {
+            return false;
+        }
         LifeDiscountCoupon lifeDiscountCoupon = this.getById(couponId);
         LifeDiscountCoupon lifeDiscountCoupon = this.getById(couponId);
         if (lifeDiscountCoupon == null) {
         if (lifeDiscountCoupon == null) {
-            //如果优惠券为空,则返回失败
             return false;
             return false;
         }
         }
+        int grantCount = userIds.size();
+
+        if (!LifeDiscountCouponStock.isUnlimitedQty(lifeDiscountCoupon.getUnlimitedQty())) {
+            Integer q = lifeDiscountCoupon.getSingleQty();
+            if (q == null || q < grantCount) {
+                return false;
+            }
+            lifeDiscountCoupon.setSingleQty(q - grantCount);
+        }
+
         List<LifeDiscountCouponUser> lifeDiscountCouponUsers = new ArrayList<>();
         List<LifeDiscountCouponUser> lifeDiscountCouponUsers = new ArrayList<>();
         for (Integer userId : userIds) {
         for (Integer userId : userIds) {
             LifeDiscountCouponUser lifeDiscountCouponUser = new LifeDiscountCouponUser();
             LifeDiscountCouponUser lifeDiscountCouponUser = new LifeDiscountCouponUser();
@@ -1825,7 +1839,16 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
             lifeDiscountCouponUser.setIssueSource(5); // 5-平台发放
             lifeDiscountCouponUser.setIssueSource(5); // 5-平台发放
             lifeDiscountCouponUsers.add(lifeDiscountCouponUser);
             lifeDiscountCouponUsers.add(lifeDiscountCouponUser);
         }
         }
-        return lifeDiscountCouponUserService.saveBatch(lifeDiscountCouponUsers);
+        if (!lifeDiscountCouponUserService.saveBatch(lifeDiscountCouponUsers)) {
+            return false;
+        }
+        if (!LifeDiscountCouponStock.isUnlimitedQty(lifeDiscountCoupon.getUnlimitedQty())) {
+            lifeDiscountCoupon.setUpdatedTime(new Date());
+            if (!this.updateById(lifeDiscountCoupon)) {
+                throw new IllegalStateException("平台发券失败:优惠券模板发行量更新失败 couponId=" + couponId);
+            }
+        }
+        return true;
     }
     }
 
 
     /**
     /**

+ 89 - 38
alien-store/src/main/java/shop/alien/store/service/impl/LifeDiscountCouponStoreFriendServiceImpl.java

@@ -54,6 +54,9 @@ public class LifeDiscountCouponStoreFriendServiceImpl extends ServiceImpl<LifeDi
 
 
     final String STORE_PREFIX = "store_";
     final String STORE_PREFIX = "store_";
 
 
+    /** 单次好评发券的张数上限,防止运营误填特大数字 */
+    private static final int GOOD_RATING_ISSUE_COPIES_HARD_CAP = 50;
+
     private final StoreUserMapper storeUserMapper;
     private final StoreUserMapper storeUserMapper;
 
 
     private final LifeFansMapper lifeFansMapper;
     private final LifeFansMapper lifeFansMapper;
@@ -1180,14 +1183,24 @@ public class LifeDiscountCouponStoreFriendServiceImpl extends ServiceImpl<LifeDi
             // 只统计活动开始时间之后的好评,活动开始前的评论不计入参与次数
             // 只统计活动开始时间之后的好评,活动开始前的评论不计入参与次数
             int passedCount = commonRatingMapper.countPassedGoodRatingsByUserAndStore(
             int passedCount = commonRatingMapper.countPassedGoodRatingsByUserAndStore(
                     Long.valueOf(userId), storeId, activity.getStartTime());
                     Long.valueOf(userId), storeId, activity.getStartTime());
-            if (passedCount >= limit) {
+            if (passedCount > limit) {
                 log.info("issueCouponForGoodRating 好评送券跳过:超过运营活动参与次数 participation_limit={}, count={}, userId={}, storeId={}, activityStartTime={}",
                 log.info("issueCouponForGoodRating 好评送券跳过:超过运营活动参与次数 participation_limit={}, count={}, userId={}, storeId={}, activityStartTime={}",
                         limit, passedCount, userId, storeId, activity.getStartTime());
                         limit, passedCount, userId, storeId, activity.getStartTime());
                 return 0;
                 return 0;
             }
             }
         }
         }
-        
-        return issueCouponForGoodRating(userId, storeId, activity.getCouponId());
+
+        return issueCouponForGoodRating(userId, storeId, activity.getCouponId(), activity.getCouponQuantity());
+    }
+
+    private static int resolveGoodRatingCouponCopies(Integer couponQuantity) {
+        if (couponQuantity == null) {
+            return 1;
+        }
+        if (couponQuantity < 1) {
+            return 0;
+        }
+        return Math.min(couponQuantity, GOOD_RATING_ISSUE_COPIES_HARD_CAP);
     }
     }
 
 
     /**
     /**
@@ -1195,6 +1208,11 @@ public class LifeDiscountCouponStoreFriendServiceImpl extends ServiceImpl<LifeDi
      */
      */
     @Override
     @Override
     public int issueCouponForGoodRating(Integer userId, Integer storeId, Integer couponId) {
     public int issueCouponForGoodRating(Integer userId, Integer storeId, Integer couponId) {
+        return issueCouponForGoodRating(userId, storeId, couponId, null);
+    }
+
+    @Override
+    public int issueCouponForGoodRating(Integer userId, Integer storeId, Integer couponId, Integer couponQuantity) {
         if (userId == null || storeId == null) {
         if (userId == null || storeId == null) {
             return 0;
             return 0;
         }
         }
@@ -1202,28 +1220,68 @@ public class LifeDiscountCouponStoreFriendServiceImpl extends ServiceImpl<LifeDi
             return 0;
             return 0;
         }
         }
         int commenterUserId = userId.intValue();
         int commenterUserId = userId.intValue();
+        int copiesWanted = resolveGoodRatingCouponCopies(couponQuantity);
+        if (copiesWanted < 1) {
+            return 0;
+        }
+
         StoreInfo storeInfo = storeInfoMapper.selectById(storeId);
         StoreInfo storeInfo = storeInfoMapper.selectById(storeId);
         LifeUser lifeUser = lifeUserMapper.selectById(commenterUserId);
         LifeUser lifeUser = lifeUserMapper.selectById(commenterUserId);
-        int grantedCoupon = 0;
-        String couponName = null;
-        LifeDiscountCoupon lifeDiscountCoupon = null;
 
 
         LifeDiscountCoupon coupon = lifeDiscountCouponMapper.selectById(couponId);
         LifeDiscountCoupon coupon = lifeDiscountCouponMapper.selectById(couponId);
-        if (coupon != null && String.valueOf(storeId).equals(coupon.getStoreId())
-                && LifeDiscountCouponStock.hasTemplateStockRemaining(coupon.getUnlimitedQty(), coupon.getSingleQty())) {
+        if (coupon == null || !String.valueOf(storeId).equals(coupon.getStoreId())) {
+            return 0;
+        }
+        if (!LifeDiscountCouponStock.hasTemplateStockRemaining(coupon.getUnlimitedQty(), coupon.getSingleQty())) {
+            return 0;
+        }
+
+        ZoneId zone = ZoneId.systemDefault();
+        if (!Integer.valueOf(1).equals(coupon.getLongTermValid())) {
+            LocalDate beginDate = coupon.getBeginGetDate();
+            if (beginDate == null) {
+                beginDate = LocalDate.now(zone);
+                coupon.setBeginGetDate(beginDate);
+            }
+            String specifiedDayStr = coupon.getSpecifiedDay();
+            if (specifiedDayStr == null || specifiedDayStr.isEmpty()) {
+                log.error("发放优惠券失败(非长期券缺少有效天数),userId={}, storeId={}, couponId={}", userId, storeId, couponId);
+                return 0;
+            }
+            int days;
+            try {
+                days = Integer.parseInt(specifiedDayStr.trim());
+            } catch (NumberFormatException e) {
+                log.error("发放优惠券失败(有效天数非法),userId={}, storeId={}, couponId={}, specifiedDay={}",
+                        userId, storeId, couponId, specifiedDayStr, e);
+                return 0;
+            }
+            if (days <= 0) {
+                log.error("发放优惠券失败(有效天数须>0),userId={}, storeId={}, couponId={}", userId, storeId, couponId);
+                return 0;
+            }
+            coupon.setEndGetDate(beginDate.plusDays(days));
+        }
+
+        int grantedCoupon = 0;
+        for (int i = 0; i < copiesWanted; i++) {
+            if (!LifeDiscountCouponStock.hasTemplateStockRemaining(coupon.getUnlimitedQty(), coupon.getSingleQty())) {
+                break;
+            }
             try {
             try {
+                Date receiveTime = new Date();
                 LifeDiscountCouponUser lifeDiscountCouponUser = new LifeDiscountCouponUser();
                 LifeDiscountCouponUser lifeDiscountCouponUser = new LifeDiscountCouponUser();
                 lifeDiscountCouponUser.setCouponId(coupon.getId());
                 lifeDiscountCouponUser.setCouponId(coupon.getId());
                 lifeDiscountCouponUser.setUserId(commenterUserId);
                 lifeDiscountCouponUser.setUserId(commenterUserId);
-                lifeDiscountCouponUser.setReceiveTime(new Date());
+                lifeDiscountCouponUser.setReceiveTime(receiveTime);
                 lifeDiscountCouponUser.setExpirationTime(DiscountCouponExpirationUtil.resolveLifeDiscountCouponExpiration(
                 lifeDiscountCouponUser.setExpirationTime(DiscountCouponExpirationUtil.resolveLifeDiscountCouponExpiration(
-                        lifeDiscountCouponUser.getReceiveTime(),
+                        receiveTime,
                         coupon.getLongTermValid(),
                         coupon.getLongTermValid(),
                         coupon.getSpecifiedDay(),
                         coupon.getSpecifiedDay(),
                         coupon.getExpirationDate(),
                         coupon.getExpirationDate(),
                         coupon.getValidDate(),
                         coupon.getValidDate(),
                         coupon.getEndDate(),
                         coupon.getEndDate(),
-                        ZoneId.systemDefault()));
+                        zone));
                 lifeDiscountCouponUser.setStatus(Integer.parseInt(DiscountCouponEnum.WAITING_USED.getValue()));
                 lifeDiscountCouponUser.setStatus(Integer.parseInt(DiscountCouponEnum.WAITING_USED.getValue()));
                 lifeDiscountCouponUser.setDeleteFlag(0);
                 lifeDiscountCouponUser.setDeleteFlag(0);
                 lifeDiscountCouponUser.setIssueSource(3); // 3-好评送券
                 lifeDiscountCouponUser.setIssueSource(3); // 3-好评送券
@@ -1232,37 +1290,25 @@ public class LifeDiscountCouponStoreFriendServiceImpl extends ServiceImpl<LifeDi
                         && coupon.getSingleQty() != null) {
                         && coupon.getSingleQty() != null) {
                     coupon.setSingleQty(coupon.getSingleQty() - 1);
                     coupon.setSingleQty(coupon.getSingleQty() - 1);
                 }
                 }
-                if (!Integer.valueOf(1).equals(coupon.getLongTermValid())) {
-                    LocalDate beginDate = coupon.getBeginGetDate();
-                    if (beginDate == null) {
-                        beginDate = LocalDate.now(ZoneId.systemDefault());
-                        coupon.setBeginGetDate(beginDate);
-                    }
-                    String specifiedDayStr = coupon.getSpecifiedDay();
-                    if (specifiedDayStr == null || specifiedDayStr.isEmpty()) {
-                        throw new IllegalArgumentException("有效天数不能为空");
-                    }
-                    int days;
-                    try {
-                        days = Integer.parseInt(specifiedDayStr);
-                    } catch (NumberFormatException e) {
-                        throw new IllegalArgumentException("有效天数必须是纯数字:" + specifiedDayStr);
-                    }
-                    if (days <= 0) {
-                        throw new IllegalArgumentException("有效天数必须大于0");
-                    }
-                    LocalDate endDate = beginDate.plusDays(days);
-                    coupon.setEndGetDate(endDate);
-                }
+                grantedCoupon++;
+            } catch (Exception e) {
+                log.error("发放优惠券失败,userId={}, storeId={}, couponId={}, index={}, error={}",
+                        userId, storeId, couponId, i, e.getMessage(), e);
+                break;
+            }
+        }
+
+        if (grantedCoupon > 0) {
+            try {
                 lifeDiscountCouponMapper.updateById(coupon);
                 lifeDiscountCouponMapper.updateById(coupon);
-                grantedCoupon = 1;
-                couponName = coupon.getName();
-                lifeDiscountCoupon = coupon;
             } catch (Exception e) {
             } catch (Exception e) {
-                log.error("发放优惠券失败,userId={}, storeId={}, couponId={}, error={}", userId, storeId, couponId, e.getMessage(), e);
+                log.error("更新优惠券模板失败 userId={}, storeId={}, couponId={}, error={}", userId, storeId, couponId, e.getMessage(), e);
             }
             }
         }
         }
 
 
+        LifeDiscountCoupon lifeDiscountCoupon = grantedCoupon > 0 ? coupon : null;
+        String couponName = grantedCoupon > 0 ? coupon.getName() : null;
+
         if (lifeUser != null && storeInfo != null && grantedCoupon > 0 && couponName != null) {
         if (lifeUser != null && storeInfo != null && grantedCoupon > 0 && couponName != null) {
             LifeNotice couponNotice = new LifeNotice();
             LifeNotice couponNotice = new LifeNotice();
             couponNotice.setSenderId("system");
             couponNotice.setSenderId("system");
@@ -1293,11 +1339,16 @@ public class LifeDiscountCouponStoreFriendServiceImpl extends ServiceImpl<LifeDi
                 }
                 }
             }
             }
 
 
-            String couponText = "您对店铺「" + storeInfo.getStoreName() + "」的好评已通过审核,已为您发放优惠券「" + couponName + "」" + couponDetailText + ",快去我的券包查看吧~";
+            String couponText = grantedCoupon > 1
+                    ? "您对店铺「" + storeInfo.getStoreName() + "」的好评已通过审核,已为您发放优惠券「" + couponName + "」"
+                    + couponDetailText + "共" + grantedCoupon + "张,快去我的券包查看吧~"
+                    : "您对店铺「" + storeInfo.getStoreName() + "」的好评已通过审核,已为您发放优惠券「" + couponName + "」"
+                    + couponDetailText + ",快去我的券包查看吧~";
             JSONObject couponJson = new JSONObject();
             JSONObject couponJson = new JSONObject();
             couponJson.put("message", couponText);
             couponJson.put("message", couponText);
             couponJson.put("couponType", "优惠券");
             couponJson.put("couponType", "优惠券");
             couponJson.put("couponName", couponName);
             couponJson.put("couponName", couponName);
+            couponJson.put("grantCount", grantedCoupon);
             if (lifeDiscountCoupon != null) {
             if (lifeDiscountCoupon != null) {
                 couponJson.put("couponTypeValue", lifeDiscountCoupon.getCouponType());
                 couponJson.put("couponTypeValue", lifeDiscountCoupon.getCouponType());
             }
             }