前言

  • 在当下区块链相关的应用项目种,一般会有质押奖励、锁仓奖励、节点奖励等等奖励。最为头疼的就是节点奖励。应为他的逻辑太过于复杂。从树状结构计算又需要拆分链路至上往下计算,从下往上统计数据。



bean 对象

@Data
public class UserBean {//用户idString userId;//节点级别String nodeRank;//对应节点的奖励级别比例String newAddP;//父类idString parentId;//理财宝金额BigDecimal allMoney;// 以上为传递参数,以下为计算参数不需要传值//分摊到每一条链路上的投资总额额度BigDecimal avgAllMoney;//该用户链路数int lineNum;}@Data
public class NotPageListBean {String lcLogId;}

接口

public interface JdWardData {//节点奖励-获取所有用户并且与他购买的资产包数据List<UserBean> getUserList(String date);//节点奖励-获取最末端用户数据List<UserBean> getBranchUserList(String date);//获取当前未计算的理财包数据List<Map<String, Object>> getNotPageList(String date);//这次计算完成后,将刚刚未计算的理财包数据记录void insertNotPageList(List<Map<String, Object>> list,String date);//发放奖金到待领取表中,等待转账时间进行发放void insertLogMoeny(List<Map<String,Object>> maps25,List<Map<String,Object>> maps75);}

执行助手类

package com.ruoyi.business.jdreward;import com.ruoyi.business.jdreward.bean.UserBean;
import com.ruoyi.common.enums.ZzTypeEnum;
import com.utils.MyMath;
import com.utils.VerifyUtil;
import com.utils.exceptinos.OutException;import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;/*** 节点奖励逻辑封装*/
public class JdWardHelper {//用户列表List<UserBean> userList;//记录普通用户父类不包含自己Map<String, Object> branchUserMap;//记录从下往上记录节点父类用户 节点大于1的 包括自己Map<String, Object> branchUserMapNode;//记录普通用户父类包含自己Map<String, Object> branchUserMapAll;JdWardTools jdWardTools;JdWardData jdWardData;boolean isDeBug;String date;public JdWardHelper(JdWardData jdWardData, boolean isDeBug, String dateStr) {this.jdWardData = jdWardData;this.isDeBug = isDeBug;this.date = dateStr;initData();}/*** 链路数据*/private Map<String, Object> linkData = new HashMap<>();/*** 链路数据*/private Map<String, Object> linkDataAll = new HashMap<>();public static String getDate(String dateStr) {if (VerifyUtil.isEmpty(dateStr)) {return VerifyUtil.getDate();} else {dateStr=dateStr+" 23:59:59";System.out.println(dateStr);//创建SimpleDateFormat对象实例并定义好转换格式SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
//            System.out.println("把当前时间转换成字符串:" + sdf.format(new Date()));Date date = null;try {// 注意格式需要与上面一致,不然会出现异常date = sdf.parse(dateStr);} catch (ParseException e) {e.printStackTrace();System.out.println("=====================时间格式不正确yyyyMMdd");return VerifyUtil.getDate();
//                throw new OutException("时间格式不正确yyyyMMdd");}String dataFromYMDHMS = VerifyUtil.getDataFromYMDHMS(date);return dataFromYMDHMS;}}public static void main(String[] args) {System.out.println(getDate("20210620"));System.out.println(getDate("20210520"));System.out.println(getDate("20210610"));System.out.println(getDate("20210612"));System.out.println(getDate("2020"));System.out.println(getDate("2024550"));}/*** 初始化数据*/public void initData() {//节点奖励-获取所有用户并且与他购买的资产包数据userList = jdWardData.getUserList(date);//获取需要计算的理财包数据,该数据以在userList allMoney 中合并统计List<Map<String, Object>> notPageList = jdWardData.getNotPageList(date);//计算工具jdWardTools = new JdWardTools(userList);//记录链路数据量不包含自己branchUserMap = new HashMap<>();//记录链路数据量不包含自己节点数据branchUserMapNode = new HashMap<>();//记录链路数据量包含自己branchUserMapAll = new HashMap<>();List<UserBean> branchUserList = jdWardData.getBranchUserList(date);//从末端数据记录链路数据for (UserBean userBean : branchUserList) {//节点用户idString id = userBean.getUserId();String parentId = userBean.getParentId();String parentIds = jdWardTools.getPraentIds(parentId);parentIds = VerifyUtil.endClear(parentIds);//记录普通用户父类不包含自己branchUserMap.put(id, parentIds);//记录从下往上记录节点父类用户 节点大于1的 包括自己branchUserMapNode.put(id, id + "," + jdWardTools.getPraentIdsNode(parentId));//记录普通用户父类包含自己branchUserMapAll.put(id, id + "," + parentIds);}//初始化没个人链路数据,每个用户initLineMumber();//计算节点奖励数据initAward();System.out.println(VerifyUtil.toJson(linkDataAll));insertMoney();if (!isDeBug) {//记录计算完后的理财包数据jdWardData.insertNotPageList(notPageList, date);}}/*** 记录金额*/private void insertMoney() {List<Map<String, Object>> list25 = new ArrayList<>();List<Map<String, Object>> list75 = new ArrayList<>();for (String userId : linkDataAll.keySet()) {String money = linkDataAll.get(userId) + "";System.out.println("userId:" + userId + "____money:" + money);String money25 = MyMath.testToFixed("%s*0.25", 8, money);String money75 = MyMath.testToFixed("%s*0.75", 8, money);Map<String, Object> map25 = new HashMap<>();map25.put("id", UUID.randomUUID().toString());map25.put("lcLogId", "");map25.put("userId", userId);map25.put("cTime", date);map25.put("moneyNum", money25);map25.put("payDate", date);map25.put("moneyType", ZzTypeEnum.DL_25_MONEY.code);map25.put("moneyTypeDes", ZzTypeEnum.DL_25_MONEY.des);list25.add(map25);Map<String, Object> map75 = new HashMap<>();map75.put("id", UUID.randomUUID().toString());map75.put("lcLogId", "");map75.put("userId", userId);map75.put("lcId", "");map75.put("cTime", date);map75.put("payTime", date);map75.put("allNum", money75);map75.put("lcNumber", "");map75.put("moneyType", ZzTypeEnum.DL_75_MONEY.code);map75.put("moneyTypeDes", ZzTypeEnum.DL_75_MONEY.des);list75.add(map75);}if (!isDeBug) {jdWardData.insertLogMoeny(list25,list75);}}/*** 计算奖励* 1.节点数据从下往上算,先算下面的节点收益再往上算节点收益* 2.计算节点收益从上往下去减*/private void initAward() {/*** 所有链路* 便利节点用户* */for (String lineCode : branchUserMapNode.keySet()) {//s链路数据//链路节点的数据包含自己的String lineData = branchUserMapNode.get(lineCode) + "";//1.从下往上顺序String[] split = lineData.split(",");for (int i = 0; i < split.length; i++) {//当前用户String onUserId = split[i];insertAddMoney(lineCode, lineData, onUserId);}}}/*** 从上往下扣除子类的数据** @param lineCode* @param onUserId*/private void insertAddMoney(String lineCode, String lineData, String onUserId) {UserBean userBeanByUserId = jdWardTools.getUserBeanByUserId(userList, onUserId);//用户级别String onNodeRank = userBeanByUserId.getNodeRank();if (VerifyUtil.isEmpty(onNodeRank)) onNodeRank = "0";//当前链路下的平均收益String onWillSy = getWillSy(lineCode, onUserId);String newAddP = userBeanByUserId.getNewAddP();if (VerifyUtil.isEmpty(newAddP)) newAddP = "0";String newAddLinkNewMoney = MyMath.testToFixed("%s*%s", 8, onWillSy, newAddP);//从上往下链路String nextClient = lineData.substring(0, lineData.indexOf(onUserId));String[] split1 = nextClient.split(",");for (int i1 = split1.length - 1; i1 > 0; i1--) {//下一级的用户String nextUserId = split1[i1];UserBean nextUserBeanByUserId = jdWardTools.getUserBeanByUserId(userList, nextUserId);//下一级节点用户节点等级String nextNodeRank = nextUserBeanByUserId.getNodeRank();if (VerifyUtil.isEmpty(nextNodeRank)) nextNodeRank = "0";if (MyMath.test2("%s<=%s", onNodeRank, nextNodeRank)) {String willSy = getWillSy(lineCode, nextUserId);newAddLinkNewMoney = MyMath.testToFixed("%s-%s*%s", 8, newAddLinkNewMoney, willSy, newAddP);break;} else {String linkNewAddItem = getLinkNewAdd(nextUserId, lineCode, "end");newAddLinkNewMoney = MyMath.testToFixed("%s-%s", 8, newAddLinkNewMoney, linkNewAddItem);}}//记录当前链对应的用户数据if (!MyMath.test2("%s==0", newAddLinkNewMoney)) {putLinkNewAdd(onUserId, lineCode, newAddLinkNewMoney, "end");}}/*** 获取支链数据** @param userId* @param zlCode* @param str    是否取原始数据* @return*/private String getLinkNewAdd(String userId, String zlCode, String str) {String s = linkData.get(userId + "_" + zlCode + str) + "";return VerifyUtil.isEmpty(s) ? "0" : s;}/*** 存入数据** @param userId* @param zlCode* @param newAddLinkNewMoney* @param str                是否存原始数*/private void putLinkNewAdd(String userId, String zlCode, String newAddLinkNewMoney, String str) {linkData.put(userId + "_" + zlCode + str, newAddLinkNewMoney);if ("end".equals(str)) {String value = linkDataAll.get(userId) + "";if (VerifyUtil.isEmpty(value)) value = "0";linkDataAll.put(userId, MyMath.test("%s+%s", value, newAddLinkNewMoney));}}/*** 个人* 获取单链路上以下的收益** @param lineCode* @param userId* @return*/private String getWillSy(String lineCode, String userId) {String userIds = branchUserMapAll.get(lineCode) + "";String allMoney = "0";String[] split = userIds.split(",");for (String s : split) {//从下检测到上,遇到当前自己则跳出if (s.equals(userId)) break;UserBean userBeanByUserId = jdWardTools.getUserBeanByUserId(userList, s);BigDecimal avgAllMoney = userBeanByUserId.getAvgAllMoney();String avgAllMoneyStr = "0";if (!VerifyUtil.isEmpty(avgAllMoney)) {avgAllMoneyStr = avgAllMoney.toString();}allMoney = MyMath.testToFixed("%s+%s", 8, allMoney, avgAllMoneyStr);}return allMoney;}/*** 计算所有人的链路数,将总投资金额平台到每一条链路上,计算使用平摊后的链路*/private void initLineMumber() {//计算每个用户有多少条链路for (UserBean userBean : userList) {for (String s : branchUserMapAll.keySet()) {//链路String s1 = branchUserMapAll.get(s) + "";if (s1.contains(userBean.getUserId()))userBean.setLineNum(userBean.getLineNum() + 1);}//计算平摊总投资金额BigDecimal allMoney = userBean.getAllMoney();String allMoneyStr = VerifyUtil.isEmpty(allMoney) ? "0" : allMoney.toString();String avgAllMoney = MyMath.testToFixed("%s/%s", 8, allMoneyStr, userBean.getLineNum() + "");userBean.setAvgAllMoney(new BigDecimal(avgAllMoney));}}}

工具类

package com.ruoyi.business.jdreward;import com.ruoyi.business.jdreward.bean.UserBean;
import com.utils.MyMath;
import com.utils.VerifyUtil;import java.util.List;
import java.util.Map;/*** 公用功能*/
public class JdWardTools {List<UserBean> userList;public JdWardTools(List<UserBean> userList) {this.userList=userList;}/*** 递归获取往上用户id数据* 普通用户** @param parentId* @return*/public String getPraentIds(String parentId) {String parentIds = "";for (UserBean userBean : userList) {if ((parentId + "").equals(userBean.getUserId() + "")) {String userId = userBean.getUserId();String parentId1 = userBean.getParentId();parentIds += (userId + ",");parentIds += getPraentIds(parentId1);}}return parentIds;}/*** 获取所有节点父类用户数据* 节点用户* 从下往上记录节点用户数据** @param parentId* @return*/public String getPraentIdsNode(String parentId) {String parentIds = "";for (UserBean userBean : userList) {if ((parentId + "").equals(userBean.getUserId() + "")) {String userId = userBean.getUserId();String parentId1 = userBean.getParentId();String nodeRank = userBean.getNodeRank();if ((!VerifyUtil.isEmpty(nodeRank)) && MyMath.test2("%s>1", nodeRank))parentIds += (userId + ",");parentIds += getPraentIds(parentId1);}}return parentIds;}/*** 获取用户数据** @param userId* @return*/public UserBean getUserBeanByUserId(List<UserBean> userList, String userId) {for (UserBean userBean : userList) {if (userBean.getUserId().equals(userId))return userBean;}return null;}
}

数据装载

