Преглед изворни кода

Merge remote-tracking branch 'origin/master'

guomengjiao пре 4 месеци
родитељ
комит
cc23547649

+ 2 - 0
ruoyi-line/src/main/java/com/ruoyi/subsidy/domain/SubsidyModeAuto.java

@@ -40,10 +40,12 @@ public class SubsidyModeAuto extends BaseTimeEntity {
     /**
      * 最高排队人数
      */
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
     private Integer maxQueueCount;
     /**
      * 自动转化日期
      */
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
     private Date autoConvertDate;
     /**
      * 转换目标模式ID

+ 2 - 0
ruoyi-line/src/main/java/com/ruoyi/subsidy/mapper/SubsidyQueueMapper.java

@@ -14,4 +14,6 @@ import org.apache.ibatis.annotations.Param;
 public interface SubsidyQueueMapper extends BaseMapperPlus<SubsidyQueueMapper, SubsidyQueue, SubsidyQueueVo> {
 
     Long validQueueCountAndLock(@Param("businessId") Long businessId);
+
+    SubsidyQueue validFirstQueue(@Param("businessId") Long businessId);
 }

+ 210 - 28
ruoyi-line/src/main/java/com/ruoyi/subsidy/service/impl/SubsidyQueueServiceImpl.java

@@ -2,6 +2,7 @@ package com.ruoyi.subsidy.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.BeanCopyUtils;
 import com.ruoyi.common.utils.MathUtils;
@@ -15,9 +16,13 @@ import com.ruoyi.onlineorder.domain.OnlineOrder;
 import com.ruoyi.onlineorder.service.IOnlineOrderService;
 import com.ruoyi.subsidy.domain.SubsidyCutIn;
 import com.ruoyi.subsidy.domain.SubsidyMode;
+import com.ruoyi.subsidy.enums.SubsidyCancelType;
 import com.ruoyi.subsidy.enums.SubsidyStatus;
 import com.ruoyi.subsidy.service.ISubsidyCutInService;
 import com.ruoyi.subsidy.service.ISubsidyModeService;
+import com.ruoyi.user.domain.bo.UserChangeBalanceBo;
+import com.ruoyi.user.enums.BalanceSourceType;
+import com.ruoyi.user.service.IUserService;
 import lombok.RequiredArgsConstructor;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
@@ -30,6 +35,7 @@ import com.ruoyi.subsidy.exception.SubsidyQueueExceptionEnum;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Collection;
@@ -47,7 +53,7 @@ public class SubsidyQueueServiceImpl implements ISubsidyQueueService {
     private final SubsidyQueueMapper baseMapper;
     @Lazy
     @Resource
-    private  ISubsidyModeService subsidyModeService;
+    private ISubsidyModeService subsidyModeService;
 
     @Lazy
     @Resource
@@ -57,6 +63,10 @@ public class SubsidyQueueServiceImpl implements ISubsidyQueueService {
     @Resource
     private ISubsidyCutInService subsidyCutInService;
 
+    @Lazy
+    @Resource
+    private IUserService userService;
+
     /**
      * 查询补贴排队分页
      *
@@ -101,7 +111,7 @@ public class SubsidyQueueServiceImpl implements ISubsidyQueueService {
         lqw.eq(bo.getSubsidyPoints() != null, SubsidyQueue::getSubsidyPoints, bo.getSubsidyPoints());
         lqw.eq(bo.getSubsidyStatus() != null, SubsidyQueue::getSubsidyStatus, bo.getSubsidyStatus());
         lqw.eq(bo.getCutIn() != null, SubsidyQueue::getCutIn, bo.getCutIn());
-         lqw.eq(bo.getCancelled() != null, SubsidyQueue::getCancelled, bo.getCancelled());
+        lqw.eq(bo.getCancelled() != null, SubsidyQueue::getCancelled, bo.getCancelled());
         lqw.eq(bo.getExchanged() != null, SubsidyQueue::getExchanged, bo.getExchanged());
         lqw.eq(bo.getExchangePoints() != null, SubsidyQueue::getExchangePoints, bo.getExchangePoints());
         lqw.eq(bo.getActualPointsAfterCancel() != null, SubsidyQueue::getActualPointsAfterCancel, bo.getActualPointsAfterCancel());
@@ -121,7 +131,7 @@ public class SubsidyQueueServiceImpl implements ISubsidyQueueService {
      * @return 补贴排队
      */
     @Override
-    public SubsidyQueueVo queryById(Long queueId){
+    public SubsidyQueueVo queryById(Long queueId) {
         return baseMapper.selectVoById(queueId);
     }
 
@@ -132,9 +142,9 @@ public class SubsidyQueueServiceImpl implements ISubsidyQueueService {
      * @return 补贴排队
      */
     @Override
-    public SubsidyQueue loadById(Long queueId, Boolean tw){
+    public SubsidyQueue loadById(Long queueId, Boolean tw) {
         SubsidyQueue info = this.baseMapper.selectById(queueId);
-        if(ObjectUtil.isEmpty(info) && tw){
+        if (ObjectUtil.isEmpty(info) && tw) {
             throw new ServiceException(SubsidyQueueExceptionEnum.SubsidyQueue_IS_NOT_EXISTS);
         }
         return info;
@@ -176,7 +186,7 @@ public class SubsidyQueueServiceImpl implements ISubsidyQueueService {
      *
      * @param entity 实体类数据
      */
-    private void validEntityBeforeSave(SubsidyQueue entity){
+    private void validEntityBeforeSave(SubsidyQueue entity) {
         //TODO 做一些数据校验,如唯一约束
     }
 
@@ -188,7 +198,7 @@ public class SubsidyQueueServiceImpl implements ISubsidyQueueService {
      */
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if(isValid){
+        if (isValid) {
             //TODO 做一些业务上的校验,判断是否需要校验
         }
         return baseMapper.deleteBatchIds(ids) > 0;
@@ -202,6 +212,12 @@ public class SubsidyQueueServiceImpl implements ISubsidyQueueService {
         );
     }
 
+    /**
+     * 获取商家当前排队人数
+     *
+     * @param businessId 商家id
+     * @return 排队人数
+     */
     @Override
     public Long validQueueCountAndLock(Long businessId) {
         return this.baseMapper.validQueueCountAndLock(businessId);
@@ -210,7 +226,7 @@ public class SubsidyQueueServiceImpl implements ISubsidyQueueService {
     @Override
     public void createQueue(OnlineOrder order) {
         SubsidyMode currentMode = subsidyModeService.loadCurrentMode(order.getBusinessId());
-        // 商家让利金额
+        // 商家总供让利金额
         BigDecimal shouldSubsidyAmount = MathUtils.setScale(order.getPayAmount().doubleValue() * currentMode.getSubsidyRatio().doubleValue() / 100);
         // 有效的第一个插队补贴数据
         SubsidyCutIn firstSubsidyCutIn = subsidyCutInService.validFirstSubsidyCutIn(order.getBusinessId());
@@ -218,43 +234,209 @@ public class SubsidyQueueServiceImpl implements ISubsidyQueueService {
         BigDecimal subsidyCutIn = BigDecimal.ZERO;
         //排队补贴金额
         BigDecimal subsidyQueue = BigDecimal.ZERO;
+
+        // 当前有效排队人数
+        Long validQueueCount = this.validQueueCountAndLock(order.getBusinessId());
+        // 当前插队有效排队人数
+        Long validCutinCount = subsidyCutInService.validQueueCountAndLock(order.getBusinessId());
+
         // 存在第一个补贴插队数据
-        if(ObjectUtil.isNotNull(firstSubsidyCutIn))
-        {
-             subsidyCutIn = MathUtils.setScale(shouldSubsidyAmount.doubleValue() * firstSubsidyCutIn.getCutInRatio().doubleValue()/100);
+        if (ObjectUtil.isNotNull(firstSubsidyCutIn)) {
+            subsidyCutIn = MathUtils.setScale(shouldSubsidyAmount.doubleValue() * firstSubsidyCutIn.getCutInRatio().doubleValue() / 100);
         }
         //排队补贴金额 = 补贴金额 - 补贴插队金额
-        subsidyQueue  = MathUtils.subtract(shouldSubsidyAmount, subsidyCutIn);
+        subsidyQueue = MathUtils.subtract(shouldSubsidyAmount, subsidyCutIn);
 
-        // 消费者最高补贴
-        BigDecimal amountSubsidy = MathUtils.setScale(order.getPayAmount().doubleValue()* currentMode.getAmountSubsidyRatio().doubleValue()/100);
+        // 当前消费者最高补贴
+        BigDecimal amountSubsidy = MathUtils.setScale(order.getPayAmount().doubleValue() * currentMode.getAmountSubsidyRatio().doubleValue() / 100);
         // 排队第一名默认补贴金额
+        BigDecimal firstSubsidy = subsidyQueue;
 
-        // 当前有效排队人数
-        Long validQueueCount = this.validQueueCountAndLock(order.getBusinessId());
+        // 创建自己的排队已完成
+        createSelfQueueHandle(order, amountSubsidy, validQueueCount);
+        if (!currentMode.getSharedMode()) {
 
-        // 排队第一名补贴金额
-        BigDecimal firstSubsidy = subsidyQueue;
-        if(!currentMode.getSharedMode())
-        {
-            //非均摊模式
-        }
-        else
-        {
+            //排队实际补贴(非均摊模式)
+            BigDecimal queueReturnAmount = queueActualSubsidyHandle(order.getBusinessId(), firstSubsidy);
+            // 如果实际补贴有盈余,商家的实际补贴金额 = 商家实际补贴金额 - 盈余
+            if (queueReturnAmount.compareTo(BigDecimal.ZERO) > 0) {
+                shouldSubsidyAmount = MathUtils.subtract(shouldSubsidyAmount, queueReturnAmount);
+            }
+        } else {
             //均摊模式
-            //排队第一名补贴金额
+            //排队第一名实际补贴金额
             firstSubsidy = MathUtils.setScale(subsidyQueue.doubleValue() * currentMode.getFirstSubsidyRatio().doubleValue() / 100);
+            //排队实际补贴
+            BigDecimal queueReturnAmount = queueActualSubsidyHandle(order.getBusinessId(), firstSubsidy);
+            if (queueReturnAmount.compareTo(BigDecimal.ZERO) > 0) {
+                shouldSubsidyAmount = MathUtils.subtract(shouldSubsidyAmount, queueReturnAmount);
+            }
+
             //排队均摊补贴金额
-            BigDecimal  sharedSubsidy = MathUtils.subtract(subsidyQueue, firstSubsidy);
+            BigDecimal sharedSubsidy = MathUtils.subtract(subsidyQueue, firstSubsidy);
+            BigDecimal sharedSubsidyReturnAmount = sharedSubsidyHandle(order.getBusinessId(), sharedSubsidy);
+            if (sharedSubsidyReturnAmount.compareTo(BigDecimal.ZERO) > 0) {
+                shouldSubsidyAmount = MathUtils.subtract(shouldSubsidyAmount, sharedSubsidyReturnAmount);
+            }
+        }
 
+        if (ObjectUtil.isNotNull(firstSubsidyCutIn) && subsidyCutIn.compareTo(BigDecimal.ZERO) > 0) {
+            BigDecimal returnAmount = subsidyCutInHandle(firstSubsidyCutIn, subsidyCutIn);
+            if (returnAmount.compareTo(BigDecimal.ZERO) > 0) {
+                shouldSubsidyAmount = MathUtils.subtract(shouldSubsidyAmount, returnAmount);
+            }
         }
 
-        if(ObjectUtil.isNotNull(firstSubsidyCutIn) && subsidyCutIn.compareTo(BigDecimal.ZERO)>0)
-        {
+        // 有了商家的实际补贴金额,就可以计算商家当前这个订单的实际所得
+        // 实际所得 = 订单金额- 商家实际补贴金额(让利)- 平台服务费(5%)
+
+
+
+    }
+
+    private BigDecimal subsidyCutInHandle(SubsidyCutIn firstSubsidyCutIn, BigDecimal subsidyCutIn) {
+        return BigDecimal.ZERO;
+    }
+
+    /**
+     * 均摊补贴金额
+     *
+     * @param businessId    商家id
+     * @param sharedSubsidy 排队均摊补贴金额
+     * @return 结余
+     */
+    private BigDecimal sharedSubsidyHandle(Long businessId, BigDecimal sharedSubsidy) {
+        return BigDecimal.ZERO;
+    }
+
+    /**
+     * 创建自己的排队
+     *
+     * @param order
+     * @param amountSubsidy   当前消费者最高补贴
+     * @param validQueueCount 当前有效排队人数
+     */
+    private void createSelfQueueHandle(OnlineOrder order, BigDecimal amountSubsidy, Long validQueueCount) {
+        if (amountSubsidy.compareTo(BigDecimal.ZERO) > 0) {
+            SubsidyQueueBo subsidyQueueBo = new SubsidyQueueBo();
+            subsidyQueueBo.setUserId(order.getUserId());
+            subsidyQueueBo.setUserMobile(order.getUserMobile());
+            subsidyQueueBo.setUserName(order.getUserName());
+            subsidyQueueBo.setOrderId(order.getOrderId());
+            subsidyQueueBo.setOrderNo(order.getOrderNo());
+            subsidyQueueBo.setCurrentBusinessId(order.getBusinessId());
+            subsidyQueueBo.setCurrentBusinessName(order.getBusinessName());
+            subsidyQueueBo.setOriginalBusinessId(order.getBusinessId());
+            subsidyQueueBo.setOriginalBusinessName(order.getBusinessName());
+            subsidyQueueBo.setPayAmount(order.getOrderAmount());
+            subsidyQueueBo.setShouldSubsidyAmount(amountSubsidy);
+            subsidyQueueBo.setActualSubsidyAmount(BigDecimal.ZERO);
+            subsidyQueueBo.setSubsidyPoints(order.getSendPoint());
+            subsidyQueueBo.setSubsidyStatus(SubsidyStatus.WAITING);
+            subsidyQueueBo.setCutIn(false);
+            subsidyQueueBo.setCancelled(false);
+            subsidyQueueBo.setExchanged(false);
+            subsidyQueueBo.setExchangePoints(BigDecimal.ONE);
+            subsidyQueueBo.setActualPointsAfterCancel(BigDecimal.ZERO);
+            subsidyQueueBo.setConsumeTime(order.getPayTime());
+            subsidyQueueBo.setCancelType(SubsidyCancelType.NO);
+            subsidyQueueBo.setQueueOrder(validQueueCount.intValue() + 1);
+            this.insertByBo(subsidyQueueBo);
+        }
+    }
+
+    /**
+     * 排队实际补贴(非均摊模式)
+     *
+     * @param businessId   商家id
+     * @param firstSubsidy 排队第一名实际补贴金额
+     * @return 结余
+     */
+    private BigDecimal queueActualSubsidyHandle(Long businessId, BigDecimal firstSubsidy) {
+        while (true) {
+            if (firstSubsidy.compareTo(BigDecimal.ZERO) <= 0) {
+                return BigDecimal.ZERO;
+            }
+            SubsidyQueue firstQueue = this.validFirstQueue(businessId);
+            if (ObjectUtil.isNull(firstQueue)) {
+                return firstSubsidy;
+            }
+            //应补贴金额
+            BigDecimal shouldSubsidyAmount = firstQueue.getShouldSubsidyAmount();
+            //已补贴金额
+            BigDecimal actualSubsidyAmount = firstQueue.getActualSubsidyAmount();
+            //当前排队用户的剩余补贴金额
+            BigDecimal currentQueueSubsidyAmount = MathUtils.subtract(shouldSubsidyAmount, actualSubsidyAmount);
+            BigDecimal actualAddSubsidyAmount = BigDecimal.ZERO;
+            if (firstSubsidy.compareTo(currentQueueSubsidyAmount) >= 0) {
+                //如果超出了应补贴金额=====================//
+                //计算给下一个排队用户的补贴金额
+                firstSubsidy = MathUtils.subtract(firstSubsidy, currentQueueSubsidyAmount);
+                firstQueue.setActualSubsidyAmount(shouldSubsidyAmount);
+                firstQueue.setSubsidyStatus(SubsidyStatus.COMPLETE);
+                firstQueue.setQueueOrder(0);
+                firstQueue.setCompleteTime(new Date());
+                this.baseMapper.updateById(firstQueue);
+                actualAddSubsidyAmount = currentQueueSubsidyAmount;
+
+                validQueueOrderRearrange(businessId,firstQueue.getQueueId());
+
+            } else {
+                //如果小于应补贴金额=====================//
+                actualAddSubsidyAmount = firstSubsidy;
+                firstSubsidy = BigDecimal.ZERO;
+                firstQueue.setActualSubsidyAmount(MathUtils.add(actualSubsidyAmount, firstSubsidy));
+                this.baseMapper.updateById(firstQueue);
+            }
+
+            //用户余额增加
+            userService.changeUserBalance(UserChangeBalanceBo.builder()
+                .userId(firstQueue.getUserId())
+                .entryValue(actualAddSubsidyAmount)
+                .isAdd(true)
+                .sourceType(BalanceSourceType.SUBSIDY)
+                .sourceId(firstQueue.getOrderId())
+                .sourceCode(firstQueue.getOrderNo())
+                .remark("消费排队补贴")
+                .build());
 
         }
     }
 
+    /**
+     * 排队顺序重新排序
+     *
+     * @param businessId    商家id
+     * @param excludeQueueId 排队id
+     */
+    private void validQueueOrderRearrange(Long businessId, Long excludeQueueId) {
+        SubsidyQueue branchQueue = new SubsidyQueue();
+        branchQueue.setQueueOrder(branchQueue.getQueueOrder() - 1);
+
+        this.baseMapper.update(branchQueue, new LambdaUpdateWrapper<SubsidyQueue>()
+            .eq(SubsidyQueue::getCurrentBusinessId, businessId)
+            .eq(SubsidyQueue::getSubsidyStatus, SubsidyStatus.WAITING)
+            .ne(SubsidyQueue::getQueueId, excludeQueueId)
+            .orderByAsc(SubsidyQueue::getQueueOrder)
+            .set(SubsidyQueue::getQueueOrder, branchQueue.getQueueOrder())
+        );
+    }
+
+    /**
+     * 获取当前商家的第一个有效的排队数据
+     *
+     * @param businessId 商家id
+     * @return 排队
+     */
+    private SubsidyQueue validFirstQueue(Long businessId) {
+        return this.baseMapper.selectOne(new LambdaQueryWrapper<SubsidyQueue>()
+            .eq(SubsidyQueue::getCurrentBusinessId, businessId)
+            .eq(SubsidyQueue::getSubsidyStatus, SubsidyStatus.WAITING)
+            .eq(SubsidyQueue::getCutIn, false)
+            .orderByAsc(SubsidyQueue::getQueueOrder)
+            .last("limit 1")
+        );
+    }
 
 
 }

+ 1 - 0
ruoyi-line/src/main/resources/mapper/subsidy/SubsidyQueueMapper.xml

@@ -42,4 +42,5 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         and  subsidy_status = 0
         for update
     </select>
+
 </mapper>

+ 2 - 0
ruoyi-user/src/main/java/com/ruoyi/user/enums/BalanceSourceType.java

@@ -15,6 +15,8 @@ public enum BalanceSourceType implements IIntegerEnum {
     RECHARGE(1, "充值"),
     SALE_ROLLBACK(2, "订单退款余额回退"),
     CONSUME(3, "订单消费"),
+    //消费排队补贴
+    SUBSIDY(4, "消费排队补贴"),
     ;
 
     @EnumValue