From e9391705ed64a34caf08c9f217b498dac3dc59b5 Mon Sep 17 00:00:00 2001
From: KKSU <15274802129@163.com>
Date: Tue, 31 Dec 2024 14:30:24 +0800
Subject: [PATCH] refactor(mall): 优化会员利润计算服务

---
 src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java |  202 ++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 147 insertions(+), 55 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java
index 9603404..60c1d1d 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java
@@ -80,6 +80,7 @@
     private final MallGoodsCouponMapper mallGoodsCouponMapper;
     private final MallMemberCouponMapper mallMemberCouponMapper;
     private final MallGoodsMapper mallGoodsMapper;
+    private final MallChargeMapper mallChargeMapper;
 
     private final MallVipConfigMapper mallVipConfigMapper;
     private final RunVipMapper runVipMapper;
@@ -130,19 +131,31 @@
         //对于邀请码的验证和上级联系人的验证
         Integer count = this.baseMapper.selectCount(null);
         if (count != null && count != 0) {
-            if(!StrUtil.isEmpty(registerDto.getInviteId())){
-                String inviteId = registerDto.getInviteId();
-                MallMember inviteMember = this.baseMapper.selectInfoByInviteId(inviteId);
-                if (inviteMember == null) {
-                    throw new FebsException("邀请码不存在");
-                }
-                mallMember.setReferrerId(registerDto.getInviteId());
+            if(StrUtil.isEmpty(registerDto.getInviteId())){
+                throw new FebsException("请输入邀请码");
             }
+            String inviteId = registerDto.getInviteId();
+            MallMember inviteMember = this.baseMapper.selectInfoByInviteId(inviteId);
+            if (inviteMember == null) {
+                throw new FebsException("邀请码不存在");
+            }
+            mallMember.setReferrerId(registerDto.getInviteId());
+//            if(!StrUtil.isEmpty(registerDto.getInviteId())){
+//                String inviteId = registerDto.getInviteId();
+//                MallMember inviteMember = this.baseMapper.selectInfoByInviteId(inviteId);
+//                if (inviteMember == null) {
+//                    throw new FebsException("邀请码不存在");
+//                }
+//                mallMember.setReferrerId(registerDto.getInviteId());
+//            }
         }
         mallMember.setName(account);
-        mallMember.setAccountStatus(MallMember.ACCOUNT_STATUS_ENABLE);
+        mallMember.setAvatar("https://res.runstep.cc/rslogo.png");
+        mallMember.setAccountStatus(YesOrNoEnum.YES.getValue());
         mallMember.setAccountType(MallMember.ACCOUNT_TYPE_NORMAL);
         mallMember.setSex("男");
+        mallMember.setDirector(YesOrNoEnum.NO.getValue());
+        mallMember.setDirectorTime(DateUtil.date());
         mallMember.setBindPhone(account);
 
         this.baseMapper.insert(mallMember);
@@ -200,8 +213,8 @@
             throw new FebsException("用户不存在或账号密码错误");
         }
 
-        if (MallMember.ACCOUNT_STATUS_DISABLED.equals(mallMember.getAccountStatus())) {
-            throw new FebsException("该账号存在异常, 暂限制登录");
+        if (YesOrNoEnum.NO.getValue() == mallMember.getAccountStatus()) {
+            throw new FebsException("账号限制登录");
         }
 
         String redisKey = AppContants.APP_LOGIN_PREFIX + mallMember.getId();
@@ -276,40 +289,72 @@
         RunVip runVip = runVipMapper.selectOne(new LambdaQueryWrapper<RunVip>().eq(RunVip::getVipCode, mallMemberVo.getLevel()));
         mallMemberVo.setLevelName(runVip.getVipName());
         mallMemberVo.setLevelPng(runVip.getVipPng());
+        mallMemberVo.setChangeState(runVip.getChangeState());
+        mallMemberVo.setWithdrawState(runVip.getWithdrawState());
+        mallMemberVo.setInsideState(runVip.getInsideState());
+
 
         MallMemberWallet wallet = mallMemberWalletMapper.selectWalletByMemberId(mallMemberVo.getId());
         mallMemberVo.setBalance(wallet.getBalance());
         mallMemberVo.setScore(wallet.getScore());
-
-        mallMemberVo.setMinScore(
-                new BigDecimal(
-                        dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
-                            RunVipDataDictionaryEnum.RUN_VIP_SCORE_MIN.getType(),
-                            RunVipDataDictionaryEnum.RUN_VIP_SCORE_MIN.getCode()).getValue()
-                ).setScale(0,BigDecimal.ROUND_DOWN)
-        );
-        mallMemberVo.setScoreBalance(
-                new BigDecimal(
-                        dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
-                                RunVipDataDictionaryEnum.RUN_VIP_SCORE_TO_BALANCE.getType(),
-                                RunVipDataDictionaryEnum.RUN_VIP_SCORE_TO_BALANCE.getCode()).getValue()
-                ).setScale(2, BigDecimal.ROUND_DOWN)
-        );
-        mallMemberVo.setBalanceCoin(
-                new BigDecimal(
-                        dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
-                                RunVipDataDictionaryEnum.RUN_VIP_BALANCE_TO_COIN.getType(),
-                                RunVipDataDictionaryEnum.RUN_VIP_BALANCE_TO_COIN.getCode()).getValue()
-                ).setScale(2, BigDecimal.ROUND_DOWN)
-        );
-        mallMemberVo.setBalanceCoinPercent(
-                new BigDecimal(
-                        dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
-                                RunVipDataDictionaryEnum.RUN_VIP_BALANCE_TO_COIN_PERCENT.getType(),
-                                RunVipDataDictionaryEnum.RUN_VIP_BALANCE_TO_COIN_PERCENT.getCode()).getValue()
-                ).setScale(4, BigDecimal.ROUND_DOWN)
-        );
         return new FebsResponse().success().data(mallMemberVo);