  @Overridepublic List<UserBean> getUserList(String date) {List<UserBean> listUser = new ArrayList<>();// //节点奖励-获取所有用户并且与他购买的资产包数据Map<String, Object> param = new HashMap<>();param.put("baseDate", date);List<Map<String, Object>> list = apiSql.runSqlByParam(param, "jsUser", "userPagerData");list.forEach(map -> {UserBean userBean = new UserBean();userBean.setAllMoney(new BigDecimal(VerifyUtil.isEmpty(map.get("allMoney") + "") ? "0" : map.get("allMoney") + ""));userBean.setUserId(map.get("userId") + "");userBean.setNodeRank(map.get("gradeType") + "");userBean.setNewAddP(map.get("syP") + "");userBean.setParentId(map.get("parentId") + "");listUser.add(userBean);});return listUser;}@Overridepublic List<UserBean> getBranchUserList(String date) {List<UserBean> listUser = new ArrayList<>();Map<String, Object> param = new HashMap<>();param.put("baseDate", date);//初始化节点用户List<Map<String, Object>> branchUserList = apiSql.runSqlByParam(param, "jsUser", "userEndBranch");branchUserList.forEach(map -> {UserBean userBean = new UserBean();userBean.setUserId(map.get("id") + "");userBean.setParentId(map.get("parentId") + "");listUser.add(userBean);});return listUser;}@Overridepublic List<Map<String, Object>> getNotPageList(String date) {Map<String, Object> param = new HashMap<>();param.put("baseDate", date);List<Map<String, Object>> list1 = apiSql.runSqlByParam(param, "lc", "notPageList");return list1;}@Overridepublic void insertNotPageList(List<Map<String, Object>> list, String date) {
//        for (Map<String, Object> map : list) {
//            apiSql.insertTableMapNotKey(new HashMap<String, Object>() {{
//                put("id", UUID.randomUUID().toString());
//                put("cTime", date);
//                put("lcLogId", map.get("id"));
//            }}, "t_node_log");
//        }List<Map<String, Object>> list2 = new ArrayList<>();for (Map<String, Object> stringObjectMap : list) {Map<String, Object> item = new HashMap<>();item.put("id", UUID.randomUUID().toString());item.put("cTime", date);item.put("lcLogId", stringObjectMap.get("id"));list2.add(item);}apiSql.insertListTableMapNotKey(list2, "t_node_log");}@Overridepublic void insertLogMoeny(List<Map<String, Object>> maps25, List<Map<String, Object>> maps75) {apiSql.insertListTableMapNotKey(maps25, "t_lc_package_item");apiSql.insertListTableMapNotKey(maps75, "t_lc_locked");}

区块链项目节点奖励逻辑封装相关推荐

  1. 一、区块链项目的基础架构

    (一)基础架构 1.以太坊 (1)以太坊的概念 Ethereum是一种新的去中心化账本协议,不是一种竞争币.以太坊的理念基因中不仅含有比特币基因,还含有BitTorrent.Java和Freenet的 ...

  2. 柏链道捷首期“PDJ区块链极客马拉松”:靠谱的区块链项目这样来发掘和开发

    4月22日,首期"PDJ区块链极客马拉松"在北京国家会议中心大酒店举办.这是一场区块链精英专属的Hackathon活动,由柏链道捷(PDJ Education)联合CSDN.产业大 ...

  3. 什么是Hyperledger?Linux如何围绕英特尔的区块链项目构建开放平台?

      访问区块链会议并关注区块链新闻时,不可避免地,您会遇到Linux基金会的Hyperledger.理解像比特币.以太坊这样的加密货币还算相对容易的,Hyperledger却不然.但如果你多研究研究, ...

  4. 干货 | 区块链项目估值的逻辑和误区

    温馨提示:全文较长近7500字,建议先收藏再阅读.:) [图1-标题页] 上周六应邀为社区做了一次有关区块链项目商业模式和估值逻辑的讲座,在此将讲义和核心内容汇总整理如下,以飨诸君,交流探讨.共同进步 ...

