From 7bf5945cdd7560922828f225c882d82f95405648 Mon Sep 17 00:00:00 2001
From: KKSU <15274802129@163.com>
Date: Fri, 03 Jan 2025 10:27:31 +0800
Subject: [PATCH] feat(mall): 添加会员购买功能并优化节点助力逻辑

---
 src/main/java/cc/mrbird/febs/mall/controller/ApiRunVipController.java       |   12 ++-
 src/main/java/cc/mrbird/febs/mall/service/AsyncService.java                 |    2 
 src/main/java/cc/mrbird/febs/mall/service/impl/RunVipServiceImpl.java       |   60 ++++++++++++++++++++
 src/main/java/cc/mrbird/febs/common/enumerates/RunVipMoneyFlowTypeEnum.java |    7 ++
 src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java |   18 +++--
 src/main/java/cc/mrbird/febs/mall/service/impl/AsyncServiceImpl.java        |   18 ++---
 src/main/java/cc/mrbird/febs/mall/dto/ApiBalanceBuyDto.java                 |   24 ++++++++
 src/main/java/cc/mrbird/febs/mall/service/IRunVipService.java               |    7 +-
 src/main/java/cc/mrbird/febs/mall/vo/ApiRunVipVo.java                       |    5 +
 9 files changed, 125 insertions(+), 28 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/common/enumerates/RunVipMoneyFlowTypeEnum.java b/src/main/java/cc/mrbird/febs/common/enumerates/RunVipMoneyFlowTypeEnum.java
index 920344b..5c776f5 100644
--- a/src/main/java/cc/mrbird/febs/common/enumerates/RunVipMoneyFlowTypeEnum.java
+++ b/src/main/java/cc/mrbird/febs/common/enumerates/RunVipMoneyFlowTypeEnum.java
@@ -8,6 +8,11 @@
     /**
      * 碳币兑换USDT
      */
+    COMMISSION_PAY(16,"购买会员,APP支付{}","购买会员,APP支付"),
+
+    /**
+     * 碳币兑换USDT
+     */
     BALANCE_OUT_COMMISSION_IN(15,"{}碳币兑换{}USDT","获得USDT"),
 
     /**
@@ -33,7 +38,7 @@
     /**
      * 节点助力
      */
