PromotionActivityServiceImpl.java 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package com.ruoyi.system.service.impl;
  2. import java.util.Date;
  3. import java.util.List;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Service;
  6. import org.springframework.transaction.annotation.Transactional;
  7. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  8. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  9. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  10. import com.ruoyi.common.exception.ServiceException;
  11. import com.ruoyi.system.mapper.PromotionActivityMapper;
  12. import com.ruoyi.system.mapper.PromotionActivityRuleMapper;
  13. import com.ruoyi.system.domain.PromotionActivity;
  14. import com.ruoyi.system.domain.PromotionActivityRule;
  15. import com.ruoyi.system.service.IPromotionActivityService;
  16. /**
  17. * 促销活动Service业务层处理
  18. *
  19. * @author ruoyi
  20. * @date 2024-05-30
  21. */
  22. @Service
  23. public class PromotionActivityServiceImpl extends ServiceImpl<BaseMapper<PromotionActivity>, PromotionActivity> implements IPromotionActivityService
  24. {
  25. @Autowired
  26. private PromotionActivityMapper promotionActivityMapper;
  27. @Autowired
  28. private PromotionActivityRuleMapper ruleMapper;
  29. @Autowired
  30. private PromotionDiscountLimitChecker discountLimitChecker;
  31. /**
  32. * 创建促销活动(含规则)
  33. */
  34. @Override
  35. @Transactional
  36. public boolean createActivity(PromotionActivity activity, List<PromotionActivityRule> rules)
  37. {
  38. Date now = new Date();
  39. activity.setCreateTime(now);
  40. activity.setUpdateTime(now);
  41. // 根据开始时间设置状态:开始时间早于当前→进行中(1),否则→未开始(0)
  42. if (activity.getStartTime() != null && activity.getStartTime().before(now))
  43. {
  44. activity.setStatus(1);
  45. }
  46. else
  47. {
  48. activity.setStatus(0);
  49. }
  50. // 校验:同一门店同一促销类型,同一时间段内只允许一个活动(时间段重叠即拒绝)
  51. checkTimeOverlap(activity, null);
  52. // 校验:优惠幅度限制(平台开关控制,满减档位/折扣率不超上限)
  53. discountLimitChecker.checkActivity(activity, rules);
  54. int rows = promotionActivityMapper.insert(activity);
  55. Long activityId = activity.getId();
  56. // 逐条插入规则
  57. for (PromotionActivityRule rule : rules)
  58. {
  59. rule.setActivityId(activityId);
  60. ruleMapper.insert(rule);
  61. }
  62. return rows > 0;
  63. }
  64. /**
  65. * 校验:同一门店同一促销类型,时间段不与其他活动重叠(排除 excludeId)。
  66. * 重叠判定:existing.start &le; newEnd 且 existing.end &ge; newStart(端点相接也视为重叠,禁止 06-16 当天两个活动都进行中)
  67. */
  68. private void checkTimeOverlap(PromotionActivity activity, Long excludeId)
  69. {
  70. LambdaQueryWrapper<PromotionActivity> w = new LambdaQueryWrapper<>();
  71. w.eq(PromotionActivity::getStoreId, activity.getStoreId())
  72. .eq(PromotionActivity::getType, activity.getType())
  73. .ne(PromotionActivity::getStatus, 2) // 排除已结束/已停止,允许在其原时段重新建促销
  74. .le(PromotionActivity::getStartTime, activity.getEndTime())
  75. .ge(PromotionActivity::getEndTime, activity.getStartTime());
  76. if (excludeId != null)
  77. {
  78. w.ne(PromotionActivity::getId, excludeId);
  79. }
  80. if (promotionActivityMapper.selectCount(w) > 0)
  81. {
  82. throw new ServiceException("该门店该类型活动在该时间段内已存在,请调整活动时间");
  83. }
  84. }
  85. /**
  86. * 查询活动详情(含规则)
  87. */
  88. @Override
  89. public PromotionActivity selectActivityWithRules(Long id)
  90. {
  91. PromotionActivity activity = promotionActivityMapper.selectById(id);
  92. if (activity != null)
  93. {
  94. List<PromotionActivityRule> rules = ruleMapper.selectRulesByActivityId(id);
  95. activity.setRules(rules);
  96. }
  97. return activity;
  98. }
  99. /**
  100. * 修改促销活动(仅未开始)
  101. */
  102. @Override
  103. @Transactional
  104. public boolean updateActivity(PromotionActivity activity, List<PromotionActivityRule> rules)
  105. {
  106. Long activityId = activity.getId();
  107. PromotionActivity existing = promotionActivityMapper.selectById(activityId);
  108. if (existing == null || existing.getStatus() != 0)
  109. {
  110. throw new ServiceException("只能修改未开始的活动");
  111. }
  112. Date now = new Date();
  113. activity.setUpdateTime(now);
  114. // 根据开始时间设置状态:开始时间早于当前→进行中(1),否则→未开始(0)
  115. if (activity.getStartTime() != null && activity.getStartTime().before(now))
  116. {
  117. activity.setStatus(1);
  118. }
  119. else
  120. {
  121. activity.setStatus(0);
  122. }
  123. // 校验:同一门店同一促销类型,同一时间段内只允许一个活动(排除自身)
  124. checkTimeOverlap(activity, activityId);
  125. // 编辑入参可能不带 type,回填现有值供优惠幅度校验用(写回同值无副作用)
  126. if (activity.getType() == null)
  127. {
  128. activity.setType(existing.getType());
  129. }
  130. // 校验:优惠幅度限制(平台开关控制,满减档位/折扣率不超上限)
  131. discountLimitChecker.checkActivity(activity, rules);
  132. int rows = promotionActivityMapper.updateById(activity);
  133. // 删除旧规则
  134. ruleMapper.delete(new LambdaQueryWrapper<PromotionActivityRule>().eq(PromotionActivityRule::getActivityId, activityId));
  135. // 重新插入新规则
  136. for (PromotionActivityRule rule : rules)
  137. {
  138. rule.setActivityId(activityId);
  139. ruleMapper.insert(rule);
  140. }
  141. return rows > 0;
  142. }
  143. /**
  144. * 删除促销活动(仅未开始)
  145. */
  146. @Override
  147. @Transactional
  148. public boolean deleteActivity(Long id)
  149. {
  150. PromotionActivity existing = promotionActivityMapper.selectById(id);
  151. if (existing == null || existing.getStatus() != 0)
  152. {
  153. throw new ServiceException("只能删除未开始的活动");
  154. }
  155. // 删除规则
  156. ruleMapper.delete(new LambdaQueryWrapper<PromotionActivityRule>().eq(PromotionActivityRule::getActivityId, id));
  157. // 删除活动
  158. return promotionActivityMapper.deleteById(id) > 0;
  159. }
  160. /**
  161. * 结束活动(仅进行中)
  162. */
  163. @Override
  164. public boolean endActivity(Long id)
  165. {
  166. PromotionActivity existing = promotionActivityMapper.selectById(id);
  167. if (existing == null || existing.getStatus() != 1)
  168. {
  169. throw new ServiceException("只能结束进行中的活动");
  170. }
  171. PromotionActivity activity = new PromotionActivity();
  172. activity.setId(id);
  173. activity.setStatus(2);
  174. activity.setUpdateTime(new Date());
  175. return promotionActivityMapper.updateById(activity) > 0;
  176. }
  177. }