+    }
+
+    private BigDecimal getDirectAchieve(String inviteId,Date startTime,Date endTime) {
+
+        try {
+            // 获取直推成员和团队成员的ID集合
+            Set<Long> memberIds = getTeamMemberIds(inviteId);
+
+            if (CollUtil.isEmpty(memberIds)) {
+                return BigDecimal.ZERO;
+            }
+
+            // 获取团队业绩(不包含本人业绩)
+            List<MallCharge> mallCharges = mallChargeMapper.selectList(
+                    new LambdaQueryWrapper<MallCharge>()
+                            .in(MallCharge::getMemberId, memberIds)
+                            .eq(MallCharge::getState, YesOrNoEnum.YES.getValue())
+                            .ge(MallCharge::getCreatedTime, startTime)
+                            .lt(MallCharge::getCreatedTime, endTime)
+            );
+
+            if (CollUtil.isEmpty(mallCharges)) {
+                return BigDecimal.ZERO;
+            }
+
+            return mallCharges.stream()
+                    .map(MallCharge::getAmount)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+        } catch (Exception e) {
+            // 异常处理
+            log.error("Error occurred while calculating direct achieve for member: {}", inviteId, e);
+            return BigDecimal.ZERO;
+        }
+    }
+    private Set<Long> getTeamMemberIds(String inviteId) {
+        Set<Long> memberIds = new HashSet<>();
+        // 获取直推成员
+        List<MallMember> directMembers = this.baseMapper.selectList(
+                new LambdaQueryWrapper<MallMember>()
+                        .eq(MallMember::getReferrerId, inviteId)
+        );
+        if(CollUtil.isEmpty(directMembers)){
+            return memberIds;
+        }
+        memberIds.addAll(directMembers.stream().map(MallMember::getId).collect(Collectors.toSet()));
+
+        // 获取团队成员
+        List<MallMember> teamMembers = this.baseMapper.selectList(
+                new LambdaQueryWrapper<MallMember>()
+                        .in(MallMember::getReferrerId, directMembers.stream().map(MallMember::getInviteId).collect(Collectors.toSet()))
+        );
+        if(CollUtil.isEmpty(teamMembers)){
+            return memberIds;
+        }
+        memberIds.addAll(teamMembers.stream().map(MallMember::getId).collect(Collectors.toSet()));
+
+        return memberIds;
     }
 
     @Override
@@ -361,7 +406,7 @@
             mallMember.setAvatar(modifyMemberInfoDto.getPhoto());
         }
 
-        this.baseMapper.updateById(mallMember);
+        this.baseMapper.updateNameAndAvatar(member.getId(),modifyMemberInfoDto.getName(),modifyMemberInfoDto.getPhoto());
         return new FebsResponse().success().message("修改成功");
     }
 
@@ -378,6 +423,17 @@
          * 直属三级
          */
         MyTeamVo myTeamVo = new MyTeamVo();
+        //节点和团队业绩
+        myTeamVo.setDirector(mallMember.getDirector());
+        if(mallMember.getDirector() == YesOrNoEnum.YES.getValue() && mallMember.getDirectorTime() != null){
+            myTeamVo.setDirectorTime(mallMember.getDirectorTime());
+            BigDecimal directAchieve = getDirectAchieve(mallMember.getInviteId(), mallMember.getDirectorTime(), DateUtil.date());
+            myTeamVo.setDirectorAchieve(directAchieve);
+        }else{
+            myTeamVo.setDirectorTime(mallMember.getCreatedTime());
+            BigDecimal directAchieve = getDirectAchieve(mallMember.getInviteId(), mallMember.getCreatedTime(), DateUtil.date());
+            myTeamVo.setDirectorAchieve(directAchieve);
+        }
         //获取个人的碳币
         MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId);
         myTeamVo.setMyBalance(mallMemberWallet.getBalance());