  5. 密码极客经济学博士揭秘,2020年哪个区块链项目最值期待?

    2020年哪个区块链项目最值期待? 文章来源:密码极客 2019年12月13日,密码极客投资总监江鹏联合密码极客经济学顾问秋叶,一起分享从业以来的投资心路历程.以下是本次分享会节选. 分享嘉宾:秋叶 ...

  6. 全球最牛的4个区块链项目都在这里!

    导读:有人说,目前区块链行业火热,各种项目层出不穷,但真正有实际落地的却寥寥可数,甚至有极端言论说99%的区块链项目最后都将夭折.事实果真如此吗?本文就为您梳理一下目前全球区块链行业最牛的四个项目,通 ...

  7. 区块链惊现山寨万融链 怎样判断一个区块链项目的真假

    区块链惊现山寨万融链 怎样判断一个区块链项目的真假 "区块链实质上是一种集体式记录方式.特别之处在于它别出心裁地采用一组技术,实现了记录结果的真实可信,难以毁坏也无法篡改."张孝荣 ...

  8. 区块链项目的价值评估关键词:数据|筱静观察2019第3期

    从2008年到2018年的第一个十年,区块链技术的发展主要集中在虚拟货币和金融领域,接下来的第二个十年,我们可以预期区块链技术与产业结合的成果,也就是区块链的应用数量会不断增长. 本期筱静观察重点关注 ...

