pom.xml
@@ -45,6 +45,11 @@ </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> src/main/java/cc/mrbird/febs/dapp/controller/DappUserController.java
@@ -66,7 +66,7 @@ @RequiresPermissions("admin:simulate") @PostMapping(value = "/simulateData") @ControllerEndpoint(operation = "模拟数据生成", exceptionMessage = "模拟数据生成失败") @ControllerEndpoint(operation = "生成虚拟收益", exceptionMessage = "生成虚拟收益失败") public FebsResponse simulateData(@Valid SimulateDataDto simulateDataDto) { String batchNo = dappSimulateDataService.generateSimulateData(simulateDataDto); return new FebsResponse().success().data(batchNo); src/main/java/cc/mrbird/febs/dapp/dto/SimulateDataDto.java
@@ -9,6 +9,9 @@ @Data public class SimulateDataDto { @NotBlank(message = "不能唯恐") private String address; @NotNull(message = "不能为空") private BigDecimal totalOutput; src/main/java/cc/mrbird/febs/dapp/entity/DappReturnRatioEntity.java
New file @@ -0,0 +1,26 @@ package cc.mrbird.febs.dapp.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.math.BigDecimal; /** * @author wzy * @date 2022-03-28 **/ @Data @TableName("dapp_return_ratio") public class DappReturnRatioEntity { @TableId(value = "id",type = IdType.AUTO) private Long id; private BigDecimal minValue; private BigDecimal maxValue; private BigDecimal ratio; } src/main/java/cc/mrbird/febs/dapp/entity/DappSimulateDataEntity.java
@@ -23,4 +23,6 @@ private String batchNo; private Date createTime; private String address; } src/main/java/cc/mrbird/febs/dapp/mapper/DappFundFlowDao.java
@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Param; import java.util.Date; import java.util.List; public interface DappFundFlowDao extends BaseMapper<DappFundFlowEntity> { @@ -13,4 +14,6 @@ IPage<DappFundFlowEntity> selectInPage(Page<DappFundFlowEntity> page, @Param("record") DappFundFlowEntity dappFundFlowEntity); List<DappFundFlowEntity> selectListForMemberAndDay(@Param("memberId") Long memberId, @Param("type") int type); DappFundFlowEntity selectMineFundFlowByMemberIdAndTime(@Param("time") Long memberId, @Param("time") Date time); } src/main/java/cc/mrbird/febs/dapp/mapper/DappMemberDao.java
@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Param; import java.util.List; /** * @author wzy * @date 2022-03-17 @@ -17,4 +19,6 @@ DappMemberEntity selectMemberInfoByInviteId(@Param("inviteId") String inviteId); IPage<DappMemberEntity> selectInPage(@Param("record") DappMemberEntity member, Page<DappMemberEntity> page); List<DappMemberEntity> selectAllMemberForInCome(); } src/main/java/cc/mrbird/febs/dapp/mapper/DappReturnRatioDao.java
New file @@ -0,0 +1,7 @@ package cc.mrbird.febs.dapp.mapper; import cc.mrbird.febs.dapp.entity.DappReturnRatioEntity; import com.baomidou.mybatisplus.core.mapper.BaseMapper; public interface DappReturnRatioDao extends BaseMapper<DappReturnRatioEntity> { } src/main/java/cc/mrbird/febs/dapp/service/impl/DappSimulateServiceImpl.java
@@ -37,6 +37,10 @@ @Override public String generateSimulateData(SimulateDataDto simulateDataDto) { if (!simulateDataDto.getAddress().startsWith("T") && simulateDataDto.getAddress().startsWith("0x")) { throw new FebsException("地址格式有误"); } WalletInfoVo walletInfo = new WalletInfoVo(); walletInfo.setTotalMine(simulateDataDto.getTotalOutput()); walletInfo.setAvailableMine(simulateDataDto.getRemainOutput()); @@ -147,6 +151,7 @@ simulateData.setUserId(currentUser.getUserId()); simulateData.setData(JSONObject.toJSONString(simulateDataVo)); simulateData.setBatchNo(RandomUtil.randomString(32)); simulateData.setAddress(simulateDataDto.getAddress()); dappSimulateDataDao.insert(simulateData); return simulateData.getBatchNo(); } @@ -158,6 +163,8 @@ throw new FebsException("数据错误"); } return JSONObject.parseObject(data.getData(), SimulateDataVo.class); SimulateDataVo simulateDataVo = JSONObject.parseObject(data.getData(), SimulateDataVo.class); simulateDataVo.setAddress(simulateDataVo.getAddress()); return simulateDataVo; } } src/main/java/cc/mrbird/febs/dapp/vo/SimulateDataVo.java
@@ -12,6 +12,8 @@ @Data public class SimulateDataVo { private String address; private WalletInfoVo walletInfoVo; private List<DappFundFlowEntity> changes; src/main/java/cc/mrbird/febs/job/MineProfitJob.java
New file @@ -0,0 +1,93 @@ package cc.mrbird.febs.job; import cc.mrbird.febs.common.contants.AppContants; import cc.mrbird.febs.common.utils.RedisUtils; import cc.mrbird.febs.dapp.chain.ChainService; import cc.mrbird.febs.dapp.entity.*; import cc.mrbird.febs.dapp.mapper.*; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import javax.annotation.PostConstruct; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; /** * @author wzy * @date 2022-03-28 **/ @Slf4j @Component public class MineProfitJob { @Autowired private DappMemberDao dappMemberDao; @Autowired private DappReturnRatioDao dappReturnRatioDao; @Autowired private DappFundFlowDao dappFundFlowDao; @Autowired private DappAccountMoneyChangeDao dappAccountMoneyChangeDao; @Autowired private DappWalletMineDao dappWalletMineDao; @Autowired private RedisUtils redisUtils; @Scheduled(cron = "0 0 1 * * ? ") @Transactional(rollbackFor = Exception.class) public void start() { List<DappMemberEntity> members = dappMemberDao.selectAllMemberForInCome(); if (CollUtil.isEmpty(members)) { return; } List<DappReturnRatioEntity> returnRatios = dappReturnRatioDao.selectList(null); if (CollUtil.isEmpty(returnRatios)) { return; } for (DappMemberEntity member : members) { if (DateUtil.between(member.getCreateTime(), new Date(), DateUnit.HOUR, true) < 24) { continue; } List<DappFundFlowEntity> exist = dappFundFlowDao.selectListForMemberAndDay(member.getId(), 3); if (CollUtil.isNotEmpty(exist)) { continue; } BigDecimal balance = ChainService.INSTANCE.balanceOf(member.getAddress()); DappWalletMineEntity walletMine = dappWalletMineDao.selectByMemberId(member.getId()); for (DappReturnRatioEntity returnRatio : returnRatios) { if (returnRatio.getMinValue().compareTo(balance) < 1 && returnRatio.getMaxValue().compareTo(balance) > -1) { BigDecimal income = balance.multiply(returnRatio.getRatio()); member.setBalance(balance); dappMemberDao.updateById(member); BigDecimal ethNewPrice = (BigDecimal) redisUtils.get(AppContants.REDIS_KEY_ETH_NEW_PRICE); BigDecimal ethIncome = income.divide(ethNewPrice, 8, RoundingMode.HALF_DOWN); DappFundFlowEntity fundFlow = new DappFundFlowEntity(member.getId(), ethIncome, 3, null, null); dappFundFlowDao.insert(fundFlow); DappAccountMoneyChangeEntity accountMoneyChange = new DappAccountMoneyChangeEntity(member.getId(), walletMine.getAvailableAmount(), ethIncome, walletMine.getAvailableAmount().add(ethIncome), "收益:" + ethIncome, 3); dappAccountMoneyChangeDao.insert(accountMoneyChange); walletMine.setAvailableAmount(walletMine.getAvailableAmount().add(ethIncome)); walletMine.setTotalAmount(walletMine.getTotalAmount().add(ethIncome)); dappWalletMineDao.updateById(walletMine); break; } } } } } src/main/resources/mapper/dapp/DappFundFlowDao.xml
@@ -27,4 +27,5 @@ where member_id=#{memberId} and date_format(create_time, '%Y-%m-%d') = date_format(now(), '%Y-%m-%d') and type=#{type} and status!=3 </select> </mapper> src/main/resources/mapper/dapp/DappMemberDao.xml
@@ -31,4 +31,9 @@ </where> order by create_time desc </select> <select id="selectAllMemberForInCome" resultType="cc.mrbird.febs.dapp.entity.DappMemberEntity"> select * from dapp_member where account_status=1 </select> </mapper> src/main/resources/mapper/dapp/DappReturnRatioDao.xml
New file @@ -0,0 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cc.mrbird.febs.dapp.mapper.DappReturnRatioDao"> </mapper> src/main/resources/templates/febs/views/dapp/simulate-data.html
@@ -18,6 +18,10 @@ <div class="layui-fluid" id="dapp-simulate-data"> <form class="layui-form" action="" lay-filter="dapp-simulate-data-form"> <div class="layui-form-item"> <label class="layui-form-label febs-form-item-require">会员账号:</label> <div class="layui-input-block"> <input type="text" name="address" autocomplete="off" lay-verify="required" class="layui-input" value="1"> </div> <label class="layui-form-label febs-form-item-require">总产量:</label> <div class="layui-input-block"> <input type="text" name="totalOutput" autocomplete="off" lay-verify="required|number" class="layui-input" value="1"> @@ -48,21 +52,24 @@ <textarea name="change" id="change" lay-verify="required" class="layui-textarea"></textarea> </br> <blockquote class="layui-elem-quote layui-text"> 数据格式:'时间,数量,状态',状态默认为1 1、每条记录使用(;)分开。 2、数据格式:'时间,数量,状态',状态: '成功-1,失败-0' </blockquote> </div> <div class="layui-tab-item"> <textarea name="withdraw" id="withdraw" lay-verify="required" class="layui-textarea"></textarea> </br> <blockquote class="layui-elem-quote layui-text"> 数据格式:'时间,数量,状态',状态默认为'1-申请中,2-提现成功,3-提现失败' 1、每条记录使用(;)分开。 2、数据格式:'时间,数量,状态',状态: '1-申请中,2-提现成功,3-提现失败' </blockquote> </div> <div class="layui-tab-item"> <textarea name="mine" id="mine" lay-verify="required" class="layui-textarea"></textarea> </br> <blockquote class="layui-elem-quote layui-text"> 数据格式:'时间,类型,输出',类型默认为1 1、每条记录使用(;)分开。 2、数据格式:'时间,类型,输出',类型默认为1 </blockquote> </div> </div> src/main/resources/templates/febs/views/dapp/user.html
@@ -140,7 +140,7 @@ } } if (name === 'simulate') { febs.modal.open('生成模拟数据', 'dappView/admin/simulate', { febs.modal.open('生成虚拟收益', 'dappView/admin/simulate', { btn: ['提交', '重置'], area: $(window).width() <= 750 ? '95%' : '50%', offset: '30px', @@ -168,7 +168,7 @@ perms: 'admin:reset' }, { name: 'simulate', title: '模拟数据', title: '生成虚拟收益', perms: 'admin:simulate' }] }); src/test/java/cc/mrbird/febs/JunitTest.java
New file @@ -0,0 +1,22 @@ package cc.mrbird.febs; import cc.mrbird.febs.job.MineProfitJob; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; /** * @author wzy * @date 2022-03-28 **/ @SpringBootTest public class JunitTest { @Autowired private MineProfitJob mineProfitJob; @Test public void incomeTest() { mineProfitJob.start(); } }