@@ -409,9 +465,10 @@
             }else{
                 item.setMyTeamCnt(mallMemberRefs.size());
                 //获取mallMembers的所有id
-                myTeamVo.setMyTeamBalance(getTeamBalance(mallMemberRefs));
+                item.setMyTeamBalance(getTeamBalance(mallMemberRefs));
             }
         });
+        myTeamVo.setTeam(teamListVos);
 
 
         return new FebsResponse().success().data(myTeamVo);
@@ -511,7 +568,7 @@
          * 用户的等级level是否允许兑换碳币
          */
         RunVip runVip = runVipMapper.selectOne(new LambdaQueryWrapper<RunVip>().eq(RunVip::getVipCode, loginMember.getLevel()));
-        if(ObjectUtil.isEmpty(runVip) || runVip.getChangeState() != YesOrNoEnum.YES.getValue()){
+        if(ObjectUtil.isEmpty(runVip) || runVip.getInsideState() != YesOrNoEnum.YES.getValue()){
             throw new FebsException("请先升级会员");
         }
 
@@ -554,6 +611,7 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void withdrawal(WithdrawalDto withdrawalDto) {
         Long memberId = LoginUserUtil.getLoginUser().getId();
         MallMember loginMember = this.baseMapper.selectById(memberId);
@@ -595,13 +653,21 @@
                 dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                         RunVipDataDictionaryEnum.RUN_VIP_BALANCE_TO_COIN_PERCENT.getType(),
                         RunVipDataDictionaryEnum.RUN_VIP_BALANCE_TO_COIN_PERCENT.getCode()).getValue()
-        ).setScale(4, BigDecimal.ROUND_DOWN);
+        ).setScale(2, BigDecimal.ROUND_DOWN);
+
+        BigDecimal withdrawalAmount = withdrawalDto.getAmount().multiply(balanceToCoin).setScale(2, BigDecimal.ROUND_DOWN);
+        BigDecimal fee = balanceToCoinPercent;
+//        BigDecimal fee = balanceToCoinPercent.multiply(withdrawalAmount).setScale(2, BigDecimal.ROUND_DOWN);
+        BigDecimal withdrawalAmountReal = withdrawalAmount.subtract(fee);
+        if(BigDecimal.ZERO.compareTo(withdrawalAmountReal) >= 0){
+            throw new FebsException(minCnt+"手续费不足");
+        }
+
         /**
          *  减少碳币,增加进行中提现记录
          */
-        BigDecimal withdrawalAmount = withdrawalDto.getAmount().multiply(balanceToCoin).setScale(2, BigDecimal.ROUND_DOWN);
-        BigDecimal fee = balanceToCoinPercent.multiply(withdrawalAmount).setScale(2, BigDecimal.ROUND_DOWN);
-        BigDecimal withdrawalAmountReal = withdrawalAmount.subtract(fee);
+        walletService.reduceBalance(withdrawalDto.getAmount(), loginMember.getId());
+
         String orderNo = MallUtils.getOrderNum("TX");
         MallMemberWithdraw withdraw = new MallMemberWithdraw();
         withdraw.setWithdrawNo(orderNo);
@@ -611,9 +677,9 @@
         withdraw.setAmountFee(fee);
         withdraw.setName(mallMemberPayment.getBank());
         withdraw.setType(mallMemberPayment.getBankNo());
+        withdraw.setWithdrawTimes(withdrawalDto.getAmount());
         mallMemberWithdrawMapper.insert(withdraw);
 