  9. 基于ubuntu16.04部署IBM开源区块链项目-弹珠资产管理(Marbles)

    前言 本教程基本上是对Marbles项目的翻译过程. 如果英文比较好的话,建议根据官方操作说明,一步步进行环境部署.当然你也可以参考本教程在自己的主机上部署该项目. Marbles 介绍 关于 Mar ...

最新文章

  1. android开发工具下载
  2. 排序第一天,回忆关键字
  3. datax参数设置_DataX Web数据增量同步配置说明
  4. Win10本地账户怎么更改为Microsoft账户
  5. EXCEL表格转换成json数据工具
  6. 富文本编辑器KindEditor在前端JS的应用
  7. ceph:如何处理rados --striper上传失败的对象
  8. webpack5+vue3搭建h5项目模板-(一)-基础配置
  9. win7设置环境变量未生效
  10. 5月已更新PS2021m1直装版!Photoshop2021 Mac真正完美适配M1芯片!完美解决2019黑屏闪退卡启动界面等所有问题!
  11. html中用js格式化JSON输出
  12. 梦幻西游服务器维护,《梦幻西游》12月1日维护公告
  13. 前端基础(三)_JavaScript数据类型(基本数据类型、复杂数据类型)
  14. 如何用计算机弹出专业团队音序,《计算机文化基础》模拟试卷(以音序排列)
  15. java 猫 老鼠_Java面试题:猫吃老鼠问题
  16. Adobe Audition CS6如何录电脑放出的声音!
  17. matlab 概率生成函数 求概率,已知某概率密度函数,如何产生一服从该分布的随机数...
  18. 屏幕时间:管理与限制手机各APP使用时间——又名【限制儿童使用手机攻略】——相关主题【救救网瘾少年】
  19. # yyyymmdd 转 yyyy--MM--dd HH:MM:SS #
  20. 2018年蓝桥杯C/C++B组赛——调手表

热门文章

  1. 计算机专业数字逻辑考试题,数字逻辑试卷及答案.doc
  2. windows10重装后锁定其他盘_云骑士新版一键重装win7系统教程
  3. 经典书籍《On Java》
  4. sogou输入法 官方下载 mac版 v3.1.0 最新版
  5. MySQL5.7.17免安装版本配置
  6. find 查询某些文件同时过滤某些文件
  7. 医疗行业AI医学影像与互联网诊疗文件存储设备解决方案
  8. windows下执行.sh脚本
  9. 013 | 民间戏剧类非物质文化遗产的保护与传承 | 大学生创新训练项目申请书 | 极致技术工厂
  10. 发模板消息( 自己项目 )