package cc.mrbird.febs.mall.service.impl;
|
|
import cc.mrbird.febs.common.enumerates.*;
|
import cc.mrbird.febs.common.utils.MallUtils;
|
import cc.mrbird.febs.mall.dto.ApiMemberChargeFailDto;
|
import cc.mrbird.febs.mall.entity.*;
|
import cc.mrbird.febs.mall.mapper.*;
|
import cc.mrbird.febs.mall.service.*;
|
import cc.mrbird.febs.rabbit.producter.AgentProducer;
|
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.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* @author wzy
|
* @date 2021-09-26
|
**/
|
@Slf4j
|
@Service
|
@RequiredArgsConstructor
|
public class AgentServiceImpl implements IAgentService {
|
|
private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
|
private final MallMemberMapper mallMemberMapper;
|
private final MallChargeMapper mallChargeMapper;
|
private final RunVipMapper runVipMapper;
|
private final IApiMallMemberWalletService walletService;
|
private final IApiMallMemberService mallMemberService;
|
private final AgentProducer agentProducer;
|
private final RunNodeSetMapper runNodeSetMapper;
|
private final AsyncService asyncService;
|
private final RunVipGrowMapper runVipGrowMapper;
|
private final IMallMoneyFlowService mallMoneyFlowService;
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void autoUpAgentLevel(Long memberId) {
|
MallMember member =mallMemberMapper.selectById(memberId);
|
if(StrUtil.isBlank(member.getReferrerIds())) {
|
return;
|
}
|
|
List<String> ids = StrUtil.split(member.getReferrerIds(), ',');
|
List<MallMember> parentMembers = mallMemberMapper.selectByInviteIds(ids);
|
for (MallMember parent : parentMembers) {
|
// 未激活用户无法升级
|
if (AgentLevelEnum.ZERO_LEVEL.name().equals(member.getLevel())) {
|
continue;
|
}
|
|
DataDictionaryCustom nextLevel = dataDictionaryCustomMapper.selectNextAgentLevelInfo(parent.getLevel());
|
if (nextLevel == null) {
|
log.info("当前层级无下一级:{}", parent.getLevel());
|
continue;
|
}
|
|
AgentInfo agentInfo = JSONObject.parseObject(nextLevel.getValue(), AgentInfo.class);
|
if (!directMemberCnt(parent, agentInfo)) {
|
continue;
|
}
|
|
if (!agentCntFinish(parent, agentInfo)) {
|
continue;
|
}
|
|
if (!teamIncome(parent, agentInfo)) {
|
continue;
|
}
|
|
parent.setLevel(nextLevel.getCode());
|
mallMemberMapper.updateById(parent);
|
}
|
}
|
|
/**
|
* 判断直推人数是否达标
|
*
|
* @param member
|
* @return
|
*/
|
private boolean directMemberCnt(MallMember member, AgentInfo agentInfo) {
|
List<MallMember> childs = mallMemberMapper.selectByRefererId(member.getInviteId());
|
if (CollUtil.isEmpty(childs)) {
|
return false;
|
}
|
|
if (childs.size() >= agentInfo.getDirectCnt()) {
|
return true;
|
}
|
|
log.info("用户:{}直推数量未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getLevel(), childs.size(), agentInfo.getLastAgentCnt());
|
return false;
|
}
|
|
/**
|
* 判断下级代理数量是否达标
|
*
|
* @return
|
*/
|
private boolean agentCntFinish(MallMember member, AgentInfo agentInfo) {
|
if (agentInfo.getLastAgentCnt() == null || agentInfo.getLastAgentCnt() == 0) {
|
return true;
|
}
|
|
// 直推用户
|
List<MallMember> directMember = mallMemberMapper.selectByRefererId(member.getInviteId());
|
if (CollUtil.isEmpty(directMember)) {
|
return false;
|
}
|
|
// 用户团队达到指定代理数量,且都不在同一条线
|
int i = 0;
|
for (MallMember child : directMember) {
|
List<MallMember> mallMembers = mallMemberMapper.selectChildAgentList(child.getInviteId(), member.getLevel());
|
if (CollUtil.isNotEmpty(mallMembers)) {
|
i++;
|
}
|
}
|
|
if (i >= agentInfo.getLastAgentCnt()) {
|
return true;
|
}
|
|
log.info("用户:{}代理数量未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getLevel(), i, agentInfo.getLastAgentCnt());
|
return false;
|
}
|
|
/**
|
* 团队业绩是否达标
|
*
|
* @param agentInfo
|
* @return
|
*/
|
private boolean teamIncome(MallMember member, AgentInfo agentInfo) {
|
BigDecimal totalIncome = mallMemberMapper.selectAchieveByMemberId(member.getInviteId(), 2);
|
|
BigDecimal targetIncome = agentInfo.getTeamIncome().multiply(new BigDecimal("10000"));
|
if (totalIncome.compareTo(targetIncome) >= 0) {
|
return true;
|
}
|
|
log.info("用户:{}团队业绩未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getLevel(), totalIncome, targetIncome);
|
return false;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void returnMoneyToAgent(Long orderId) {
|
}
|
|
@Override
|
public void rankReturnMoney(Long orderId) {
|
|
}
|
|
@Override
|
public void sendMemberChargeFailMsg(ApiMemberChargeFailDto apiMemberChargeFailDto) {
|
// 获取充值订单ID
|
Long chargeId = apiMemberChargeFailDto.getChargeId();
|
|
// 根据充值订单ID查询充值订单信息
|
MallCharge mallCharge = mallChargeMapper.selectById(chargeId);
|
|
// 如果查询不到充值订单信息,则直接返回
|
if(ObjectUtil.isEmpty(mallCharge)){
|
return;
|
}
|
|
// 获取充值订单的状态
|
Integer state = mallCharge.getState();
|
|
// 如果充值订单状态不是正在进行中,则直接返回
|
if(YesOrNoEnum.ING.getValue() != state){
|
return;
|
}
|
|
// 更新充值订单状态为失败
|
mallCharge.setState(YesOrNoEnum.NO.getValue());
|
|
// 更新数据库中的充值订单信息
|
mallChargeMapper.updateById(mallCharge);
|
}
|
|
/**
|
* 购买会员看你的上级和上上级是否满足升级节点的条件
|
* 直推 10人
|
* 团队 50人
|
* 团队总业绩 10000
|
* 满足以上三个条件
|
* 更新升级节点的时间
|
*/
|
private void NodeUp(Long memberId,Integer directCnt,Integer teamCnt,BigDecimal achieveCnt){
|
try {
|
// 获取会员信息
|
MallMember mallMember = mallMemberMapper.selectById(memberId);
|
if (mallMember == null) {
|
log.info("会员不存在");
|
return;
|
}
|
|
// 已经是节点则跳过
|
if (YesOrNoEnum.YES.getValue() == mallMember.getDirector()) {
|
return;
|
}
|
|
//节点不是最高等级不升级节点
|
Optional<RunVip> max = runVipMapper.selectList(null).stream().max(Comparator.comparing(RunVip::getOrderNumber));
|
RunVip maxRunVip = max.orElse(null);
|
if (maxRunVip == null) {
|
log.info("会员等级不存在");
|
return;
|
}
|
if (!maxRunVip.getVipCode().equals(mallMember.getLevel())) {
|
return;
|
}
|
|
// 获取直推成员和团队成员
|
List<MallMember> allMembers = mallMemberMapper.selectList(
|
new LambdaQueryWrapper<MallMember>()
|
.eq(MallMember::getReferrerId, mallMember.getInviteId())
|
.or()
|
.in(MallMember::getReferrerId, mallMemberMapper.selectList(
|
new LambdaQueryWrapper<MallMember>()
|
.eq(MallMember::getReferrerId, mallMember.getInviteId())
|
).stream()
|
.map(MallMember::getInviteId)
|
.collect(Collectors.toSet()))
|
);
|
|
if (allMembers == null || allMembers.isEmpty()) {
|
return;
|
}
|
|
// 检查直推人数
|
long directCount = allMembers.stream()
|
.filter(member -> mallMember.getInviteId().equals(member.getReferrerId()))
|
.count();
|
if (directCount < directCnt) {
|
return;
|
}
|
|
// 检查团队人数
|
if (allMembers.size() < teamCnt) {
|
return;
|
}
|
|
// 获取团队业绩(不包含本人业绩)
|
Set<Long> memberIds = allMembers.stream()
|
.map(MallMember::getId)
|
.collect(Collectors.toSet());
|
|
List<MallCharge> mallCharges = mallChargeMapper.selectList(
|
new LambdaQueryWrapper<MallCharge>()
|
.in(MallCharge::getMemberId, memberIds)
|
.eq(MallCharge::getState, YesOrNoEnum.YES.getValue())
|
.ge(MallCharge::getCreatedTime, mallMember.getDirectorTime())
|
);
|
|
BigDecimal totalCharge = mallCharges.stream()
|
.map(MallCharge::getAmount)
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
if (totalCharge.compareTo(achieveCnt) < 0) {
|
return;
|
}
|
|
mallMember.setDirector(YesOrNoEnum.YES.getValue());
|
mallMember.setDirectorTime(DateUtil.date());
|
mallMemberMapper.updateById(mallMember);
|
|
//获取节点设置
|
List<RunNodeSet> runNodeSets = runNodeSetMapper.selectList(null);
|
//获取总业绩
|
BigDecimal nodePercent = getNodePercent(runNodeSets, totalCharge);
|
if(nodePercent.compareTo(BigDecimal.ZERO) >= 0){
|
asyncService.releaseNodeCoin(totalCharge,nodePercent,memberId);
|
}
|
} catch (Exception e) {
|
// 记录日志并处理异常
|
log.error("会员升级节点失败: {}", memberId, e);
|
throw new RuntimeException("会员升级节点失败", e);
|
}
|
}
|
|
private BigDecimal getNodePercent(List<RunNodeSet> runNodeSets, BigDecimal directAchieve) {
|
BigDecimal percent = BigDecimal.ZERO;
|
//获取directAchieve在runNodeSets中哪一个位置
|
for(RunNodeSet item : runNodeSets){
|
BigDecimal minAchieve = item.getMinAchieve();
|
BigDecimal maxAchieve = item.getMaxAchieve();
|
BigDecimal nodePercent = new BigDecimal(item.getNodePercent());
|
if(directAchieve.compareTo(minAchieve) >= 0 && directAchieve.compareTo(maxAchieve) < 0){
|
percent = nodePercent;
|
break;
|
}
|
}
|
return percent;
|
}
|
@Override
|
public void buyVipSuccessMsg(Long chargeId) {
|
MallCharge mallCharge = mallChargeMapper.selectById(chargeId);
|
|
Long memberId = mallCharge.getMemberId();
|
String vipCode = mallCharge.getVipCode();
|
|
//判断mallCharge.getVipName()的最后两个字符是否等于“权益”
|
if("权益".equals(mallCharge.getVipName().substring(mallCharge.getVipName().length()-2,mallCharge.getVipName().length()))){
|
MallMember mallMember = mallMemberMapper.selectById(memberId);
|
|
RunVipGrow runVipGrow = runVipGrowMapper.selectOne(
|
new LambdaQueryWrapper<RunVipGrow>()
|
.eq(RunVipGrow::getMemberId, memberId)
|
.eq(RunVipGrow::getLevelNow, mallMember.getLevel())
|
);
|
BigDecimal amount = mallCharge.getAmount();
|
//有升级权益的记录
|
if(runVipGrow != null){
|
//判断金额是否满足升级条件
|
BigDecimal amountNow = runVipGrow.getAmountNow();
|
BigDecimal amountAll = runVipGrow.getAmountAll();
|
BigDecimal subtract = amountAll.subtract(amountNow);
|
|
if(subtract.compareTo(amount) <= 0){
|
runVipGrow.setAmountNow(amountAll);
|
}else{
|
runVipGrow.setAmountNow(amountNow.add(amount).setScale(2, RoundingMode.DOWN));
|
}
|
runVipGrow.setAmount(amount);
|
runVipGrowMapper.updateById(runVipGrow);
|
}else{
|
List<RunVip> runVips = runVipMapper.selectList(null);
|
Map<String, RunVip> runVipMap = runVips.stream()
|
.collect(Collectors.toMap(RunVip::getVipCode, runVip -> runVip));
|
|
RunVip runVipNow = runVipMap.get(mallMember.getLevel());
|
RunVip runVipNext = runVips.stream().filter(runVip -> runVip.getOrderNumber() == runVipNow.getOrderNumber() + 1).findFirst().orElse(null);
|
if(null != runVipNext){
|
BigDecimal add = runVipNow.getPresentPrice().add(amount);
|
|
runVipGrow = new RunVipGrow();
|
runVipGrow.setMemberId(memberId);
|
runVipGrow.setLevelNow(mallMember.getLevel());
|
runVipGrow.setLevelNext(runVipNext.getVipCode());
|
runVipGrow.setAmountAll(runVipNext.getPresentPrice());
|
runVipGrow.setAmount(add);
|
runVipGrow.setAmountNow(add);
|
runVipGrowMapper.insert(runVipGrow);
|
}
|
}
|
}
|
//更新会员的等级和会员升级的时间
|
mallMemberMapper.updateVipLevelTimeAndLevel(memberId,DateUtil.date(),vipCode);
|
|
//直推权益
|
asyncService.directCoin(mallCharge.getAmount(),memberId);
|
|
agentProducer.sendNodeUpMsg(memberId);
|
}
|
|
@Override
|
public void nodeUpMsg(Long memberId) {
|
DataDictionaryCustom directCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
|
RunVipDataDictionaryEnum.NODE_DIRECT_CNT.getType(),
|
RunVipDataDictionaryEnum.NODE_DIRECT_CNT.getCode());
|
Integer directCnt = Integer.parseInt(directCntDic.getValue());
|
DataDictionaryCustom teamCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
|
RunVipDataDictionaryEnum.NODE_TEAM_CNT.getType(),
|
RunVipDataDictionaryEnum.NODE_TEAM_CNT.getCode());
|
Integer teamCnt = Integer.parseInt(teamCntDic.getValue());
|
DataDictionaryCustom achieveCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
|
RunVipDataDictionaryEnum.NODE_ACHIEVE_CNT.getType(),
|
RunVipDataDictionaryEnum.NODE_ACHIEVE_CNT.getCode());
|
BigDecimal achieveCnt = new BigDecimal(achieveCntDic.getValue());
|
|
MallMember mallMember = mallMemberMapper.selectById(memberId);
|
if(StrUtil.isEmpty(mallMember.getReferrerId())){
|
return;
|
}
|
//上级
|
MallMember parentMember = mallMemberMapper.selectInfoByInviteId(mallMember.getReferrerId());
|
NodeUp(parentMember.getId(),directCnt,teamCnt,achieveCnt);
|
|
if(StrUtil.isEmpty(parentMember.getReferrerId())){
|
return;
|
}
|
//上上级
|
MallMember graMember = mallMemberMapper.selectInfoByInviteId(parentMember.getReferrerId());
|
NodeUp(graMember.getId(),directCnt,teamCnt,achieveCnt);
|
}
|
|
@Override
|
public void chargeSuccessMsg(Long chargeId) {
|
|
MallCharge mallCharge = mallChargeMapper.selectById(chargeId);
|
if(null == mallCharge){
|
return;
|
}
|
Long memberId = mallCharge.getMemberId();
|
BigDecimal amount = mallCharge.getAmount();
|
|
walletService.addCommission(amount, memberId);
|
String orderNo = MallUtils.getOrderNum("C");
|
mallMoneyFlowService.runVipMoneyFlowAdd(
|
memberId,
|
memberId,
|
orderNo,
|
FlowTypeEnum.COMMISSION.getValue(),
|
RunVipMoneyFlowTypeEnum.COMMISSION_PAY_CHARGE.getValue(),
|
amount,
|
StrUtil.format(RunVipMoneyFlowTypeEnum.COMMISSION_PAY_CHARGE.getDescription(),amount),
|
YesOrNoEnum.YES.getValue()
|
);
|
}
|
}
|