租赁系统
This commit is contained in:
197
src/main/java/com/m2pool/lease/task/GpuRequestApiTask.java
Normal file
197
src/main/java/com/m2pool/lease/task/GpuRequestApiTask.java
Normal file
@@ -0,0 +1,197 @@
|
||||
package com.m2pool.lease.task;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.m2pool.lease.constant.BlockInterval;
|
||||
import com.m2pool.lease.entity.LeaseGpuConfig;
|
||||
import com.m2pool.lease.entity.LeaseMiningSoftwareConfig;
|
||||
import com.m2pool.lease.mapper.LeaseGpuConfigMapper;
|
||||
import com.m2pool.lease.mapper.LeaseMiningSoftwareConfigMapper;
|
||||
import com.m2pool.lease.task.info.*;
|
||||
import io.lettuce.core.ScriptOutputType;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description 获取gpu 信息三方api:whattomine.com 定时任务
|
||||
* @Date 2025/12/16 15:38
|
||||
* @Author yyb
|
||||
*/
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class GpuRequestApiTask {
|
||||
|
||||
@Resource
|
||||
private LeaseGpuConfigMapper leaseGpuConfigMapper;
|
||||
|
||||
|
||||
@Resource
|
||||
private LeaseMiningSoftwareConfigMapper leaseMiningSoftwareConfigMapper;
|
||||
|
||||
@Scheduled(cron = "0 0 0/6 * * ? ")
|
||||
//@Scheduled(cron = "0 0/5 * * * ? ")
|
||||
public void gpuInfoTask(){
|
||||
List<GpuInfo> gpuInfos = fetchGpuInfo();
|
||||
List<LeaseGpuConfig> leaseGpuConfigs = convertGpuInfoToLeaseConfig(gpuInfos);
|
||||
List<LeaseMiningSoftwareConfig> leaseMiningSoftwareConfigs = leaseMiningSoftwareConfigMapper.
|
||||
selectList(new LambdaQueryWrapper<>());
|
||||
//选出挖矿软件只支持的算法和币种
|
||||
List<LeaseGpuConfig> leaseGpuConfigs1 = new ArrayList<>();
|
||||
for (LeaseGpuConfig leaseGpuConfig : leaseGpuConfigs) {
|
||||
for (LeaseMiningSoftwareConfig leaseMiningSoftwareConfig : leaseMiningSoftwareConfigs) {
|
||||
if (leaseMiningSoftwareConfig.getAlgorithm().contains(leaseGpuConfig.getAlgorithm())){
|
||||
leaseGpuConfig.setCoin(leaseMiningSoftwareConfig.getCoin());
|
||||
leaseGpuConfigs1.add(leaseGpuConfig);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
List<AlgorithmInfo> coinNetPowers = fetchMiningPower();
|
||||
if (!coinNetPowers.isEmpty()){
|
||||
Map<String, AlgorithmInfo> coinPowerMap = coinNetPowers.stream()
|
||||
.collect(Collectors.toMap(AlgorithmInfo-> AlgorithmInfo.getCoin()+"-"+AlgorithmInfo.getName(), Function.identity()));
|
||||
for (LeaseGpuConfig leaseGpuConfig : leaseGpuConfigs1) {
|
||||
AlgorithmInfo coinPower = coinPowerMap.get(leaseGpuConfig.getCoin()+"-"+leaseGpuConfig.getAlgorithm());
|
||||
BigDecimal monthIncome = calculateMonthIncome(leaseGpuConfig, coinPower);
|
||||
leaseGpuConfig.setMonthIncome(monthIncome);
|
||||
}
|
||||
|
||||
}
|
||||
leaseGpuConfigMapper.insertOrUpdateBatchByEntity(leaseGpuConfigs1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算月收入
|
||||
* @param leaseGpuConfig
|
||||
* @param coinPower
|
||||
* @return
|
||||
*/
|
||||
private static BigDecimal calculateMonthIncome(LeaseGpuConfig leaseGpuConfig, AlgorithmInfo coinPower) {
|
||||
BigDecimal monthIncome = BigDecimal.ZERO;
|
||||
if (coinPower != null){
|
||||
monthIncome = leaseGpuConfig.getHashrate()
|
||||
.divide(coinPower.getHashrate().divide(BigDecimal.valueOf(1000 * 1000), 8, RoundingMode.HALF_UP), 8, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(24 * 60 * 60)
|
||||
.divide(coinPower.getBlockInterval(), 8, RoundingMode.HALF_UP))
|
||||
.multiply(coinPower.getBlockReward()).multiply(BigDecimal.valueOf(30))
|
||||
.multiply(coinPower.getPrice())
|
||||
;
|
||||
}
|
||||
return monthIncome;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 三方api 获取gpu信息
|
||||
* @return
|
||||
*/
|
||||
public List<GpuInfo> fetchGpuInfo() {
|
||||
String url = "https://whattomine.com/api/v1/gpus?api_token=8ea12738081eaa70a37d62364ddfffecc0c96a6047f02b4cc728af7588fcdbd8";
|
||||
String response = HttpRequest.get(url).execute().body();
|
||||
|
||||
// 将JSONUtil.parseArray改为JSON.parseArray
|
||||
JSONArray gpusArray = JSON.parseArray(response);
|
||||
List<GpuInfo> gpuInfoList = new ArrayList<>();
|
||||
|
||||
for (Object obj : gpusArray) {
|
||||
// JSONObject转换方式
|
||||
JSONObject gpuJson = (JSONObject) obj;
|
||||
GpuInfo gpuInfo = new GpuInfo();
|
||||
|
||||
// 设置基本GPU信息
|
||||
gpuInfo.setId(gpuJson.getLong("id"));
|
||||
gpuInfo.setName(gpuJson.getString("name"));
|
||||
gpuInfo.setRelease_date(gpuJson.getString("release_date"));
|
||||
|
||||
// 处理算法信息
|
||||
JSONArray algorithmsArray = gpuJson.getJSONArray("algorithms");
|
||||
List<AlgorithmInfo> algorithmInfos = new ArrayList<>();
|
||||
|
||||
for (Object algoObj : algorithmsArray) {
|
||||
// JSONObject转换方式
|
||||
JSONObject algoJson = (JSONObject) algoObj;
|
||||
AlgorithmInfo algorithmInfo = new AlgorithmInfo();
|
||||
|
||||
algorithmInfo.setName(algoJson.getString("name"));
|
||||
algorithmInfo.setHashrate(algoJson.getBigDecimal("hashrate"));
|
||||
algorithmInfo.setPower(algoJson.getBigDecimal("power"));
|
||||
|
||||
algorithmInfos.add(algorithmInfo);
|
||||
}
|
||||
|
||||
gpuInfo.setAlgorithms(algorithmInfos);
|
||||
gpuInfoList.add(gpuInfo);
|
||||
}
|
||||
|
||||
return gpuInfoList;
|
||||
}
|
||||
|
||||
|
||||
public List<LeaseGpuConfig> convertGpuInfoToLeaseConfig(List<GpuInfo> gpuInfos) {
|
||||
List<LeaseGpuConfig> leaseGpuConfigs = new ArrayList<>();
|
||||
|
||||
for (GpuInfo gpuInfo : gpuInfos) {
|
||||
if (gpuInfo.getAlgorithms() != null) {
|
||||
for (AlgorithmInfo algorithm : gpuInfo.getAlgorithms()) {
|
||||
LeaseGpuConfig config = buildGpuConfig(gpuInfo, algorithm);
|
||||
leaseGpuConfigs.add(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return leaseGpuConfigs;
|
||||
}
|
||||
|
||||
private static LeaseGpuConfig buildGpuConfig(GpuInfo gpuInfo, AlgorithmInfo algorithm) {
|
||||
LeaseGpuConfig config = new LeaseGpuConfig();
|
||||
config.setName(gpuInfo.getName());
|
||||
config.setAlgorithm(algorithm.getName());
|
||||
config.setHashrate(algorithm.getHashrate().divide(BigDecimal.valueOf(1000 * 1000),2, RoundingMode.HALF_UP));
|
||||
config.setPowerDissipation(algorithm.getPower());
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 三方api 获取gpu 对应算法的收益信息
|
||||
* @return
|
||||
*/
|
||||
public static List<AlgorithmInfo> fetchMiningPower() {
|
||||
String url = "https://whattomine.com/api/v1/coins?api_token=8ea12738081eaa70a37d62364ddfffecc0c96a6047f02b4cc728af7588fcdbd8";
|
||||
String response = HttpRequest.get(url).execute().body();
|
||||
JSONArray gpusArray = JSON.parseArray(response);
|
||||
List<AlgorithmInfo> hashRateInfos = new ArrayList<>();
|
||||
for (int i = 0; i < gpusArray.size(); i++) {
|
||||
JSONObject item = gpusArray.getJSONObject(i);
|
||||
AlgorithmInfo info = new AlgorithmInfo();
|
||||
info.setCoin(item.getString("tag"));
|
||||
info.setName(item.getString("algorithm"));
|
||||
info.setHashrate(new BigDecimal(item.getLong("nethash")));
|
||||
info.setBlockReward(BigDecimal.valueOf(item.getDouble("block_reward")));
|
||||
info.setBlockInterval(BigDecimal.valueOf(item.getDouble("block_time")));
|
||||
// 解析exchanges数组并获取第一个对象的price值
|
||||
JSONArray exchanges = item.getJSONArray("exchanges");
|
||||
if (!exchanges.isEmpty()) {
|
||||
JSONObject firstExchange = exchanges.getJSONObject(0);
|
||||
//30日平均币价
|
||||
info.setPrice(BigDecimal.valueOf(firstExchange.getDouble("price30")).multiply(BigDecimal.valueOf(100000)));
|
||||
}
|
||||
hashRateInfos.add(info);
|
||||
}
|
||||
return hashRateInfos;
|
||||
}
|
||||
}
|
||||
1081
src/main/java/com/m2pool/lease/task/OrderAndPayTask.java
Normal file
1081
src/main/java/com/m2pool/lease/task/OrderAndPayTask.java
Normal file
File diff suppressed because it is too large
Load Diff
324
src/main/java/com/m2pool/lease/task/OwnProductTask.java
Normal file
324
src/main/java/com/m2pool/lease/task/OwnProductTask.java
Normal file
@@ -0,0 +1,324 @@
|
||||
package com.m2pool.lease.task;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.m2pool.lease.dto.HourIncomeDto;
|
||||
import com.m2pool.lease.dto.OrderStatusDto;
|
||||
import com.m2pool.lease.entity.*;
|
||||
import com.m2pool.lease.mapper.*;
|
||||
import com.m2pool.lease.mq.message.RabbitmqPoolProxyMessage;
|
||||
import com.m2pool.lease.service.LeaseOrderInfoService;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.rmi.dgc.Lease;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.m2pool.lease.constant.RabbitmqConstant.POOL_PROXY_QUEUE_NAME;
|
||||
|
||||
/**
|
||||
* @Description 后台管理系统 定时任务
|
||||
* @Date 2025/7/15 15:45
|
||||
* @Author yyb
|
||||
*/
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class OwnProductTask {
|
||||
|
||||
@Resource
|
||||
private LeaseUserOwnedProductMapper leaseUserOwnedProductMapper;
|
||||
|
||||
|
||||
@Resource
|
||||
private LeaseProductMachineMapper leaseProductMachineMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseOrderItemMapper leaseOrderItemMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseOrderInfoService leaseOrderInfoService;
|
||||
|
||||
@Resource
|
||||
private LeasePayRecordMessageMapper leasePayRecordMessageMapper;
|
||||
|
||||
@Resource
|
||||
private RabbitTemplate rabbitTemplate;
|
||||
|
||||
private static final int THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors();
|
||||
private static final int BATCH_SIZE = 1000;
|
||||
private final ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
|
||||
/**
|
||||
* 修改已购表租约过期状态为1 已过期 + 机器表状态为0 未售出 + 修改租约到期订单状态为已完成
|
||||
*/
|
||||
@Scheduled(cron = "0 1,5,7 0 * * ? ")
|
||||
//@Scheduled(cron = "0 0/3 * * * ? ")
|
||||
@Transactional
|
||||
public void updateOwnMachineStateTask(){
|
||||
// 获取当天 0 点的 LocalDateTime
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime startOfDay = now.toLocalDate().atStartOfDay();
|
||||
//1. 查询当天失效机器
|
||||
LambdaQueryWrapper<LeaseUserOwnedProduct> wrapper = new LambdaQueryWrapper<LeaseUserOwnedProduct>()
|
||||
.eq(LeaseUserOwnedProduct::getEndTime, startOfDay).eq(LeaseUserOwnedProduct::getStatus, 0);
|
||||
List<LeaseUserOwnedProduct> leaseUserOwnedProducts = leaseUserOwnedProductMapper.selectList(wrapper);
|
||||
|
||||
if (!leaseUserOwnedProducts.isEmpty()){
|
||||
//2.修改商品机器表中 销售状态为 0 未售出
|
||||
List<Long> ids = new ArrayList<>();
|
||||
List<Long> isExpireIds = new ArrayList<>();
|
||||
List<Long> itemIds = new ArrayList<>();
|
||||
for (LeaseUserOwnedProduct leaseUserOwnedProduct : leaseUserOwnedProducts) {
|
||||
ids.add(leaseUserOwnedProduct.getId());
|
||||
isExpireIds.add(leaseUserOwnedProduct.getProductMachineId());
|
||||
itemIds.add(leaseUserOwnedProduct.getOrderItemId());
|
||||
}
|
||||
leaseUserOwnedProductMapper.update(LeaseUserOwnedProduct.builder().status(1).build(),new LambdaUpdateWrapper<LeaseUserOwnedProduct>()
|
||||
.in(LeaseUserOwnedProduct::getId, ids));
|
||||
leaseProductMachineMapper.update(LeaseProductMachine.builder().saleState(0).build(),
|
||||
new LambdaQueryWrapper<LeaseProductMachine>().in(LeaseProductMachine::getId, isExpireIds));
|
||||
leaseOrderItemMapper.update(LeaseOrderItem.builder().status(0).build(),new LambdaQueryWrapper<LeaseOrderItem>().in(LeaseOrderItem::getId, itemIds));
|
||||
//3.订单所有机器已过期,直接修改订单状态为已完成
|
||||
List<Long> orderIds = leaseOrderItemMapper.getOrderIds(itemIds);
|
||||
List<OrderStatusDto> orderInfoStatus = leaseOrderItemMapper.getOrderInfoStatus(orderIds);
|
||||
|
||||
List<LeaseOrderInfo> infoList = new ArrayList<>();
|
||||
orderInfoStatus.forEach(item->{
|
||||
if (item.getOrderInfoStatus() == 8){
|
||||
infoList.add(LeaseOrderInfo.builder().id(item.getOrderId()).status(8).build());
|
||||
}
|
||||
});
|
||||
if (!infoList.isEmpty()){
|
||||
leaseOrderInfoService.saveOrUpdateBatch(infoList);
|
||||
}
|
||||
|
||||
System.out.println("租约过期机器状态修改成功");
|
||||
//3.发送rabbitmq消息给矿池代理删除代理的矿机
|
||||
//sendRabbitmqMessage(leaseUserOwnedProducts);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendRabbitmqMessage( List<LeaseUserOwnedProduct> leaseUserOwnedProducts) {
|
||||
leaseUserOwnedProducts.forEach(item -> {
|
||||
executorService.execute(()->{
|
||||
RabbitmqPoolProxyMessage rabbitmqPoolProxyMessage = RabbitmqPoolProxyMessage.builder()
|
||||
.MethodID(1)
|
||||
.Msg("")
|
||||
.ID(item.getUser() + "-" + item.getMiner())
|
||||
.Address(item.getAddress())
|
||||
.build();
|
||||
try {
|
||||
rabbitTemplate.convertAndSend(POOL_PROXY_QUEUE_NAME, rabbitmqPoolProxyMessage);
|
||||
//同步阻塞等待消息发送成功
|
||||
//boolean b = rabbitTemplate.waitForConfirms(10000);
|
||||
} catch (Exception e) {
|
||||
|
||||
System.err.println("发送失败: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Scheduled(cron = "0 35 0/1 * * ? ")
|
||||
//@Scheduled(cron = "30 0/2 * * * ? ")
|
||||
@DSTransactional
|
||||
public void updateNexaIncomeTask(){
|
||||
List<LeaseUserOwnedProduct> updateList = computeIncome("nexa");
|
||||
//批量修改
|
||||
batchUpdateLeaseUserOwnedProducts(updateList);
|
||||
|
||||
}
|
||||
|
||||
@Scheduled(cron = "10 35 0/1 * * ? ")
|
||||
//@Scheduled(cron = "30 0/2 * * * ? ")
|
||||
@DSTransactional
|
||||
public void updateGrsIncomeTask(){
|
||||
List<LeaseUserOwnedProduct> updateList = computeIncome("grs");
|
||||
//批量修改
|
||||
batchUpdateLeaseUserOwnedProducts(updateList);
|
||||
}
|
||||
|
||||
@Scheduled(cron = "20 35 0/1 * * ? ")
|
||||
//@Scheduled(cron = "30 0/2 * * * ? ")
|
||||
@DSTransactional
|
||||
public void updateRxdIncomeTask(){
|
||||
List<LeaseUserOwnedProduct> updateList = computeIncome("rxd");
|
||||
//批量修改
|
||||
batchUpdateLeaseUserOwnedProducts(updateList);
|
||||
}
|
||||
|
||||
@Scheduled(cron = "30 35 0/1 * * ? ")
|
||||
//@Scheduled(cron = "30 0/2 * * * ? ")
|
||||
@DSTransactional
|
||||
public void updateMonaIncomeTask(){
|
||||
List<LeaseUserOwnedProduct> updateList = computeIncome("mona");
|
||||
//批量修改
|
||||
batchUpdateLeaseUserOwnedProducts(updateList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 计算已购生效机器过去一小时收益
|
||||
* @param coin
|
||||
*/
|
||||
public List<LeaseUserOwnedProduct> computeIncome(String coin){
|
||||
//获取当前时间整点时间
|
||||
LocalDateTime now = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0);
|
||||
//获取当天开始时间
|
||||
//LocalDateTime startOfDay = now.with(LocalTime.MIN);
|
||||
LocalDateTime end = now.minusHours(1);
|
||||
LocalDateTime start = now.minusHours(2);
|
||||
//1. 查询在有效期内的已购机器
|
||||
LambdaQueryWrapper<LeaseUserOwnedProduct> wrapper = new LambdaQueryWrapper<LeaseUserOwnedProduct>()
|
||||
.eq(LeaseUserOwnedProduct::getCoin, coin)
|
||||
.eq(LeaseUserOwnedProduct::getStatus, 0);
|
||||
List<LeaseUserOwnedProduct> leaseUserOwnedProducts = leaseUserOwnedProductMapper.selectList(wrapper);
|
||||
|
||||
//2.获取近一个小时矿机的收益 + 并计算实时收益
|
||||
List<LeaseUserOwnedProduct> updateList = new ArrayList<>();
|
||||
if (!leaseUserOwnedProducts.isEmpty()){
|
||||
List<HourIncomeDto> incomeDtos = leaseUserOwnedProductMapper.getHourIncomeList(leaseUserOwnedProducts,coin, start, end);
|
||||
Map<String, LeaseUserOwnedProduct> collect = leaseUserOwnedProducts.stream()
|
||||
.collect(Collectors.toMap(item-> item.getUser() + "-" + item.getMiner()+ "-" + item.getCoin(),Function.identity()));
|
||||
for (HourIncomeDto hourIncomeDto : incomeDtos) {
|
||||
String key = hourIncomeDto.getUser() + "-" + hourIncomeDto.getMiner()+ "-" + coin;
|
||||
LeaseUserOwnedProduct leaseUserOwnedProduct = collect.get(key) ;
|
||||
leaseUserOwnedProduct.setSettleIncome(hourIncomeDto.getIncome().add(leaseUserOwnedProduct.getSettleIncome()));
|
||||
//leaseUserOwnedProduct.setSettleUsdtIncome(hourIncomeDto.getUsdtIncome().add(leaseUserOwnedProduct.getSettleUsdtIncome()));
|
||||
updateList.add(leaseUserOwnedProduct);
|
||||
}
|
||||
|
||||
}
|
||||
return updateList;
|
||||
}
|
||||
|
||||
|
||||
///**
|
||||
// * 计算已购生效机器过去一小时收益
|
||||
// * @param coin
|
||||
// */
|
||||
//public List<LeaseUserOwnedProduct> computeIncome(String coin){
|
||||
// //获取当前时间整点时间
|
||||
// LocalDateTime now = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0);
|
||||
// //获取当天开始时间
|
||||
// LocalDateTime startOfDay = now.with(LocalTime.MIN);
|
||||
// LocalDateTime end = now.minusHours(1);
|
||||
// LocalDateTime start = now.minusHours(2);
|
||||
// //1. 查询在有效期内的已购机器
|
||||
// LambdaQueryWrapper<LeaseUserOwnedProduct> wrapper = new LambdaQueryWrapper<LeaseUserOwnedProduct>()
|
||||
// .eq(LeaseUserOwnedProduct::getCoin, coin)
|
||||
// .eq(LeaseUserOwnedProduct::getStatus, 0);
|
||||
// List<LeaseUserOwnedProduct> leaseUserOwnedProducts = leaseUserOwnedProductMapper.selectList(wrapper);
|
||||
// System.out.println("个人收益--矿机: " + JSONUtil.toJsonPrettyStr(leaseUserOwnedProducts));
|
||||
// //2.获取近一个小时矿机的收益 + 并计算实时收益
|
||||
// List<LeaseUserOwnedProduct> updateList = new ArrayList<>();
|
||||
// if (!leaseUserOwnedProducts.isEmpty()){
|
||||
// Map<String, LeaseUserOwnedProduct> collect = new HashMap<>();
|
||||
// Set<Long> orderInfoIds = new HashSet<>();
|
||||
// for (LeaseUserOwnedProduct item : leaseUserOwnedProducts) {
|
||||
// collect.put(item.getUser() + "-" + item.getMiner() + "-" + item.getCoin(), item);
|
||||
// orderInfoIds.add(item.getOrderId());
|
||||
// }
|
||||
//
|
||||
// //2.1 查询当天已支付订单
|
||||
// //查询订单详情对应的信息formAddress + fromChain + fromSymbol + toAddress + toChain + toSymbol
|
||||
// List<LeaseOrderItem> leaseOrderItems = leaseOrderItemMapper.getOrderItemByOrderIds(orderInfoIds);
|
||||
// Map<String, LeaseOrderItem> collect1 = leaseOrderItems.stream().collect(Collectors.toMap(item -> item.getUser() + "-" + item.getMiner() + "-" + item.getCoin(), Function.identity()));
|
||||
//
|
||||
// List<HourIncomeDto> incomeDtos = leaseUserOwnedProductMapper.getHourIncomeList(leaseUserOwnedProducts,coin, start, end);
|
||||
// for (HourIncomeDto hourIncomeDto : incomeDtos) {
|
||||
// String key = hourIncomeDto.getUser() + "-" + hourIncomeDto.getMiner()+ "-" + coin;
|
||||
// System.out.println("个人收益--矿机详情: " + key);
|
||||
// LeaseUserOwnedProduct leaseUserOwnedProduct = collect.get(key) ;
|
||||
// LeaseOrderItem leaseOrderItem = collect1.get(key);
|
||||
// System.out.println("个人收益--订单详情: " + JSONUtil.toJsonPrettyStr(leaseOrderItem));
|
||||
// if (leaseOrderItem != null && leaseOrderItem.getStatus() == 1){
|
||||
// BigDecimal coinIncome = hourIncomeDto.getIncome().add(leaseUserOwnedProduct.getCurrentIncome());
|
||||
// BigDecimal usdtIncome = hourIncomeDto.getUsdtIncome().add(leaseUserOwnedProduct.getCurrentUsdtIncome());
|
||||
// //当日待结算收益不为0,把待结算收益加到当前收益中
|
||||
// if (leaseUserOwnedProduct.getSettleIncome().compareTo(BigDecimal.ZERO) > 0){
|
||||
// coinIncome = coinIncome.add(leaseUserOwnedProduct.getSettleIncome());
|
||||
// usdtIncome = usdtIncome.add(leaseUserOwnedProduct.getSettleUsdtIncome());
|
||||
// leaseUserOwnedProduct.setSettleIncome(BigDecimal.ZERO);
|
||||
// leaseUserOwnedProduct.setSettleUsdtIncome(BigDecimal.ZERO);
|
||||
// }
|
||||
// leaseUserOwnedProduct.setCurrentIncome(coinIncome);
|
||||
// leaseUserOwnedProduct.setCurrentUsdtIncome(usdtIncome);
|
||||
//
|
||||
// }else{
|
||||
// leaseUserOwnedProduct.setSettleIncome(hourIncomeDto.getIncome().add(leaseUserOwnedProduct.getSettleIncome()));
|
||||
// leaseUserOwnedProduct.setSettleUsdtIncome(hourIncomeDto.getUsdtIncome().add(leaseUserOwnedProduct.getSettleUsdtIncome()));
|
||||
// }
|
||||
// if (now.equals(startOfDay)){
|
||||
// leaseUserOwnedProduct.setSettleIncome(BigDecimal.ZERO);
|
||||
// leaseUserOwnedProduct.setSettleUsdtIncome(BigDecimal.ZERO) ;
|
||||
// }
|
||||
//
|
||||
// updateList.add(leaseUserOwnedProduct);
|
||||
// }
|
||||
// }
|
||||
// return updateList;
|
||||
//}
|
||||
|
||||
/**
|
||||
* 批量修改已购机器的收益
|
||||
* @param updateList
|
||||
*/
|
||||
public void batchUpdateLeaseUserOwnedProducts(List<LeaseUserOwnedProduct> updateList) {
|
||||
// 用于记录执行过程中的异常
|
||||
AtomicReference<Exception> exceptionRef = new AtomicReference<>();
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < updateList.size(); i += BATCH_SIZE) {
|
||||
int toIndex = Math.min(i + BATCH_SIZE, updateList.size());
|
||||
List<LeaseUserOwnedProduct> subList = updateList.subList(i, toIndex);
|
||||
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
if (!subList.isEmpty()){
|
||||
leaseUserOwnedProductMapper.updateBatchIncome(subList);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exceptionRef.set(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}, executorService);
|
||||
|
||||
futures.add(future);
|
||||
}
|
||||
|
||||
// 等待所有任务完成
|
||||
CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
|
||||
try {
|
||||
allFutures.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
// 如果有异常,将异常信息设置到 exceptionRef 中
|
||||
exceptionRef.set(e);
|
||||
}
|
||||
|
||||
// 如果有异常,抛出异常触发事务回滚
|
||||
if (exceptionRef.get() != null) {
|
||||
throw new RuntimeException("批量更新数据时发生错误", exceptionRef.get());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
116
src/main/java/com/m2pool/lease/task/RealPowerInsetTask.java
Normal file
116
src/main/java/com/m2pool/lease/task/RealPowerInsetTask.java
Normal file
@@ -0,0 +1,116 @@
|
||||
package com.m2pool.lease.task;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.m2pool.lease.dto.ProductMachineDto;
|
||||
import com.m2pool.lease.entity.LeaseProductMachine;
|
||||
import com.m2pool.lease.mapper.LeaseProductMachineMapper;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* @Description 矿机实时算力入库
|
||||
* @Date 2025/11/7 14:16
|
||||
* @Author yyb
|
||||
*/
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class RealPowerInsetTask {
|
||||
|
||||
@Resource
|
||||
private LeaseProductMachineMapper leaseProductMachineMapper;
|
||||
|
||||
private static final int BATCH_SIZE = 1000;
|
||||
private static final int THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors();
|
||||
private final ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
|
||||
public void batchInsert(String coin,List<ProductMachineDto> recentlyFiveMinutesData) {
|
||||
// 用于记录执行过程中的异常
|
||||
AtomicReference<Exception> exceptionRef = new AtomicReference<>();
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < recentlyFiveMinutesData.size(); i += BATCH_SIZE) {
|
||||
int toIndex = Math.min(i + BATCH_SIZE, recentlyFiveMinutesData.size());
|
||||
List<ProductMachineDto> subList = recentlyFiveMinutesData.subList(i, toIndex);
|
||||
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
leaseProductMachineMapper.batchInsertPowers(coin, subList);
|
||||
} catch (Exception e) {
|
||||
exceptionRef.set(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}, executorService);
|
||||
|
||||
futures.add(future);
|
||||
}
|
||||
// 等待所有任务完成
|
||||
CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
|
||||
try {
|
||||
allFutures.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
// 如果有异常,将异常信息设置到 exceptionRef 中
|
||||
exceptionRef.set(e);
|
||||
}
|
||||
|
||||
// 如果有异常,抛出异常触发事务回滚
|
||||
if (exceptionRef.get() != null) {
|
||||
System.out.println("批量插入数据实时算力数据出错"+exceptionRef.get());
|
||||
throw new RuntimeException("批量插入数据实时算力数据出错", exceptionRef.get());
|
||||
}
|
||||
}
|
||||
|
||||
public List<ProductMachineDto> getRealPower(String coin){
|
||||
List<LeaseProductMachine> leaseProductMachines = leaseProductMachineMapper.selectList(new LambdaQueryWrapper<LeaseProductMachine>()
|
||||
.eq(LeaseProductMachine::getDel, false));
|
||||
List<ProductMachineDto> recentlyFiveMinutesData = leaseProductMachineMapper.getRecentlyFiveMinutesData(leaseProductMachines, coin);
|
||||
for (ProductMachineDto recentlyFiveMinutesDatum : recentlyFiveMinutesData) {
|
||||
recentlyFiveMinutesDatum.setComputingPower(recentlyFiveMinutesDatum.getComputingPower()
|
||||
.divide(BigDecimal.valueOf(24 * 60 * 60),2, RoundingMode.HALF_UP));
|
||||
}
|
||||
return recentlyFiveMinutesData;
|
||||
}
|
||||
|
||||
|
||||
@Scheduled(cron = "0 0/5 * * * ? ")
|
||||
@DSTransactional
|
||||
public void nexaRealPowerInset(){
|
||||
List<ProductMachineDto> nexaPower = getRealPower("nexa");
|
||||
batchInsert("nexa",nexaPower);
|
||||
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0/5 * * * ? ")
|
||||
@DSTransactional
|
||||
public void monaRealPowerInset(){
|
||||
List<ProductMachineDto> monaPower = getRealPower("mona");
|
||||
batchInsert("mona",monaPower);
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0/5 * * * ? ")
|
||||
@DSTransactional
|
||||
public void rxdRealPowerInset(){
|
||||
List<ProductMachineDto> rxdPower = getRealPower("mona");
|
||||
batchInsert("rxd",rxdPower);
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0/5 * * * ? ")
|
||||
@DSTransactional
|
||||
public void grsRealPowerInset(){
|
||||
List<ProductMachineDto> rxdPower = getRealPower("grs");
|
||||
batchInsert("grs",rxdPower);
|
||||
}
|
||||
|
||||
}
|
||||
46
src/main/java/com/m2pool/lease/task/info/AlgorithmInfo.java
Normal file
46
src/main/java/com/m2pool/lease/task/info/AlgorithmInfo.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package com.m2pool.lease.task.info;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @Description 算法信息类
|
||||
* @Date 2025/12/16 15:43
|
||||
* @Author yyb
|
||||
*/
|
||||
@Data
|
||||
public class AlgorithmInfo {
|
||||
|
||||
/**
|
||||
* 币种名称
|
||||
*/
|
||||
private String coin;
|
||||
|
||||
/**
|
||||
* 算法名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 挖矿算力
|
||||
*/
|
||||
private BigDecimal hashrate;
|
||||
|
||||
/**
|
||||
* 功耗
|
||||
*/
|
||||
private BigDecimal power;
|
||||
|
||||
/**
|
||||
* 报块间隔
|
||||
*/
|
||||
private BigDecimal blockInterval;
|
||||
|
||||
/**
|
||||
* 报块奖励
|
||||
*/
|
||||
private BigDecimal blockReward;
|
||||
|
||||
private BigDecimal price;
|
||||
}
|
||||
34
src/main/java/com/m2pool/lease/task/info/BlockInfo.java
Normal file
34
src/main/java/com/m2pool/lease/task/info/BlockInfo.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package com.m2pool.lease.task.info;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @Description 算法信息类
|
||||
* @Date 2025/12/16 15:43
|
||||
* @Author yyb
|
||||
*/
|
||||
@Data
|
||||
public class BlockInfo {
|
||||
|
||||
/**
|
||||
* 币种
|
||||
*/
|
||||
private String coin;
|
||||
|
||||
/**
|
||||
* 每日报块数
|
||||
*/
|
||||
private String blocks;
|
||||
|
||||
/**
|
||||
* 报块间隔
|
||||
*/
|
||||
private BigDecimal blockInterval;
|
||||
|
||||
/**
|
||||
* 报块奖励
|
||||
*/
|
||||
private BigDecimal blockReward;
|
||||
}
|
||||
34
src/main/java/com/m2pool/lease/task/info/GpuInfo.java
Normal file
34
src/main/java/com/m2pool/lease/task/info/GpuInfo.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package com.m2pool.lease.task.info;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description gpu 信息类
|
||||
* @Date 2025/12/16 15:42
|
||||
* @Author yyb
|
||||
*/
|
||||
@Data
|
||||
public class GpuInfo {
|
||||
/**
|
||||
* gpu id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* gpu 名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* gpu 发布日期
|
||||
*/
|
||||
private String release_date;
|
||||
|
||||
|
||||
/**
|
||||
* gpu 算法信息
|
||||
*/
|
||||
private List<AlgorithmInfo> algorithms;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.m2pool.lease.task.info;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class MiningRewardInfo {
|
||||
private int id;
|
||||
/**
|
||||
* 币种名
|
||||
*/
|
||||
private String tag;
|
||||
private String name;
|
||||
private String estimated_rewards;
|
||||
private String estimated_rewards24;
|
||||
private String btc_revenue;
|
||||
private String btc_revenue24;
|
||||
private double revenue;
|
||||
private double revenue24;
|
||||
private double profit;
|
||||
private double profit24;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.m2pool.lease.task.info;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @Description 月收益信息
|
||||
* @Date 2025/12/16 15:43
|
||||
* @Author yyb
|
||||
*/
|
||||
@Builder
|
||||
@Data
|
||||
public class MonthIncomeInfo {
|
||||
|
||||
/**
|
||||
* 算法名称
|
||||
*/
|
||||
private String algorithm;
|
||||
|
||||
/**
|
||||
* 功耗
|
||||
*/
|
||||
private BigDecimal power;
|
||||
|
||||
/**
|
||||
* 矿机算力 单位H/S
|
||||
*/
|
||||
private BigDecimal hashrate;
|
||||
}
|
||||
Reference in New Issue
Block a user