From a320f1c89e73c6530f768cde114f6176d7e82190 Mon Sep 17 00:00:00 2001
From: KKSU <15274802129@163.com>
Date: Mon, 30 Dec 2024 11:02:11 +0800
Subject: [PATCH] feat(mall): 添加会员每日助力碳币功能
---
src/main/java/cc/mrbird/febs/common/enumerates/RunVipMoneyFlowTypeEnum.java | 7 ++
src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java | 137 +++++++++++++++++++++++++++++++++++++++++++++
src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java | 9 +++
src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java | 2
src/main/java/cc/mrbird/febs/mall/entity/RunVip.java | 2
5 files changed, 155 insertions(+), 2 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 6bf02bf..f835dd3 100644
--- a/src/main/java/cc/mrbird/febs/common/enumerates/RunVipMoneyFlowTypeEnum.java
+++ b/src/main/java/cc/mrbird/febs/common/enumerates/RunVipMoneyFlowTypeEnum.java
@@ -8,7 +8,12 @@
/**
* 节点助力
*/
- NODE_BALANCE(10,"节点助力碳币{}","节点助力"),
+ DIRECT_SCORE(11,"团队助力碳积分{}","团队助力碳积分"),
+
+ /**
+ * 节点助力
+ */
+ NODE_BALANCE(10,"节点助力碳币{}","节点助力碳币"),
/**
* 获得碳积分
diff --git a/src/main/java/cc/mrbird/febs/mall/entity/RunVip.java b/src/main/java/cc/mrbird/febs/mall/entity/RunVip.java
index 3885252..999892e 100644
--- a/src/main/java/cc/mrbird/febs/mall/entity/RunVip.java
+++ b/src/main/java/cc/mrbird/febs/mall/entity/RunVip.java
@@ -31,6 +31,6 @@
private Integer growthCnt;//每日获取碳积分最大值
- private BigDecimal rebatePercent;//购买会员返利金额比例(实际支付金额 * rebatePercent = 返利金额)
+ private BigDecimal rebatePercent;//返利上级的百分比
}
diff --git a/src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java b/src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java
index 339055a..2f9c5d6 100644
--- a/src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java
+++ b/src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java
@@ -44,6 +44,15 @@
}
/**
+ * 每天凌晨
+ * 释放每一个用户的助力碳币
+ */
+ @Scheduled(cron = "0 0 0 * * ?")
+ public void updateMemberCoin() {
+ memberProfitService.updateMemberCoin();
+ }
+
+ /**
* 每个月一号
* 节点奖励分发
*/
diff --git a/src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java b/src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
index 02600f6..4720b4f 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
@@ -46,6 +46,8 @@
void updateRunScore();
+ void updateMemberCoin();
+
void updateMemberScore();
void updateNodeScore();
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 ad680eb..2c79b71 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
@@ -2,6 +2,7 @@
import cc.mrbird.febs.common.enumerates.*;
import cc.mrbird.febs.common.utils.AppContants;
+import cc.mrbird.febs.common.utils.MallUtils;
import cc.mrbird.febs.mall.entity.*;
import cc.mrbird.febs.mall.mapper.*;
import cc.mrbird.febs.mall.service.AsyncService;
@@ -53,6 +54,7 @@
private final MallMemberWalletMapper mallMemberWalletMapper;
private final RunNodeSetMapper runNodeSetMapper;
private final MallChargeMapper mallChargeMapper;
+ private final IMallMoneyFlowService mallMoneyFlowService;
private final AsyncService asyncService;
@@ -648,6 +650,141 @@
}
}
+ @Override
+ public void updateMemberCoin() {
+ try {
+ // 操作时间
+ DateTime operationDate = DateUtil.date();
+
+ // 获取最低级别的会员等级
+ RunVip minRunVip = runVipMapper.selectOne(new LambdaQueryWrapper<RunVip>()
+ .orderByAsc(RunVip::getOrderNumber)
+ .last("LIMIT 1")
+ );
+ if (minRunVip == null) {
+ log.error("最低级别的会员等级未找到");
+ return;
+ }
+
+ // 获取全部referrerId不为空的用户,并获取每个用户的所有上级id,返回一个set集合
+ List<MallMember> mallMembers = mallMemberMapper.selectList(
+ new LambdaQueryWrapper<MallMember>()
+ .isNotNull(MallMember::getReferrerId)
+ );
+ if (CollUtil.isEmpty(mallMembers)) {
+ return;
+ }
+
+ Set<Long> memberIds = mallMembers.stream()
+ .map(MallMember::getId)
+ .collect(Collectors.toSet());
+ if (CollUtil.isEmpty(memberIds)) {
+ return;
+ }
+
+
+ // 构建成员ID到MallMember对象的映射
+ Map<Long, MallMember> memberMap = mallMemberMapper.selectBatchIds(memberIds).stream()
+ .collect(Collectors.toMap(MallMember::getId, member -> member));
+
+ for (Long memberId : memberIds) {
+ MallMember mallMember = memberMap.get(memberId);
+ if (mallMember == null || minRunVip.getVipCode().equals(mallMember.getLevel())) {
+ continue;
+ }
+
+ // 获取所有购买了会员等级的直推成员
+ List<MallMember> directMembers = mallMemberMapper.selectList(
+ new LambdaQueryWrapper<MallMember>()
+ .eq(MallMember::getReferrerId, mallMember.getInviteId())
+ .ne(MallMember::getLevel, minRunVip.getVipCode())
+ );
+ if (CollUtil.isEmpty(directMembers)) {
+ continue;
+ }
+
+ for (MallMember item : directMembers) {
+ BigDecimal realScore = calculateDirectScore(mallMember, item, operationDate);
+ if(BigDecimal.ZERO.compareTo(realScore) >= 0){
+ continue;
+ }
+ walletService.addScore(realScore, memberId);
+ String orderNo = MallUtils.getOrderNum("ZLS");
+ mallMoneyFlowService.runVipMoneyFlowAdd(
+ memberId,
+ item.getId(),
+ orderNo,
+ FlowTypeEnum.SCORE.getValue(),
+ RunVipMoneyFlowTypeEnum.DIRECT_SCORE.getValue(),
+ realScore,
+ StrUtil.format(RunVipMoneyFlowTypeEnum.DIRECT_SCORE.getDescription(), realScore),
+ YesOrNoEnum.YES.getValue()
+ );
+ }
+ }
+ } catch (Exception e) {
+ log.error("更新会员积分时发生异常", e);
+ throw new RuntimeException("更新会员积分时发生异常", e); // 根据业务需求选择是否抛出异常
+ }
+ }
+
+
+ private BigDecimal calculateDirectScore(MallMember mallMember, MallMember directMember, Date operationDate) {
+ // 实际助力
+ BigDecimal realScore = BigDecimal.ZERO;
+
+ try {
+ String directLevel = directMember.getLevel();
+ RunVip directRunVip = runVipMapper.selectOne(new LambdaQueryWrapper<RunVip>().eq(RunVip::getVipCode, directLevel));
+ if (directRunVip == null) {
+ return realScore;
+ }
+ // 获取每一个会员的前一日碳积分总和
+ LambdaQueryWrapper<MallMoneyFlow> mallMoneyFlowLambdaQueryWrapper = new LambdaQueryWrapper<>();
+ mallMoneyFlowLambdaQueryWrapper.ge(MallMoneyFlow::getCreatedTime, DateUtil.offsetDay(operationDate, -1));
+ mallMoneyFlowLambdaQueryWrapper.eq(MallMoneyFlow::getFlowType, FlowTypeEnum.SCORE.getValue());
+ mallMoneyFlowLambdaQueryWrapper.eq(MallMoneyFlow::getType, RunVipMoneyFlowTypeEnum.GET_SCORE.getValue());
+
+ List<MallMoneyFlow> mallMoneyFlows = mallMoneyFlowMapper.selectList(mallMoneyFlowLambdaQueryWrapper);
+ if (CollUtil.isEmpty(mallMoneyFlows)) {
+ return realScore;
+ }
+
+ String memberLevel = mallMember.getLevel();
+ RunVip memberRunVip = runVipMapper.selectOne(new LambdaQueryWrapper<RunVip>().eq(RunVip::getVipCode, memberLevel));
+ if (memberRunVip == null) {
+ return realScore;
+ }
+
+ // 如果直推小于会员本身的会员等级,则全部助力
+ if (memberRunVip.getOrderNumber() >= directRunVip.getOrderNumber()) {
+ BigDecimal rebatePercent = directRunVip.getRebatePercent();
+ BigDecimal totalScore = mallMoneyFlows.stream()
+ .map(MallMoneyFlow::getAmount)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ realScore = totalScore.multiply(rebatePercent).setScale(0, RoundingMode.DOWN);
+ } else {
+ Integer growthCnt = memberRunVip.getGrowthCnt();
+ if (growthCnt == null || growthCnt <= 0) {
+ return realScore;
+ }
+ BigDecimal rebatePercent1 = memberRunVip.getRebatePercent();
+ if (rebatePercent1 == null || rebatePercent1.compareTo(BigDecimal.ZERO) <= 0) {
+ return realScore;
+ }
+ realScore = new BigDecimal(growthCnt).multiply(rebatePercent1).setScale(0, RoundingMode.DOWN);
+ }
+ } catch (Exception e) {
+ // 记录日志并返回默认值
+ log.error("Error calculating direct score", e);
+ return BigDecimal.ZERO;
+ }
+
+ return realScore;
+ }
+
+
+
public boolean isDivisibleByTwo(int number) {
return number % 2 == 0;
--
Gitblit v1.9.1