|
@@ -0,0 +1,102 @@
|
|
|
+package cn.iocoder.yudao.module.promotion.service.bargain;
|
|
|
+
|
|
|
+import cn.hutool.core.lang.Assert;
|
|
|
+import cn.hutool.core.util.ObjUtil;
|
|
|
+import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.help.AppBargainHelpCreateReqVO;
|
|
|
+import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
|
|
|
+import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainHelpDO;
|
|
|
+import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO;
|
|
|
+import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainHelpMapper;
|
|
|
+import cn.iocoder.yudao.module.promotion.enums.bargain.BargainRecordStatusEnum;
|
|
|
+import jodd.util.MathUtil;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.validation.annotation.Validated;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+
|
|
|
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
+import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 砍价助力 Service 实现类
|
|
|
+ *
|
|
|
+ * @author 芋道源码
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@Validated
|
|
|
+public class BargainHelpServiceImpl implements BargainHelpService {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private BargainHelpMapper bargainHelpMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private BargainRecordService bargainRecordService;
|
|
|
+ @Resource
|
|
|
+ private BargainActivityService bargainActivityService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public BargainHelpDO createBargainHelp(Long userId, AppBargainHelpCreateReqVO reqVO) {
|
|
|
+ // 1.1 校验砍价记录存在,并且处于进行中
|
|
|
+ BargainRecordDO record = bargainRecordService.getBargainRecord(reqVO.getRecordId());
|
|
|
+ if (record == null) {
|
|
|
+ throw exception(BARGAIN_RECORD_NOT_EXISTS);
|
|
|
+ }
|
|
|
+ if (ObjUtil.notEqual(record.getStatus(), BargainRecordStatusEnum.IN_PROGRESS.getStatus())) {
|
|
|
+ throw exception(BARGAIN_HELP_CREATE_FAIL_RECORD_NOT_IN_PROCESS);
|
|
|
+ }
|
|
|
+ // 1.2 不能自己给自己砍价
|
|
|
+ if (ObjUtil.equal(record.getUserId(), userId)) {
|
|
|
+ throw exception(BARGAIN_HELP_CREATE_FAIL_RECORD_SELF);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2.1 校验砍价活动
|
|
|
+ BargainActivityDO activity = bargainActivityService.getBargainActivity(record.getActivityId());
|
|
|
+ // 2.2 校验自己是否助力次数上限
|
|
|
+ if (bargainHelpMapper.selectCountByUserIdAndActivityId(userId, activity.getId())
|
|
|
+ >= activity.getBargainCount()) {
|
|
|
+ throw exception(BARGAIN_HELP_CREATE_FAIL_LIMIT);
|
|
|
+ }
|
|
|
+ // 2.3 特殊情况:砍价已经砍到最低价,不能再砍了
|
|
|
+ if (record.getBargainPrice() <= activity.getBargainMinPrice()) {
|
|
|
+ throw exception(BARGAIN_HELP_CREATE_FAIL_RECORD_NOT_IN_PROCESS);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 已经助力
|
|
|
+ if (bargainHelpMapper.selectByUserIdAndRecordId(userId, record.getId()) != null) {
|
|
|
+ throw exception(BARGAIN_HELP_CREATE_FAIL_HELP_EXISTS);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4.1 计算砍价金额
|
|
|
+ Integer reducePrice = calculateReducePrice(activity, record);
|
|
|
+ Assert.isTrue(reducePrice > 0, "砍价金额必须大于 0 元");
|
|
|
+ // 4.2 创建助力记录
|
|
|
+ BargainHelpDO help = BargainHelpDO.builder().userId(userId).activityId(activity.getId())
|
|
|
+ .recordId(record.getId()).reducePrice(reducePrice).build();
|
|
|
+ bargainHelpMapper.insert(help);
|
|
|
+
|
|
|
+ // 5. 判断砍价记录是否完成
|
|
|
+ Boolean success = record.getBargainPrice() - reducePrice <= activity.getBargainMinPrice() // 情况一:砍价已经砍到最低价
|
|
|
+ || bargainHelpMapper.selectCountByRecordId(reqVO.getRecordId()) >= activity.getTotalLimitCount(); // 情况二:砍价助力已经达到上限
|
|
|
+ if (!bargainRecordService.updateBargainRecordBargainPrice(
|
|
|
+ record.getId(), record.getBargainPrice(), reducePrice, success)) {
|
|
|
+ // 多人一起砍价,需要重试
|
|
|
+ throw exception(BARGAIN_HELP_CREATE_FAIL_CONFLICT);
|
|
|
+ }
|
|
|
+ return help;
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO 芋艿:优化点:实现一个更随机的逻辑,可以按照你自己的业务;
|
|
|
+ private Integer calculateReducePrice(BargainActivityDO activity, BargainRecordDO record) {
|
|
|
+ // 1. 随机金额
|
|
|
+ Integer reducePrice = MathUtil.randomInt(activity.getBargainMinPrice(),
|
|
|
+ activity.getRandomMaxPrice() + 1); // + 1 的原因是,randomInt 默认不包含第二个参数
|
|
|
+ // 2. 校验是否超过砍价上限
|
|
|
+ if (record.getBargainPrice() - reducePrice < activity.getBargainMinPrice()) {
|
|
|
+ reducePrice = record.getBargainPrice() - activity.getBargainMinPrice();
|
|
|
+ }
|
|
|
+ return reducePrice;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|