src/main/java/cc/mrbird/febs/common/interceptor/LoginInterceptor.java
@@ -68,7 +68,7 @@ private String resolveToken(String token) { try { RSA rsa = new RSA(AppContants.PRIVATE_KEY, null); String[] tokens = StrUtil.split(rsa.decryptStr(token, KeyType.PrivateKey), "_"); String[] tokens = StrUtil.splitToArray(rsa.decryptStr(token, KeyType.PrivateKey), "_"); if (verifyTokenExpired(Long.parseLong(tokens[1]))) { return tokens[0]; } else { src/main/java/cc/mrbird/febs/common/tree/MatrixTree.java
@@ -4,6 +4,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; /** @@ -136,4 +137,31 @@ return null; } /** * 获取某一个MemberNode的所有上级节点 * @param node MemberNode节点 * @return MemberNode的List,按照从上到下的顺序排列 */ public List<MemberNode> getAllAncestors(MemberNode node) { List<MemberNode> ancestorList = new ArrayList<>(); getAllAncestorsHelper(node, ancestorList); return ancestorList; } /** * 递归辅助方法,用于获取某一个MemberNode的所有上级节点 * @param node 当前节点 * @param ancestorList 存储上级节点的List */ private void getAllAncestorsHelper(MemberNode node, List<MemberNode> ancestorList) { if (node == null || node.getRefererId() == null) { return; } MemberNode parent = getNode(node.getRefererId()); ancestorList.add(parent); getAllAncestorsHelper(parent, ancestorList); } } src/main/java/cc/mrbird/febs/common/tree/MemberNode.java
@@ -18,6 +18,8 @@ private String refererId; private Integer type; public List<MemberNode> CHILD = new LinkedList<>(); public MemberNode(Long memberId, String phone, String inviteId, String refererId) { src/main/java/cc/mrbird/febs/dapp/entity/DappMemberEntity.java
@@ -56,7 +56,7 @@ private String chainType; /** * 是否是超级节点 1-是 2-否 * 推广标识 1-左 2-右 */ private Integer nodeType; @@ -64,8 +64,12 @@ * 账号类型 admin normal */ private String accountType; //小区业绩 private BigDecimal usdtBalance; //左边区域业绩 private BigDecimal leftAchieve; //右边区域业绩 private BigDecimal rightAchieve; /** * 激活状态 1-已激活 2-未激活 src/main/java/cc/mrbird/febs/dapp/entity/MallAchieveRecord.java
@@ -16,7 +16,7 @@ public class MallAchieveRecord extends BaseEntity { private Long memberId; //剩余业绩 private BigDecimal amount; //订单成本 private BigDecimal costAmount; src/main/java/cc/mrbird/febs/dapp/entity/MatrixTreeNode.java
@@ -14,6 +14,8 @@ private Long parentNode; private Integer deep; //1:左边 2:右边 0:根节点 private Integer type; @TableField(exist = false) private String phone; src/main/java/cc/mrbird/febs/dapp/mapper/DappMemberDao.java
@@ -90,4 +90,6 @@ DappMemberEntity selectInviteLeft(@Param("inviteId")String inviteId); DappMemberEntity selectInviteRight(@Param("inviteId")String inviteId); List<DappMemberEntity> selectMemberByActiveStatus(); } src/main/java/cc/mrbird/febs/dapp/mapper/MallAchieveRecordMapper.java
@@ -19,5 +19,9 @@ BigDecimal selectSumAchieveByMemberIds(@Param("list")List<Long> mallMembersOffLinePerkIds, @Param("date") Date date); BigDecimal selectSumAchieveByMemberIdList(@Param("list")List<Long> mallMembersOffLinePerkIds); List<MallAchieveRecord> selectListByDate(@Param("date")Date profitDate); List<MallAchieveRecord> selectListByMemberId(@Param("memberId")Long memberId); } src/main/java/cc/mrbird/febs/dapp/mapper/MatrixTreeNodeMapper.java
@@ -12,4 +12,6 @@ List<MatrixTreeNode> selectAllMatrixTreeNode(); MatrixTreeNode selectByTreeNode(@Param("treeNode") Long treeNode); MatrixTreeNode selectByParentNodeAndType(@Param("parentNodeMemberId")Long parentNodeMemberId, @Param("nodeType")Integer nodeType); } src/main/java/cc/mrbird/febs/dapp/service/DappSystemService.java
@@ -104,4 +104,6 @@ void speedPayOrderMsg(Long orderId); void speedAutoLevelUpMsg(Long memberId); void memberPerk(); } src/main/java/cc/mrbird/febs/dapp/service/impl/DappMemberServiceImpl.java
@@ -933,11 +933,20 @@ BigDecimal.ZERO, payOrderNo, id); dappFundFlowDao.insert(donateScoreFlow); /** * 支付成功,消费后成有效账户后可分享(有效用户可推广) */ DappMemberEntity dappMemberEntity = dappMemberDao.selectById(member.getId()); if(2 == dappMemberEntity.getActiveStatus()){ dappMemberEntity.setActiveStatus(1); dappMemberDao.updateById(dappMemberEntity); } /** * todo 发送一条订单出的消息 */ chainProducer.sendSpeedPayOrderMsg(id); chainProducer.sendAutoLevelUpMsg(member.getId()); } public static List<List<String>> partitionList(List<String> originalList, int partitionSize) { src/main/java/cc/mrbird/febs/dapp/service/impl/DappSystemServiceImpl.java
@@ -2,6 +2,7 @@ import cc.mrbird.febs.common.contants.AppContants; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.common.tree.MatrixTree; import cc.mrbird.febs.common.tree.MemberNode; import cc.mrbird.febs.common.utils.LoginUserUtil; import cc.mrbird.febs.common.utils.RedisUtils; @@ -2488,26 +2489,100 @@ return; } List<DataDictionaryCustom> dicList = dataDictionaryCustomMapper.selectDicByType(AppContants.AGENT_LEVEL); DataDictionaryCustom dic = null; for (DataDictionaryCustom dataDictionaryCustom : dicList) { if (Integer.parseInt(dataDictionaryCustom.getValue()) == parentNode.CHILD.size()) { dic = dataDictionaryCustom; break; } } if (dic == null) { MatrixTree matrixTree = MatrixTree.getInstance(); List<MemberNode> allNodes = matrixTree.getAllAncestors(parentNode); // 获取某一个MemberNode的所有上级节点 allNodes.add(parentNode); if(CollUtil.isEmpty(allNodes)){ return; } /** * 更新所有上级的小区业绩 */ for(MemberNode memberNode : allNodes){ BigDecimal smallAchieve = BigDecimal.ZERO; List<MemberNode> allNodesChildList = memberNode.getCHILD(); if(CollUtil.isNotEmpty(allNodesChildList)){ List<Long> left = allNodesChildList.stream().filter(allNodesChild -> allNodesChild.getType() == 1).map(MemberNode::getMemberId).collect(Collectors.toList()); List<Long> right = allNodesChildList.stream().filter(allNodesChild -> allNodesChild.getType() == 2).map(MemberNode::getMemberId).collect(Collectors.toList()); MallMember parentMember = memberMapper.selectById(parentNode.getMemberId()); parentMember.setChildNodeCnt(parentNode.CHILD.size()); int levelCode = MemberLevelEnum.getLevelCode(parentMember.getLevel()); if (Integer.parseInt(dic.getValue()) >= levelCode) { parentMember.setLevel(dic.getCode()); BigDecimal leftAmount = mallAchieveRecordMapper.selectSumAchieveByMemberIdList(left); BigDecimal rightAmount = mallAchieveRecordMapper.selectSumAchieveByMemberIdList(right); if(leftAmount.compareTo(rightAmount) > 0){ smallAchieve = rightAmount; }else{ smallAchieve = leftAmount; } memberMapper.updateById(parentMember); //更新用户的区域业绩 DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberNode.getMemberId()); dappMemberEntity.setUsdtBalance(smallAchieve); dappMemberEntity.setLeftAchieve(leftAmount); dappMemberEntity.setRightAchieve(rightAmount); dappMemberDao.updateById(dappMemberEntity); log.info("用户:{},leftAchieve :{}, rightAchieve:{}, smallAchieve:{}", dappMemberEntity.getAddress(), leftAmount, rightAmount, smallAchieve); /** * 判断是否符合升级条件 */ String nextLevel = MemberLevelEnum.MEMBER.getNextLevel(dappMemberEntity.getAccountType()); DataDictionaryCustom memberLevelDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( DataDictionaryEnum.V1.getType() , nextLevel); if(ObjectUtil.isNotEmpty(memberLevelDic)){ String value = memberLevelDic.getValue(); cn.hutool.json.JSONObject parseObj = JSONUtil.parseObj(value); BigDecimal smallAchieveDic = new BigDecimal(parseObj.get("smallAchieve").toString()); if(smallAchieve.compareTo(smallAchieveDic) >= 0){ //升级 dappMemberEntity.setAccountType(nextLevel); dappMemberDao.updateById(dappMemberEntity); } } } } } @Override public void memberPerk() { List<DappMemberEntity> dappMemberEntityList = dappMemberDao.selectMemberByActiveStatus(); if(CollUtil.isEmpty(dappMemberEntityList)){ return; } DataDictionaryCustom staticReleaseDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( DataDictionaryEnum.STATIC_RELEASE.getType(), DataDictionaryEnum.STATIC_RELEASE.getCode() ); if(ObjectUtil.isEmpty(staticReleaseDic)){ return; } BigDecimal staticRelease = new BigDecimal(staticReleaseDic.getValue() == null ? "0" : staticReleaseDic.getValue()); if(BigDecimal.ZERO.compareTo(staticRelease) >= 0){ return; } for(DappMemberEntity dappMemberEntity : dappMemberEntityList){ if(1 != dappMemberEntity.getActiveStatus()){ break; } List<MallAchieveRecord> mallAchieveRecords = mallAchieveRecordMapper.selectListByMemberId(dappMemberEntity.getId()); /** * 按照订单、比例生成对应的静态释放 */ for(MallAchieveRecord mallAchieveRecord : mallAchieveRecords){ BigDecimal costAmount = mallAchieveRecord.getCostAmount(); BigDecimal amount = mallAchieveRecord.getAmount(); BigDecimal eachDayPerk = costAmount.multiply(staticRelease).setScale(2,BigDecimal.ROUND_DOWN); /** * 生成一条静态补贴的流水 * 增加账户余额 * 生成减少赠送积分流水 * 减少账户的赠送积分 * 业绩记录减少实际业绩amount * */ } } } /** src/main/java/cc/mrbird/febs/dapp/service/impl/MatrixTreeNodeServiceImpl.java
@@ -7,6 +7,7 @@ import cc.mrbird.febs.dapp.mapper.DappMemberDao; import cc.mrbird.febs.dapp.mapper.MatrixTreeNodeMapper; import cc.mrbird.febs.dapp.service.IMatrixTreeNodeService; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; @@ -30,16 +31,26 @@ MatrixTree instance = MatrixTree.getInstance(); MemberNode node = instance.getNode(memberId); //节点存在则直接返回 if (node != null) { return null; } //未找到节点 if (StrUtil.isNotBlank(mallMember.getRefererId())) { //返回直推上级所在节点 MemberNode parentNode = instance.getNode(mallMember.getRefererId()); MemberNode notWholeNode = null; if (parentNode != null) { Long parentNodeMemberId = parentNode.getMemberId(); MatrixTreeNode matrixTreeNode = matrixTreeNodeMapper.selectByParentNodeAndType(parentNodeMemberId,mallMember.getNodeType()); if(ObjectUtil.isNotEmpty(matrixTreeNode)){ //直推上级的第一代子节点 MemberNode nodeParentChild = instance.getNode(matrixTreeNode.getTreeNode()); notWholeNode = instance.findNotWholeNode(nodeParentChild); }else{ notWholeNode = instance.findNotWholeNode(parentNode); } } else { notWholeNode = instance.findNotWholeNode(); } @@ -47,17 +58,21 @@ MatrixTreeNode treeNode = new MatrixTreeNode(); treeNode.setTreeNode(mallMember.getId()); treeNode.setParentNode(notWholeNode.getMemberId()); treeNode.setType(mallMember.getNodeType()); matrixTreeNodeMapper.insert(treeNode); } else { MatrixTreeNode treeNode = new MatrixTreeNode(); treeNode.setTreeNode(mallMember.getId()); treeNode.setType(0); matrixTreeNodeMapper.insert(treeNode); } MatrixTreeNode matrixTreeNode = matrixTreeNodeMapper.selectByTreeNode(memberId); DappMemberEntity dappMemberEntity = mallMemberMapper.selectById(matrixTreeNode.getParentNode()); node = new MemberNode(); node.setMemberId(memberId); node.setInviteId(mallMember.getInviteId()); node.setRefererId(mallMember.getRefererId()); node.setRefererId(dappMemberEntity.getInviteId()); node.setType(mallMember.getNodeType()); return instance.addNode(node); } } src/main/java/cc/mrbird/febs/job/BnbTransferJob.java
@@ -24,9 +24,18 @@ @ConditionalOnProperty(prefix = "system", name = "quartz-job", havingValue = "true") public class BnbTransferJob{ @Autowired private DappSystemService dappSystemService; /** * 每天按照消费金额的5‰静释放(千分之五的静态释放比例) * (按购买顺序结算,同时有5个订单就有结算记录) * (设置多少,全部按照最新的来释放) */ @Scheduled(cron = "0 0 0 * * ?") public void aKlineJobDay() { dappSystemService.aKlineJobDay(); dappSystemService.memberPerk(); } src/main/resources/mapper/dapp/DappMemberDao.xml
@@ -309,4 +309,8 @@ <select id="selectInviteRight" resultType="cc.mrbird.febs.dapp.entity.DappMemberEntity"> select * from dapp_member where invite_right = #{inviteId} </select> <select id="selectMemberByActiveStatus" resultType="cc.mrbird.febs.dapp.entity.DappMemberEntity"> select * from dapp_member where active_status = 1 </select> </mapper> src/main/resources/mapper/dapp/MallAchieveRecordMapper.xml
@@ -23,9 +23,24 @@ and date_format(achieve_time, '%Y-%m-%d') = date_format(#{date}, '%Y-%m-%d'); </select> <select id="selectSumAchieveByMemberIdList" resultType="java.math.BigDecimal"> select IFNULL(sum(IFNULL(amount,0)),0) from mall_achieve_record where member_id IN <foreach collection = "list" item = "item" separator="," open = "(" close = ")" > #{item} </foreach > </select> <select id="selectListByDate" resultType="cc.mrbird.febs.dapp.entity.MallAchieveRecord"> select * from mall_achieve_record where date_format(achieve_time, '%Y-%m-%d') = date_format(#{date}, '%Y-%m-%d'); </select> <select id="selectListByMemberId" resultType="cc.mrbird.febs.dapp.entity.MallAchieveRecord"> select * from mall_achieve_record where member_id = #{memberId} order by CREATE_TIME asc </select> </mapper> src/main/resources/mapper/dapp/MatrixTreeNodeMapper.xml
@@ -11,4 +11,10 @@ <select id="selectByTreeNode" resultType="cc.mrbird.febs.dapp.entity.MatrixTreeNode"> select * from matrix_tree_node where tree_node=#{treeNode} </select> <select id="selectByParentNodeAndType" resultType="cc.mrbird.febs.dapp.entity.MatrixTreeNode"> select * from matrix_tree_node where tree_node = #{parentNodeMemberId} and type = #{nodeType} </select> </mapper>