From 4ee42556139749bf6f29d47b912da0be6c37da2a Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Thu, 15 May 2025 11:29:39 +0800
Subject: [PATCH] feat(mall): 添加商品 SKU静态属性价格字段
---
src/main/java/cc/mrbird/febs/vip/service/impl/VipCommonServiceImpl.java | 429 ++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 341 insertions(+), 88 deletions(-)
diff --git a/src/main/java/cc/mrbird/febs/vip/service/impl/VipCommonServiceImpl.java b/src/main/java/cc/mrbird/febs/vip/service/impl/VipCommonServiceImpl.java
index 1693591..2c20a88 100644
--- a/src/main/java/cc/mrbird/febs/vip/service/impl/VipCommonServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/vip/service/impl/VipCommonServiceImpl.java
@@ -2,15 +2,16 @@
import cc.mrbird.febs.common.enumerates.FlowTypeEnum;
import cc.mrbird.febs.common.enumerates.MoneyFlowTypeEnum;
+import cc.mrbird.febs.common.enumerates.OrderStatusEnum;
import cc.mrbird.febs.common.enumerates.ScoreFlowTypeEnum;
-import cc.mrbird.febs.mall.entity.MallMember;
-import cc.mrbird.febs.mall.entity.MallOrderInfo;
-import cc.mrbird.febs.mall.entity.MallOrderItem;
-import cc.mrbird.febs.mall.mapper.MallMemberMapper;
-import cc.mrbird.febs.mall.mapper.MallOrderInfoMapper;
+import cc.mrbird.febs.common.exception.FebsException;
+import cc.mrbird.febs.mall.entity.*;
+import cc.mrbird.febs.mall.mapper.*;
+import cc.mrbird.febs.mall.service.IApiMallGoodsService;
import cc.mrbird.febs.mall.service.IApiMallMemberWalletService;
import cc.mrbird.febs.mall.service.IApiMallOrderInfoService;
import cc.mrbird.febs.mall.service.IMallMoneyFlowService;
+import cc.mrbird.febs.rabbit.producter.AgentProducer;
import cc.mrbird.febs.vip.entity.MallVipBenefits;
import cc.mrbird.febs.vip.entity.MallVipConfig;
import cc.mrbird.febs.vip.mapper.MallVipConfigMapper;
@@ -18,6 +19,7 @@
import cc.mrbird.febs.vip.service.IVipCommonService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
@@ -26,8 +28,13 @@
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.logging.Handler;
+import java.util.stream.Collectors;
@Slf4j
@Service
@@ -38,124 +45,370 @@
private final IMallVipConfigService mallVipConfigService;
private final IMallMoneyFlowService mallMoneyFlowService;
private final IApiMallMemberWalletService mallMemberWalletService;
+ private final MallMemberWalletMapper mallMemberWalletMapper;
private final MallMemberMapper mallMemberMapper;
private final MallVipConfigMapper mallVipConfigMapper;
-
+ private final AgentProducer agentProducer;
+ private final IApiMallGoodsService mallGoodsService;
+ private final HappyMemberLevelMapper happyMemberLevelMapper;
+ private final HappySaleLevelMapper happySaleLevelMapper;
+ private final MallAchieveRecordMapper mallAchieveRecordMapper;
+ /**
+ * 根据订单ID获取分数
+ * 此方法处理订单得分逻辑,包括直接购买得分、会员等级得分和推荐人得分
+ *
+ * @param orderId 订单ID,用于查询订单详细信息
+ */
@Override
@Transactional(rollbackFor = Exception.class)
public void getScore(Long orderId) {
+ // 根据订单ID查询订单详细信息
MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectOrderDetailsById(orderId);
if (mallOrderInfo == null) {
+ // 如果订单信息为空,则直接返回
return;
}
- Long memberId = mallOrderInfo.getMemberId();
- MallVipBenefits mallVipBenefits = mallVipConfigService.hasVipBenefits(memberId);
-
- BigDecimal multiple = BigDecimal.ONE;
- String name = "";
- if (mallVipBenefits != null) {
- multiple = mallVipBenefits.getScoreMultiple();
- name = mallVipBenefits.getName();
+ if (mallOrderInfo.getStatus() != OrderStatusEnum.FINISH.getValue()) {
+ // 订单不是完成状态
+ return;
}
- double sum = mallOrderInfo.getItems().stream().map(MallOrderItem::getAmount).mapToDouble(BigDecimal::doubleValue).sum();
+ // 获取订单金额
+ BigDecimal amount = mallOrderInfo.getAmount();
+ if(BigDecimal.ZERO.compareTo(amount) >= 0){
+ // 如果订单金额小于等于0,则直接返回
+ return;
+ }
- int score = multiple.multiply(BigDecimal.valueOf(sum)).intValue();
+ // 获取会员ID
+ Long memberId = mallOrderInfo.getMemberId();
+ // 根据会员ID查询会员信息
+ MallMember member = mallMemberMapper.selectById(memberId);
- mallMoneyFlowService.addMoneyFlow(memberId, new BigDecimal(score), ScoreFlowTypeEnum.BUY.getValue(), mallOrderInfo.getOrderNo(), FlowTypeEnum.PRIZE_SCORE.getValue(), name, 2);
- mallMemberWalletService.add(new BigDecimal(score), memberId, "prizeScore");
+ // 记录会员购买获得的经验
+ mallMoneyFlowService.addMoneyFlow(
+ memberId,
+ amount,
+ ScoreFlowTypeEnum.BUY.getValue(),
+ mallOrderInfo.getOrderNo(),
+ FlowTypeEnum.SCORE.getValue(),
+ StrUtil.format(ScoreFlowTypeEnum.BUY.getDesc(),amount),
+ 2
+ );
+ // 更新会员钱包中的分数
+ mallMemberWalletService.add(amount, memberId, "score");
+
+ // 下单自己获得积分,推荐人获得积分
+ //<memberId,积分数量>的map
+ Map<Long, BigDecimal> recommendScoreMap = new HashMap<>();
+ Map<Long, Integer> recommendTypeScoreMap = new HashMap<>();
+ // 获取会员的董事等级代码
+ Integer director = member.getDirector();
+ // 查询与董事等级代码匹配的会员等级信息
+ LambdaQueryWrapper<HappyMemberLevel> happyMemberLevelLambdaQueryWrapper = new LambdaQueryWrapper<HappyMemberLevel>();
+ happyMemberLevelLambdaQueryWrapper.eq(HappyMemberLevel::getCode, director);
+ happyMemberLevelLambdaQueryWrapper.last("limit 1");
+ HappyMemberLevel happyMemberLevel = happyMemberLevelMapper.selectOne(happyMemberLevelLambdaQueryWrapper);
+ if(ObjectUtil.isNotEmpty(happyMemberLevel)){
+ // 计算自己获得的积分
+ BigDecimal minePercent = happyMemberLevel.getMinePercent();
+ BigDecimal mineScore = amount.multiply(minePercent).setScale(0, RoundingMode.HALF_DOWN);
+ if(BigDecimal.ZERO.compareTo(mineScore) < 0){
+ recommendScoreMap.put(memberId, mineScore);
+ recommendTypeScoreMap.put(memberId, ScoreFlowTypeEnum.MINE_RECOMMEND.getValue());
+ }
+ // 计算推荐人获得的积分
+ if(StrUtil.isNotEmpty(member.getReferrerId())){
+ MallMember refMember = mallMemberMapper.selectInfoByInviteId(member.getReferrerId());
+ BigDecimal otherPercent = happyMemberLevel.getOtherPercent();
+ BigDecimal otherScore = amount.multiply(otherPercent).setScale(0, RoundingMode.HALF_DOWN);
+ if(BigDecimal.ZERO.compareTo(otherScore) < 0){
+ recommendScoreMap.put(refMember.getId(), otherScore);
+ recommendTypeScoreMap.put(memberId, ScoreFlowTypeEnum.OTHER_RECOMMEND.getValue());
+ }
+ }
+ }
+
+ // 为推荐人和自己添加积分流动记录和更新钱包
+ recommendScoreMap.forEach((key, value) -> {
+ if (value != null) {
+ mallMoneyFlowService.addMoneyFlow(
+ key,
+ value,
+ recommendTypeScoreMap.get(key),
+ mallOrderInfo.getOrderNo(),
+ FlowTypeEnum.PRIZE_SCORE.getValue(),
+ StrUtil.format(ScoreFlowTypeEnum.getDescByValue(recommendTypeScoreMap.get(key)),value),
+ 2);
+ mallMemberWalletService.add(value, key, "prizeScore");
+ }
+ });
+
+ // 发送会员等级升级消息
+ agentProducer.sendVipLevelUp(orderId);
}
+
+ /**
+ * 根据订单ID升级会员等级
+ * 当订单完成时,根据会员当前的经验值升级会员等级
+ *
+ * @param orderId 订单ID
+ */
@Override
public void levelUp(Long orderId) {
+ // 根据订单ID获取订单详细信息
MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectOrderDetailsById(orderId);
+ // 如果订单信息为空,则直接返回
if (mallOrderInfo == null) {
return;
}
+ // 如果订单状态不是完成状态,则直接返回
+ if (mallOrderInfo.getStatus() != OrderStatusEnum.FINISH.getValue()) {
+ // 订单不是完成状态
+ return;
+ }
+ // 根据订单中的会员ID获取会员信息
MallMember member = mallMemberMapper.selectById(mallOrderInfo.getMemberId());
+ // 如果会员信息为空,则记录日志并返回
if (member == null) {
log.info("会员不存在");
return;
}
- MallVipConfig config = mallVipConfigMapper.selectVipConfigByCode(member.getLevel());
- if (config == null) {
- log.info("会员等级配置不存在");
+ // 根据会员ID获取会员钱包信息
+ MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(member.getId());
+ // 如果会员钱包信息为空,则记录日志并返回
+ if (mallMemberWallet == null) {
+ log.info("会员钱包不存在");
+ return;
+ }
+ //当前经验值
+ int score = mallMemberWallet.getScore().intValue();
+
+ // 查询当前经验值对应的会员等级
+ HappyMemberLevel happyMemberLevel = happyMemberLevelMapper.selectOne(
+ new LambdaQueryWrapper<HappyMemberLevel>()
+ .ge(HappyMemberLevel::getUpgradeScore, score)
+ .orderByAsc(HappyMemberLevel::getCode)
+ .last("limit 1")
+ );
+ // 如果查询不到对应的会员等级,则记录日志并返回
+ if (happyMemberLevel == null) {
+ log.info("会员等级不存在");
+ return;
+ }
+ // 获取当前会员等级代码
+ Integer code = happyMemberLevel.getCode();
+ // 如果当前会员等级与会员的导演等级相同,则直接返回
+ if(member.getDirector() == code){
return;
}
-// LambdaQueryWrapper<MallVipConfig> configQuery = new LambdaQueryWrapper<>();
-// configQuery.gt(MallVipConfig::getLevel, config.getLevel())
-// .orderByAsc(MallVipConfig::getLevel)
-// .last("limit 1");
-// MallVipConfig nextLevel = mallVipConfigMapper.selectOne(configQuery);
+ // 更新会员的导演等级为当前会员等级代码
+ member.setDirector(code);
+ // 更新会员信息
+ mallMemberMapper.updateById(member);
- List<MallVipConfig> configs = mallVipConfigMapper.selectVipConfigList();
-
- String nextLevelCode = "";
- for (MallVipConfig nextLevel : configs) {
- if (config.getLevel() >= nextLevel.getLevel()) {
- continue;
- }
-
- // 指定商品
- if (nextLevel.getType() == 1) {
- boolean hasMatch = mallOrderInfo.getItems().stream().anyMatch(item -> {
- return item.getGoodsId().equals(nextLevel.getTargetId());
- });
-
- if (hasMatch) {
- nextLevelCode = nextLevel.getCode();
- continue;
- }
- }
-
- // 时间区间内金额
- if (nextLevel.getType() == 2) {
- Date endTime = DateUtil.endOfDay(new Date());
- Date startTime = getStartTime(nextLevel.getValidType());
-
- LambdaQueryWrapper<MallOrderInfo> query = new LambdaQueryWrapper<>();
- query.ge(MallOrderInfo::getReceivingTime, startTime)
- .le(MallOrderInfo::getReceivingTime, endTime)
- .eq(MallOrderInfo::getStatus, 4)
- .eq(MallOrderInfo::getMemberId, member.getId());
- List<MallOrderInfo> orderList = mallOrderInfoMapper.selectList(query);
- if (CollUtil.isEmpty(orderList)) {
- continue;
- }
-
- double totalAmount = orderList.stream().mapToDouble(item -> {
- return item.getAmount().doubleValue();
- }).sum();
-
- if (nextLevel.getAmount().compareTo(BigDecimal.valueOf(totalAmount)) <= 0) {
- nextLevelCode = nextLevel.getCode();
- }
- }
- }
-
- if (StrUtil.isNotBlank(nextLevelCode)) {
- MallMember update = new MallMember();
- update.setId(member.getId());
- update.setLevel(nextLevelCode);
- mallMemberMapper.updateById(update);
- }
+ // 发送分销等级升级消息
+ agentProducer.sendSaleLevelUp(orderId);
}
- private Date getStartTime(String type) {
- Date date = new Date();
- switch (type) {
- case "day" :
- return DateUtil.beginOfDay(date);
- case "month":
- return DateUtil.beginOfMonth(date);
- case "year":
- return DateUtil.beginOfYear(date);
- default:
- return date;
+ /**
+ * 升级销售级别时处理订单相关的逻辑
+ *
+ * @param orderId 订单ID,用于识别和处理特定的订单
+ */
+ @Override
+ public void saleLevelUp(Long orderId) {
+ // 根据订单ID获取订单详细信息
+ MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectOrderDetailsById(orderId);
+ // 如果订单信息为空,则直接返回
+ if (mallOrderInfo == null) {
+ return;
}
+ // 如果订单状态不是完成状态,则直接返回
+ if (mallOrderInfo.getStatus() != OrderStatusEnum.FINISH.getValue()) {
+ // 订单不是完成状态
+ return;
+ }
+
+ // 根据订单中的会员ID获取会员信息
+ MallMember member = mallMemberMapper.selectById(mallOrderInfo.getMemberId());
+ // 如果会员信息为空,则记录日志并返回
+ if (member == null) {
+ log.info("会员不存在");
+ return;
+ }
+
+ // 如果会员的推荐人ID为空,则直接返回
+ if(StrUtil.isEmpty(member.getReferrerIds())){
+ return;
+ }
+ // 分割会员的推荐人ID
+ String[] referrerIds = member.getReferrerIds().split(",");
+ // 查询符合条件的团长会员
+ MallMember storeMasterMember = mallMemberMapper.selectOne(
+ new LambdaQueryWrapper<MallMember>()
+ .in(MallMember::getInviteId, referrerIds)
+ .eq(MallMember::getAccountStatus, MallMember.ACCOUNT_STATUS_ENABLE)
+ .eq(MallMember::getAccountType, MallMember.ACCOUNT_TYPE_NORMAL)
+ .ne(MallMember::getStoreMaster, 0)
+ .orderByAsc(MallMember::getStoreMaster)
+ .last("limit 1")
+ );
+ // 如果没有找到符合条件的团长,则记录日志并返回
+ if (storeMasterMember == null) {
+ log.info("团长不存在");
+ return;
+ }
+ // 根据团长的等级代码查询团长等级信息
+ HappySaleLevel happySaleLevel = happySaleLevelMapper.selectOne(
+ new LambdaQueryWrapper<HappySaleLevel>()
+ .eq(HappySaleLevel::getCode, storeMasterMember.getStoreMaster())
+ );
+ // 如果团长等级信息不存在,则记录日志并返回
+ if (happySaleLevel == null) {
+ log.info("团长等级不存在");
+ return;
+ }
+ // 计算返佣金额
+ BigDecimal returnPercent = happySaleLevel.getReturnPercent();
+ BigDecimal multiply = mallOrderInfo.getAmount().multiply(returnPercent).setScale(2, RoundingMode.HALF_DOWN);
+ // 如果返佣金额小于等于0,则直接返回
+ if(BigDecimal.ZERO.compareTo(multiply) >=0){
+ return;
+ }
+ // 如果返佣金额大于等于订单金额,则直接返回
+ if(multiply.compareTo(mallOrderInfo.getAmount()) >= 0){
+ return;
+ }
+ // 记录团长获得返佣
+ mallMoneyFlowService.addMoneyFlow(
+ storeMasterMember.getId(),
+ multiply,
+ ScoreFlowTypeEnum.SALE_RECOMMEND.getValue(),
+ mallOrderInfo.getOrderNo(),
+ FlowTypeEnum.COMMISSION.getValue(),
+ StrUtil.format(ScoreFlowTypeEnum.SALE_RECOMMEND.getDesc(),multiply),
+ 2
+ );
+ // 更新会员钱包中的余额
+ mallMemberWalletService.add(multiply, storeMasterMember.getId(), "commission");
+ mallMemberWalletService.add(multiply, storeMasterMember.getId(), "total_score");
+
+ MallAchieveRecord mallAchieveRecord = new MallAchieveRecord();
+ mallAchieveRecord.setMemberId(mallOrderInfo.getMemberId());
+ mallAchieveRecord.setAchieveTime(new Date());
+ mallAchieveRecord.setAmount(mallOrderInfo.getAmount());
+ mallAchieveRecord.setCostAmount(multiply);
+ mallAchieveRecord.setOrderId(mallOrderInfo.getId());
+ mallAchieveRecord.setIsNormal(1);
+ mallAchieveRecord.setPayTime(mallOrderInfo.getPayTime());
+ mallAchieveRecordMapper.insert(mallAchieveRecord);
+
+ this.autoUpAgentLevel(storeMasterMember.getId());
}
+
+
+ /**
+ * 自动升级代理等级
+ * 根据会员的当前状态和业绩,自动为其升级到下一个代理等级
+ * @param memberId 会员ID,用于识别需要升级的会员
+ */
+ private void autoUpAgentLevel(Long memberId) {
+ // 根据会员ID查询会员信息
+ MallMember member = mallMemberMapper.selectById(memberId);
+
+ // 检查会员账户状态和类型,只有在启用状态和普通类型时才进行升级操作
+ if(MallMember.ACCOUNT_STATUS_ENABLE != member.getAccountStatus()
+ || MallMember.ACCOUNT_TYPE_NORMAL != member.getAccountType() ){
+ return;
+ }
+ // 获取会员当前的店铺主人等级
+ Integer storeMaster = member.getStoreMaster();
+ // 下一个分销等级
+ storeMaster =storeMaster +1;
+ // 根据新的店铺主人等级查询对应的快乐销售等级信息
+ HappySaleLevel happySaleLevel = happySaleLevelMapper.selectOne(
+ new LambdaQueryWrapper<HappySaleLevel>()
+ .eq(HappySaleLevel::getCode, storeMaster)
+ );
+ // 如果没有找到对应的快乐销售等级信息,则记录日志并返回
+ if (happySaleLevel == null) {
+ log.info("当前等级无下级");
+ return;
+ }
+ // 检查直推会员数量是否达到要求
+ if (!directMemberCnt(member, happySaleLevel.getDirectCnt())) {
+ return;
+ }
+
+ // 检查团队人数是否达到要求
+ if (!teamCntFinish(member, happySaleLevel.getTeamCnt())) {
+ return;
+ }
+
+ // 检查团队业绩是否达到要求
+ if (!teamIncome(member, happySaleLevel.getTeamAmount())) {
+ return;
+ }
+
+ // 更新会员的店铺主人等级
+ member.setStoreMaster(storeMaster);
+ // 更新会员信息
+ mallMemberMapper.updateById(member);
+ }
+
+
+ /**
+ * 判断直推人数是否达标
+ */
+ private boolean directMemberCnt(MallMember member, Integer directCnt) {
+ List<MallMember> childList = mallMemberMapper.selectByRefererId(member.getInviteId());
+ if (CollUtil.isEmpty(childList)) {
+ return false;
+ }
+
+ if (childList.size() >= directCnt) {
+ return true;
+ }
+
+ log.info("用户:{}直推数量未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getStoreMaster(), childList.size(), directCnt);
+ return false;
+ }
+
+ /**
+ * 判断团队数量是否达标
+ */
+ private boolean teamCntFinish(MallMember member, Integer teamCnt) {
+ // 直推用户
+ List<MallMember> teamMember = mallMemberMapper.selectAllChildAgentListByInviteId(member.getInviteId());
+ if (CollUtil.isEmpty(teamMember)) {
+ return false;
+ }
+
+ if (teamMember.size() >= teamCnt) {
+ return true;
+ }
+
+ log.info("用户:{}团队数量未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getStoreMaster(), teamMember.size(), teamCnt);
+ return false;
+ }
+
+ /**
+ * 团队业绩是否达标
+ */
+ private boolean teamIncome(MallMember member, BigDecimal teamAmount) {
+ BigDecimal totalIncome = mallMemberMapper.selectAchieveByMemberId(member.getInviteId(), 2);
+
+ if(totalIncome.compareTo(teamAmount) >= 0){
+ return true;
+ }
+ log.info("用户:{}团队业绩未达标, 当前等级:{}, 当前业绩:{}, 目标业绩:{}", member.getPhone(), member.getStoreMaster(), totalIncome, teamAmount);
+ return false;
+ }
+
}
--
Gitblit v1.9.1