-        walletService.reduceBalance(withdrawalDto.getAmount(), loginMember.getId());
         this.runVipMoneyFlowAdd(
                 loginMember.getId(),
                 loginMember.getId(),
@@ -628,6 +694,7 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void commissionChange(CommissionChangeDto commissionChange) {
         Long memberId = LoginUserUtil.getLoginUser().getId();
         BigDecimal minScore = new BigDecimal(
@@ -652,6 +719,11 @@
         RunVip runVip = runVipMapper.selectOne(new LambdaQueryWrapper<RunVip>().eq(RunVip::getVipCode, loginMember.getLevel()));
         if(ObjectUtil.isEmpty(runVip) || runVip.getChangeState() != YesOrNoEnum.YES.getValue()){
             throw new FebsException("请先升级会员");
+        }
+
+        MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId);
+        if(minScore.compareTo(mallMemberWallet.getScore()) > 0){
+            throw new FebsException("碳积分不足");
         }
 
         BigDecimal scoreBalancePercent = new BigDecimal(
@@ -691,20 +763,24 @@
     @Override
     public void setPayment(ApiMallMemberPaymentDto apiMallMemberPaymentDto) {
 
-        List<MallMemberPayment> mallMemberPayments = mallMemberPaymentMapper.selectList(
-                new LambdaQueryWrapper<MallMemberPayment>().eq(MallMemberPayment::getBank, apiMallMemberPaymentDto.getBank()));
-        if(CollUtil.isNotEmpty(mallMemberPayments)){
-            throw new FebsException("地址已使用");
-        }
-
         MallMember member = LoginUserUtil.getLoginUser();
         if(null == apiMallMemberPaymentDto.getId()){//新增
+            List<MallMemberPayment> mallMemberPayments = mallMemberPaymentMapper.selectList(
+                    new LambdaQueryWrapper<MallMemberPayment>().eq(MallMemberPayment::getBank, apiMallMemberPaymentDto.getBank()));
+            if(CollUtil.isNotEmpty(mallMemberPayments)){
+                throw new FebsException("地址已使用");
+            }
             MallMemberPayment mallMemberPayment = new MallMemberPayment();
             mallMemberPayment.setMemberId(member.getId());
             mallMemberPayment.setBankNo(apiMallMemberPaymentDto.getBankNo());
             mallMemberPayment.setBank(apiMallMemberPaymentDto.getBank());
             mallMemberPaymentMapper.insert(mallMemberPayment);
         }else{
+            List<MallMemberPayment> mallMemberPayments = mallMemberPaymentMapper.selectList(
+                    new LambdaQueryWrapper<MallMemberPayment>().eq(MallMemberPayment::getBank, apiMallMemberPaymentDto.getBank()));
+            if(CollUtil.isNotEmpty(mallMemberPayments) && mallMemberPayments.size() > 1){
+                throw new FebsException("地址已使用");
+            }
             MallMemberPayment mallMemberPayment = mallMemberPaymentMapper.selectById(apiMallMemberPaymentDto.getId());
             mallMemberPayment.setMemberId(member.getId());
             mallMemberPayment.setBankNo(apiMallMemberPaymentDto.getBankNo());
@@ -1561,6 +1637,18 @@
         return new FebsResponse().success().data(data);
     }
 
+
+    public static String hidePhoneNumber(String phoneNumber) {
+        //判断字符串的长度小于4就直接返回
+        if (phoneNumber.length() < 4) {
+            return phoneNumber;
+        }
+        // 获取前3位和后4位
+        String prefix = phoneNumber.substring(0, 3);
+        // 生成隐藏的电话号码
+        return prefix + "****";
+    }
+
     @Override
     public List<ApiChartVo> dayRecord(ApiRecordDto apiRecordDto) {
         /**
@@ -1576,7 +1664,11 @@
             mallMoneyFlowLambdaQueryWrapper.ge(MallMoneyFlow :: getCreatedTime , dateTime);
         }
         mallMoneyFlowLambdaQueryWrapper.eq(MallMoneyFlow :: getFlowType, FlowTypeEnum.SCORE.getValue());
-        mallMoneyFlowLambdaQueryWrapper.eq(MallMoneyFlow :: getType, RunVipMoneyFlowTypeEnum.SCORE_OUT_BALANCE.getValue());
+        mallMoneyFlowLambdaQueryWrapper.in(
+                MallMoneyFlow :: getType,
+                RunVipMoneyFlowTypeEnum.GET_SCORE.getValue(),
+                RunVipMoneyFlowTypeEnum.SYS_SCORE.getValue()
+        );
         List<MallMoneyFlow> mallMoneyFlows = mallMoneyFlowMapper.selectList(mallMoneyFlowLambdaQueryWrapper);
 
         List<ApiChartVo> apiChartVos = new ArrayList<>();
@@ -1602,7 +1694,7 @@
         sortedList.forEach(entry -> {
             ApiChartVo apiChartVo = new ApiChartVo();
             MallMember mallMember = this.baseMapper.selectById(entry.getKey());
-            apiChartVo.setPhone(mallMember.getPhone());
+            apiChartVo.setName(hidePhoneNumber(mallMember.getName()));
             apiChartVo.setAvatar(mallMember.getAvatar());
             apiChartVo.setScore(entry.getValue());
             apiChartVos.add(apiChartVo);

--
Gitblit v1.9.1