-    NODE_BALANCE(10,"节点助力碳币{}","节点助力碳币"),
+    NODE_COMMISSION(10,"节点助力{}","节点助力"),
 
     /**
      * 获得碳积分
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/ApiRunVipController.java b/src/main/java/cc/mrbird/febs/mall/controller/ApiRunVipController.java
index 0b0591a..d62ce1d 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/ApiRunVipController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/ApiRunVipController.java
@@ -2,10 +2,7 @@
 
 import cc.mrbird.febs.common.annotation.SubmitRepeat;
 import cc.mrbird.febs.common.entity.FebsResponse;
-import cc.mrbird.febs.mall.dto.ApiChargeListDto;
-import cc.mrbird.febs.mall.dto.ApiGetRunDateDto;
-import cc.mrbird.febs.mall.dto.ApiGoChargeDto;
-import cc.mrbird.febs.mall.dto.ApiGoChargeInfoDto;
+import cc.mrbird.febs.mall.dto.*;
 import cc.mrbird.febs.mall.service.IRunVipService;
 import cc.mrbird.febs.mall.vo.*;
 import io.swagger.annotations.Api;
@@ -75,6 +72,13 @@
         return new FebsResponse().success().data(iRunVipService.getChargeList(apiChargeListDto));
     }
 
+    @ApiOperation(value = "【购买VIP】APP支付", notes = "【购买VIP】APP支付")
+    @PostMapping(value = "/goCharge")
+    @SubmitRepeat
+    public FebsResponse balanceBuy(@RequestBody @Valid ApiBalanceBuyDto apiBalanceBuyDto) {
+        return iRunVipService.balanceBuy(apiBalanceBuyDto);
+    }
+
     @ApiOperation(value = "【购买VIP】立即购买", notes = "【购买VIP】立即购买")
     @ApiResponses({
             @ApiResponse(code = 200, message = "success", response = ApiGoChargeVo.class)
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/ApiBalanceBuyDto.java b/src/main/java/cc/mrbird/febs/mall/dto/ApiBalanceBuyDto.java
new file mode 100644
index 0000000..82e9187
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/ApiBalanceBuyDto.java
@@ -0,0 +1,24 @@
+package cc.mrbird.febs.mall.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel(value = "ApiBalanceBuyDto", description = "参数接收类")
+public class ApiBalanceBuyDto {
+
+    @NotNull(message = "请选择会员")
+    @ApiModelProperty(value = "会员ID", example = "123456")
+    private Long runVipId;
+
+    @NotNull(message = "请输入资金密码")
+    @ApiModelProperty(value = "资金密码", example = "123456")
+    private String tradeWord;
+
+    @NotNull(message = "请选择数量")
+    @ApiModelProperty(value = "数量", example = "123456")
+    private Integer vipCnt;
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/service/AsyncService.java b/src/main/java/cc/mrbird/febs/mall/service/AsyncService.java
index f913a72..a8e517b 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/AsyncService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/AsyncService.java
@@ -13,5 +13,5 @@
     void releaseScore(BigDecimal amount,Long memberId);
 
     @Async(FebsConstant.ASYNC_POOL)
-    void releaseNodeCoin(BigDecimal amount, BigDecimal percent, BigDecimal balanceToCoin, Long memberId);
+    void releaseNodeCoin(BigDecimal amount, BigDecimal percent, Long memberId);
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/IRunVipService.java b/src/main/java/cc/mrbird/febs/mall/service/IRunVipService.java
index a642de2..28ef69a 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IRunVipService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IRunVipService.java
@@ -1,10 +1,7 @@
 package cc.mrbird.febs.mall.service;
 
 import cc.mrbird.febs.common.entity.FebsResponse;
-import cc.mrbird.febs.mall.dto.ApiChargeListDto;
-import cc.mrbird.febs.mall.dto.ApiGetRunDateDto;
-import cc.mrbird.febs.mall.dto.ApiGoChargeDto;
-import cc.mrbird.febs.mall.dto.ApiGoChargeInfoDto;
+import cc.mrbird.febs.mall.dto.*;
 import cc.mrbird.febs.mall.entity.RunVip;
 import cc.mrbird.febs.mall.vo.*;
 import com.baomidou.mybatisplus.extension.service.IService;
@@ -16,6 +13,8 @@
 
     FebsResponse goCharge(ApiGoChargeDto apiGoChargeDto);
 
+    FebsResponse balanceBuy(ApiBalanceBuyDto apiBalanceBuyDto);
+
     FebsResponse goChargeInfo(ApiGoChargeInfoDto apiGoChargeInfoDto);
 
     List<ApiChargeVo> getChargeList(ApiChargeListDto apiChargeListDto);
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/AsyncServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/AsyncServiceImpl.java
index c3585fd..9063f79 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/AsyncServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/AsyncServiceImpl.java
@@ -43,26 +43,22 @@
     }
 
     @Override
-    public void releaseNodeCoin(BigDecimal amount, BigDecimal percent, BigDecimal balanceToCoin, Long memberId) {
+    public void releaseNodeCoin(BigDecimal amount, BigDecimal percent, Long memberId) {
         //实际节点助力的碳币
-        BigDecimal multiply = amount.multiply(percent);
+        BigDecimal multiply = amount.multiply(percent).setScale(2,RoundingMode.DOWN);
         if(BigDecimal.ZERO.compareTo(multiply) >=0){
             return;
         }
-        BigDecimal divide = multiply.divide(balanceToCoin, 2, RoundingMode.DOWN);
-        if(BigDecimal.ZERO.compareTo(divide) >=0){
-            return;
-        }
-        walletService.addBalance(divide,memberId);
+        walletService.addCommission(multiply,memberId);
         String orderNo = MallUtils.getOrderNum("JD");
         mallMoneyFlowService.runVipMoneyFlowAdd(
                 memberId,
                 memberId,
                 orderNo,
-                FlowTypeEnum.BALANCE.getValue(),
-                RunVipMoneyFlowTypeEnum.NODE_BALANCE.getValue(),
-                divide,
-                StrUtil.format(RunVipMoneyFlowTypeEnum.NODE_BALANCE.getDescription(),divide),
+                FlowTypeEnum.COMMISSION.getValue(),
+                RunVipMoneyFlowTypeEnum.NODE_COMMISSION.getValue(),
+                multiply,
+                StrUtil.format(RunVipMoneyFlowTypeEnum.NODE_COMMISSION.getDescription(),multiply),
                 YesOrNoEnum.YES.getValue()
         );
 
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java
index d6a9301..0324149 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java
@@ -857,24 +857,28 @@
         }
         //获取节点设置
         List<RunNodeSet> runNodeSets = runNodeSetMapper.selectList(null);
-        BigDecimal balanceToCoin = new BigDecimal(
-                dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
-                        RunVipDataDictionaryEnum.RUN_VIP_BALANCE_TO_COIN.getType(),
-                        RunVipDataDictionaryEnum.RUN_VIP_BALANCE_TO_COIN.getCode()).getValue()
-        ).setScale(2, BigDecimal.ROUND_DOWN);
+
+        //获取节点设置runNodeSets中orderNumber最小的节点
+        RunNodeSet minRunNodeSet = runNodeSets.stream().min(Comparator.comparingInt(RunNodeSet::getOrderNumber)).orElse(null);
+        if(null == minRunNodeSet){
+            return;
+        }
 
         DateTime endTime = DateUtil.date();
         for (MallMember item : mallMembers) {
             //获取总业绩
             BigDecimal achieve = getDirectAchieve(item.getInviteId(),item.getDirectorTime(),endTime);
-            if(BigDecimal.ZERO.compareTo(achieve) >= 0){
+            //判断总业绩是否小于最小业绩
+            if(minRunNodeSet.getMinAchieve().compareTo(achieve) > 0){
+                item.setDirector(YesOrNoEnum.NO.getValue());
+                mallMemberMapper.updateById(item);
                 continue;
             }
             BigDecimal nodePercent = getNodePercent(runNodeSets, achieve);
             if(BigDecimal.ZERO.compareTo(nodePercent) >= 0){
                 continue;
             }
-            asyncService.releaseNodeCoin(achieve,nodePercent,balanceToCoin,item.getId());
+            asyncService.releaseNodeCoin(achieve,nodePercent,item.getId());
             item.setDirectorTime(endTime);
             mallMemberMapper.updateById(item);
         }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/RunVipServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/RunVipServiceImpl.java
index 37fad9e..635c78d 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/RunVipServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/RunVipServiceImpl.java
@@ -12,6 +12,8 @@
 import cc.mrbird.febs.mall.dto.*;
 import cc.mrbird.febs.mall.entity.*;
 import cc.mrbird.febs.mall.mapper.*;
+import cc.mrbird.febs.mall.service.IApiMallMemberWalletService;
+import cc.mrbird.febs.mall.service.IMallMoneyFlowService;
 import cc.mrbird.febs.mall.service.IRunVipService;
 import cc.mrbird.febs.mall.vo.*;
 import cc.mrbird.febs.rabbit.producter.AgentProducer;
@@ -48,6 +50,8 @@
     private final MallMoneyFlowMapper mallMoneyFlowMapper;
     private final MallMemberWalletMapper mallMemberWalletMapper;
     private final MallMemberMapper mallMemberMapper;
+    private final IApiMallMemberWalletService walletService;
+    private final IMallMoneyFlowService mallMoneyFlowService;
     @Override
     public List<ApiRunVipVo> vipInfo() {
         Long memberId = LoginUserUtil.getLoginUser().getId();
@@ -152,6 +156,62 @@
     }
 
     @Override
+    public FebsResponse balanceBuy(ApiBalanceBuyDto apiBalanceBuyDto) {
+        Long memberId = LoginUserUtil.getLoginUser().getId();
+        MallMember mallMember = mallMemberMapper.selectById(memberId);
+        if (StrUtil.isBlank(mallMember.getTradePassword())) {
+            throw new FebsException("未设置资金密码");
+        }
+
+        if (!mallMember.getTradePassword().equals(SecureUtil.md5(apiBalanceBuyDto.getTradeWord()))) {
+            throw new FebsException("资金密码错误");
+        }
+        Long runVipId = apiBalanceBuyDto.getRunVipId();
+        RunVip runVip = this.baseMapper.selectById(runVipId);
+        if(runVip.getState() != YesOrNoEnum.YES.getValue()){
+            throw new FebsException("会员套餐已下架");
+        }
+        //价格
+        BigDecimal presentAmount = runVip.getPresentPrice().setScale(2,BigDecimal.ROUND_DOWN);
+        MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId);
+        if(mallMemberWallet.getCommission().compareTo(BigDecimal.ZERO) <= 0){
+            throw new FebsException("余额不足");
+        }
+        if(mallMemberWallet.getCommission().compareTo(presentAmount) < 0){
+            throw new FebsException("余额不足");
+        }
+
+        String orderNo = MallUtils.getOrderNum();
+        walletService.reduceCommission(presentAmount,memberId);
+        mallMoneyFlowService.runVipMoneyFlowAdd(
+                memberId,
+                memberId,
+                orderNo,
+                FlowTypeEnum.COMMISSION.getValue(),
+                RunVipMoneyFlowTypeEnum.COMMISSION_PAY.getValue(),
+                presentAmount,
+                StrUtil.format(RunVipMoneyFlowTypeEnum.COMMISSION_PAY.getDescription(),presentAmount),
+                YesOrNoEnum.YES.getValue()
+        );
+
+        MallCharge mallCharge = new MallCharge();
+        mallCharge.setMemberId(memberId);
+        mallCharge.setOrderNo(orderNo);
+        mallCharge.setState(YesOrNoEnum.YES.getValue());
+        mallCharge.setType(StrUtil.format(RunVipMoneyFlowTypeEnum.COMMISSION_PAY.getDescription(),presentAmount));
+        mallCharge.setAddress(mallMember.getPhone());
+        mallCharge.setAmount(presentAmount);
+        mallCharge.setVipCode(runVip.getVipCode());
+        mallCharge.setVipName(runVip.getVipName());
+        mallCharge.setVipCnt(apiBalanceBuyDto.getVipCnt());
+        mallChargeMapper.insert(mallCharge);
+
+        agentProducer.sendBuyVipSuccessMsg(mallCharge.getId());
+
+        return new FebsResponse().success().message("操作成功");
+    }
+
+    @Override
     public FebsResponse goChargeInfo(ApiGoChargeInfoDto apiGoChargeInfoDto) {
         Long memberId = LoginUserUtil.getLoginUser().getId();
         String orderNo = apiGoChargeInfoDto.getOrderNo();
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/ApiRunVipVo.java b/src/main/java/cc/mrbird/febs/mall/vo/ApiRunVipVo.java
index cea7b1d..645a1b1 100644
--- a/src/main/java/cc/mrbird/febs/mall/vo/ApiRunVipVo.java
+++ b/src/main/java/cc/mrbird/febs/mall/vo/ApiRunVipVo.java
@@ -34,10 +34,15 @@
     private Integer commissionState;//是否允许USDT提现 1是0否
     @ApiModelProperty(value = "是否允许内转 1-是0-否")
     private Integer insideState;//是否允许内转 1-是0-否
+
+    @ApiModelProperty(value = "是否允许权益升级 1-是0-否")
+    private Integer growState;//是否允许权益升级 1-是0-否
+
     @ApiModelProperty(value = "每日碳积分增长倍数")
     private BigDecimal growthValue;//每日碳积分增长倍数
     @ApiModelProperty(value = "每日获取碳积分最大值")
     private Integer growthCnt;//每日获取碳积分最大值
+
     @ApiModelProperty(value = "购买会员返利金额比例(实际支付金额 * rebatePercent = 返利金额)")
     private BigDecimal rebatePercent;//购买会员返利金额比例(实际支付金额 * rebatePercent = 返利金额)
 }

--
Gitblit v1.9.1