update 租赁系统业务完成,其他矿池挖矿机器租赁业务开始

This commit is contained in:
yyb
2025-11-19 16:39:25 +08:00
parent 9c0cc31a64
commit a7a2b73d00
16 changed files with 458 additions and 123 deletions

View File

@@ -48,6 +48,22 @@ public enum CoinCharge {
return BigDecimal.ONE;
}
/**
* 根据 chain 和 coin 查找对应的手续费,未找到则返回 1
* @param chain 链名
* @param coin 币种名
* @return 对应的手续费,未找到返回 1
*/
public static BigDecimal getDeductibleAmountByChainAndCoin(String chain, String coin) {
for (CoinCharge charge : CoinCharge.values()) {
if (charge.chain.equals(chain) && charge.coin.equals(coin)) {
return charge.amount.divide(charge.feeRate, 4, RoundingMode.HALF_UP);
}
}
return BigDecimal.ONE;
}
/**
* 根据 chain 和 coin 找到手续费和费率然后比较totalPrice是否小于 费率/手续费
* @param chain 链名
@@ -59,7 +75,7 @@ public enum CoinCharge {
for (CoinCharge charge : CoinCharge.values()) {
if (charge.chain.equals(chain) && charge.coin.equals(coin)) {
BigDecimal feeRate = charge.feeRate;
BigDecimal deductible= feeRate.divide(charge.amount, 4, RoundingMode.HALF_UP);
BigDecimal deductible= charge.amount.divide(feeRate, 4, RoundingMode.HALF_UP);
if(deductible.compareTo(totalPrice) < 0){
fee = BigDecimal.ZERO;
}else{

View File

@@ -48,4 +48,7 @@ public class PayConfigDto {
@ApiModelProperty(value = "起付金额")
private BigDecimal deductibleAmount;
@ApiModelProperty(value = "手续费")
private BigDecimal fee;
}

View File

@@ -0,0 +1,138 @@
package com.m2pool.lease.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* <p>
* 支付消息记录表
* </p>
*
* @author yyb
* @since 2025-09-10
*/
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class LeasePayRecordMessageInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 消息ID
*/
private String queueId;
/**
* 买家充值地址
*/
private String fromAddress;
/**
* 卖家充值地址
*/
private String toAddress;
/**
* 订单id
*/
private String orderId;
/**
* 订单号
*/
private String orderNumber;
/**
* 店铺ID
*/
private Long shopId;
/**
* 用户邮箱
*/
private String userId;
/**
* 理论支付金额(根据商家定价)
*/
private BigDecimal amount;
/**
*真实支付金额
*/
private BigDecimal realAmount;
/**
* 实际应支付金额(根据一天内预估算力和实际算力差值计算得来)
*/
private BigDecimal needAmount;
/**
* 钱包冻结金额
*/
private BigDecimal blockAmount;
/**
* 币种
*/
private String toSymbol;
/**
* 链名称
*/
private String toChain;
/**
* 币种
*/
private String fromSymbol;
/**
* 链名称
*/
private String fromChain;
/**
* 交易hash
*/
private String txHash;
private Long blockHeight;
/**
* 支付时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 0 支付失败 1 支付成功 2 等待校验
*/
private Integer status;
/**
* 逻辑删除字段
*/
private boolean del;
}

View File

@@ -0,0 +1,30 @@
package com.m2pool.lease.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.m2pool.lease.dto.CheckAddressDto;
import com.m2pool.lease.dto.PayRecordMessageDto;
import com.m2pool.lease.dto.RecentlyTransactionDto;
import com.m2pool.lease.dto.TransactionRecordDto;
import com.m2pool.lease.entity.LeasePayRecordMessage;
import com.m2pool.lease.entity.LeasePayRecordMessageInfo;
import com.m2pool.lease.entity.LeaseShopConfig;
import com.m2pool.lease.entity.LeaseUserWalletData;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* <p>
* LeasePayRecordMessageMapper 接口
* </p>
*
* @author yyb
* @since 2025-09-10
*/
@Mapper
public interface LeasePayRecordMessageInfoMapper extends BaseMapper<LeasePayRecordMessageInfo> {
}

View File

@@ -10,6 +10,7 @@ import com.m2pool.lease.exception.PayRechargeException;
import com.m2pool.lease.mapper.*;
import com.m2pool.lease.mq.message.*;
import com.m2pool.lease.service.LeaseOrderItemService;
import com.m2pool.lease.utils.UuidGeneratorUtil;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.messaging.handler.annotation.Payload;
@@ -92,11 +93,15 @@ public class MessageReceiver {
@Transactional(rollbackFor = Exception.class)
public void listenerPayBalanceStatusQueueMessage(@Payload RabbitmqPayAutoReturnMessage payAutoReturnMessage) {
System.out.println("支付消费者"+JSONUtil.toJsonPrettyStr(payAutoReturnMessage));
//查找到数据库对应的支付记录
//查找到数据库对应的支付记录 现在已经每日记录和总记录拆分开了,实际查出来的只会有一条记录
List<LeasePayRecordMessage> leasePayRecordMessagesList = leasePayRecordMessageMapper.selectList(new LambdaQueryWrapper<LeasePayRecordMessage>()
.eq(LeasePayRecordMessage::getQueueId, payAutoReturnMessage.getQueue_id()));
if (leasePayRecordMessagesList.isEmpty()){
return ;
}
//买家钱包
LeasePayRecordMessage payRecordMessage = leasePayRecordMessagesList.get(0);
LeaseUserWalletData buyer = leaseUserWalletDataMapper.selectOne(new LambdaQueryWrapper<LeaseUserWalletData>()
.eq(LeaseUserWalletData::getFromAddress,payRecordMessage.getFromAddress())
.eq(LeaseUserWalletData::getFromChain, payRecordMessage.getFromChain())
@@ -247,6 +252,9 @@ public class MessageReceiver {
.eq(LeaseUserWalletData::getFromAddress, payRechargeReturnMessage.getAddress())
.eq(LeaseUserWalletData::getDel, false)
);
if (leaseUserWalletDataList.isEmpty()){
return;
}
LeaseUserWalletData leaseUserWalletData = null;
for (LeaseUserWalletData item : leaseUserWalletDataList) {
if (item.getFromSymbol().equals(payRechargeReturnMessage.getSymbol())){
@@ -277,6 +285,7 @@ public class MessageReceiver {
if (leasePayRechargeMessage != null){
return;
}
LeasePayRechargeMessage build = LeasePayRechargeMessage.builder()
.queueId(payRechargeReturnMessage.getQueue_id())
.chain(payRechargeReturnMessage.getChain())
@@ -300,7 +309,6 @@ public class MessageReceiver {
}
//处理支付成功消息
if (payRechargeReturnMessage.getStatus() == 1){
System.out.println("余额"+balance);
leaseUserWalletData.setBalance(balance.add(payRechargeReturnMessage.getAmount()));
//使用乐观锁防止余额少加
int update = leaseUserWalletDataMapper.update(leaseUserWalletData, new LambdaQueryWrapper<LeaseUserWalletData>()
@@ -324,7 +332,9 @@ public class MessageReceiver {
System.out.println("提现消费者----"+ JSONUtil.toJsonPrettyStr(payWithdrawReturnMessage));
List<LeasePayWithdrawMessage> leasePayWithdrawMessageList = leasePayWithdrawMessageMapper.selectList(new LambdaQueryWrapper<LeasePayWithdrawMessage>()
.eq(LeasePayWithdrawMessage::getQueueId, payWithdrawReturnMessage.getQueue_id()));
if (leasePayWithdrawMessageList.isEmpty()){
return ;
}
LeasePayWithdrawMessage leasePayWithdrawMessage = leasePayWithdrawMessageList.get(0);
//获取对应的提现钱包
LeaseUserWalletData leaseUserWalletData = leaseUserWalletDataMapper.selectOne(new LambdaQueryWrapper<LeaseUserWalletData>()
@@ -472,76 +482,77 @@ public class MessageReceiver {
}
//测试 开发环境 支付回调测试
@RabbitListener(queues = RabbitmqConstant.PAY_AUTO_QUEUE,containerFactory ="rabbitListenerContainerFactory")
@Transactional(rollbackFor = Exception.class)
public void listenerPayBalanceStatusQueueMessage(@Payload RabbitmqPayAutoMessage payAutoReturnMessage) {
//消费消息
System.out.println("自动支付功能queueId"+payAutoReturnMessage.getQueue_id());
RabbitmqPayAutoReturnMessage rabbitmqPayAutoReturnMessage = RabbitmqPayAutoReturnMessage.builder()
.queue_id(payAutoReturnMessage.getQueue_id())
.from_address(payAutoReturnMessage.getFrom_address())
.to_address(payAutoReturnMessage.getTo_address())
.chain(payAutoReturnMessage.getChain())
.symbol(payAutoReturnMessage.getSymbol())
.fee(payAutoReturnMessage.getFee())
.amount(payAutoReturnMessage.getAmount())
.status(1)
.tx_hash(payAutoReturnMessage.getQueue_id())
.block_height(1000L)
.order_id(payAutoReturnMessage.getOrder_id())
.build();
rabbitTemplate.convertAndSend(RabbitmqConstant.PAY_AUTO_RETURN_QUEUE,rabbitmqPayAutoReturnMessage);
}
//测试 开发环境 充值测试
@RabbitListener(queues = RabbitmqConstant.PAY_RECHARGE_QUEUE,containerFactory ="rabbitListenerContainerFactory")
@Transactional(rollbackFor = Exception.class)
public void listenerPayRechargeQueueMessage(@Payload RabbitmqPayRechargeMessage payAutoReturnMessage) {
//发送充值消息
RabbitmqPayRechargeReturnMessage rabbitmqPayRechargeReturnMessage = RabbitmqPayRechargeReturnMessage.builder()
.queue_id(payAutoReturnMessage.getQueue_id())
.status(2)
.amount(BigDecimal.valueOf(20))
.chain(payAutoReturnMessage.getChain())
.symbol(payAutoReturnMessage.getSymbol())
.address(payAutoReturnMessage.getAddress())
.tx_hash(payAutoReturnMessage.getQueue_id()+"第四笔")
.build();
rabbitTemplate.convertAndSend(RabbitmqConstant.PAY_RECHARGE_RETURN_QUEUE,rabbitmqPayRechargeReturnMessage);
//发送充值消息
RabbitmqPayRechargeReturnMessage rabbitmqPayRechargeReturnMessage1 = RabbitmqPayRechargeReturnMessage.builder()
.queue_id(payAutoReturnMessage.getQueue_id())
.status(1)
.amount(BigDecimal.valueOf(20))
.chain(payAutoReturnMessage.getChain())
.symbol(payAutoReturnMessage.getSymbol())
.address(payAutoReturnMessage.getAddress())
.tx_hash(payAutoReturnMessage.getQueue_id()+"第四笔")
.build();
rabbitTemplate.convertAndSend(RabbitmqConstant.PAY_RECHARGE_RETURN_QUEUE,rabbitmqPayRechargeReturnMessage1);
}
//提现
@RabbitListener(queues = RabbitmqConstant.PAY_WITHDRAW_QUEUE,containerFactory ="rabbitListenerContainerFactory")
@Transactional(rollbackFor = Exception.class)
public void listenerWithdrawQueueMessage(@Payload RabbitmqPayWithdrawMessage payAutoReturnMessage) {
//发送充值消息
RabbitmqPayWithdrawReturnMessage rabbitmqPayRechargeReturnMessage = RabbitmqPayWithdrawReturnMessage.builder()
.queue_id(payAutoReturnMessage.getQueue_id())
.status(1)
.amount(payAutoReturnMessage.getAmount())
.chain(payAutoReturnMessage.getChain())
.symbol(payAutoReturnMessage.getSymbol())
.tx_hash(payAutoReturnMessage.getQueue_id()+"第一笔")
.fee(payAutoReturnMessage.getFee())
.build();
rabbitTemplate.convertAndSend(RabbitmqConstant.PAY_WITHDRAW_RETURN_QUEUE,rabbitmqPayRechargeReturnMessage);
}
////测试 开发环境 支付回调测试
//@RabbitListener(queues = RabbitmqConstant.PAY_AUTO_QUEUE,containerFactory ="rabbitListenerContainerFactory")
//@Transactional(rollbackFor = Exception.class)
//public void listenerPayBalanceStatusQueueMessage(@Payload RabbitmqPayAutoMessage payAutoReturnMessage) {
// //消费消息
// System.out.println("自动支付功能queueId"+payAutoReturnMessage.getQueue_id());
//
// RabbitmqPayAutoReturnMessage rabbitmqPayAutoReturnMessage = RabbitmqPayAutoReturnMessage.builder()
// .queue_id(payAutoReturnMessage.getQueue_id())
// .from_address(payAutoReturnMessage.getFrom_address())
// .to_address(payAutoReturnMessage.getTo_address())
// .chain(payAutoReturnMessage.getChain())
// .symbol(payAutoReturnMessage.getSymbol())
// .fee(payAutoReturnMessage.getFee())
// .amount(payAutoReturnMessage.getAmount())
// .status(1)
// .tx_hash(UuidGeneratorUtil.generateUuidWithoutHyphen())
// .block_height(1000L)
// .order_id(payAutoReturnMessage.getOrder_id())
// .build();
//
// rabbitTemplate.convertAndSend(RabbitmqConstant.PAY_AUTO_RETURN_QUEUE,rabbitmqPayAutoReturnMessage);
//}
//
////测试 开发环境 充值测试
//@RabbitListener(queues = RabbitmqConstant.PAY_RECHARGE_QUEUE,containerFactory ="rabbitListenerContainerFactory")
//@Transactional(rollbackFor = Exception.class)
//public void listenerPayRechargeQueueMessage(@Payload RabbitmqPayRechargeMessage payAutoReturnMessage) {
// String s = UuidGeneratorUtil.generateUuidWithoutHyphen();
// //发送充值消息
// RabbitmqPayRechargeReturnMessage rabbitmqPayRechargeReturnMessage = RabbitmqPayRechargeReturnMessage.builder()
// .queue_id(payAutoReturnMessage.getQueue_id())
// .status(2)
// .amount(BigDecimal.valueOf(20))
// .chain(payAutoReturnMessage.getChain())
// .symbol(payAutoReturnMessage.getSymbol())
// .address(payAutoReturnMessage.getAddress())
// .tx_hash(s)
// .build();
// rabbitTemplate.convertAndSend(RabbitmqConstant.PAY_RECHARGE_RETURN_QUEUE,rabbitmqPayRechargeReturnMessage);
//
//
// //发送充值消息
// RabbitmqPayRechargeReturnMessage rabbitmqPayRechargeReturnMessage1 = RabbitmqPayRechargeReturnMessage.builder()
// .queue_id(payAutoReturnMessage.getQueue_id())
// .status(1)
// .amount(BigDecimal.valueOf(20))
// .chain(payAutoReturnMessage.getChain())
// .symbol(payAutoReturnMessage.getSymbol())
// .address(payAutoReturnMessage.getAddress())
// .tx_hash(s)
// .build();
// rabbitTemplate.convertAndSend(RabbitmqConstant.PAY_RECHARGE_RETURN_QUEUE,rabbitmqPayRechargeReturnMessage1);
//}
//
////提现
//@RabbitListener(queues = RabbitmqConstant.PAY_WITHDRAW_QUEUE,containerFactory ="rabbitListenerContainerFactory")
//@Transactional(rollbackFor = Exception.class)
//public void listenerWithdrawQueueMessage(@Payload RabbitmqPayWithdrawMessage payAutoReturnMessage) {
// //发送充值消息
// RabbitmqPayWithdrawReturnMessage rabbitmqPayRechargeReturnMessage = RabbitmqPayWithdrawReturnMessage.builder()
// .queue_id(payAutoReturnMessage.getQueue_id())
// .status(1)
// .amount(payAutoReturnMessage.getAmount())
// .chain(payAutoReturnMessage.getChain())
// .symbol(payAutoReturnMessage.getSymbol())
// .tx_hash(UuidGeneratorUtil.generateUuidWithoutHyphen())
// .fee(payAutoReturnMessage.getFee())
// .build();
// rabbitTemplate.convertAndSend(RabbitmqConstant.PAY_WITHDRAW_RETURN_QUEUE,rabbitmqPayRechargeReturnMessage);
//}
////测试 开发环境 删除钱包测试

View File

@@ -0,0 +1,16 @@
package com.m2pool.lease.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.m2pool.lease.entity.LeasePayRecordMessage;
import com.m2pool.lease.entity.LeasePayRecordMessageInfo;
/**
* <p>
* service层支付
* </p>
*
* @author yyb
* @since 2025-09-10
*/
public interface LeasePayRecordMessageInfoService extends IService<LeasePayRecordMessageInfo> {
}

View File

@@ -0,0 +1,22 @@
package com.m2pool.lease.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.m2pool.lease.entity.LeasePayRecordMessage;
import com.m2pool.lease.entity.LeasePayRecordMessageInfo;
import com.m2pool.lease.mapper.LeasePayRecordMessageInfoMapper;
import com.m2pool.lease.mapper.LeasePayRecordMessageMapper;
import com.m2pool.lease.service.LeasePayRecordMessageInfoService;
import com.m2pool.lease.service.LeasePayRecordMessageService;
import org.springframework.stereotype.Service;
/**
* <p>
* service层支付
* </p>
*
* @author yyb
* @since 2025-09-10
*/
@Service
public class LeasePayRecordMessageInfoServiceImpl extends ServiceImpl<LeasePayRecordMessageInfoMapper, LeasePayRecordMessageInfo> implements LeasePayRecordMessageInfoService {
}

View File

@@ -66,7 +66,7 @@ public class LeaseProductMachineServiceImpl extends ServiceImpl<LeaseProductMach
String userId = SecurityUtils.getUsername();
//开发环境
userId = "Eudora.law@outlook.com";
//userId = "Eudora.law@outlook.com";
List<UserMinerDto> userMinersList = leaseProductMachineMapper.getUserMinersList(userId,userMinerVo.getCoin());
Map<String, List<UserMinerDto>> collect = userMinersList.stream().collect(Collectors.groupingBy(UserMinerDto::getCoin));
return Result.success(collect);

View File

@@ -1,5 +1,6 @@
package com.m2pool.lease.service.impl;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -158,8 +159,8 @@ public class LeaseProductServiceImpl extends ServiceImpl<LeaseProductMapper, Lea
BigDecimal singleTheoryMachineIncome = BigDecimal.ZERO;
productMachineDto.setAlgorithm(product.getAlgorithm());
// 矿机算力单位转换 + 计算单矿机平均算力(ComputingPower coin_real_power 24小时总算力)
BigDecimal computingPower = PowerUnitUtils.getPower(productMachineDto.getUnit(), productMachineDto.getComputingPower().multiply(BigDecimal.valueOf(1000 * 1000))
.divide(BigDecimal.valueOf(24 * 60 * 60),2,RoundingMode.HALF_UP));
BigDecimal computingPower = PowerUnitUtils.getPower(productMachineDto.getUnit(), productMachineDto.getComputingPower()
.multiply(BigDecimal.valueOf(1000 * 1000)));
//全网算力单位转换
BigDecimal power = PowerUnitUtils.getPower(productMachineDto.getUnit(), mhs.multiply(BigDecimal.valueOf(1000 * 1000)));
//(理论收益 = 矿机算力/全网算力 * 24h /出块间隔秒数 * 单块奖励redis中nexa:reward
@@ -193,6 +194,9 @@ public class LeaseProductServiceImpl extends ServiceImpl<LeaseProductMapper, Lea
productMachineVo.setChain(payConfigDto.getPayChain());
productMachineVo.setCoin(payConfigDto.getPayCoin());
}
BigDecimal power = PowerUnit.getPower(productMachineVo.getUnit()).divide(BigDecimal.valueOf(1000 * 1000),2,RoundingMode.HALF_UP);
productMachineVo.setMaxPower(productMachineVo.getMaxPower().multiply(power));
productMachineVo.setMinPower(productMachineVo.getMinPower().multiply(power));
//算力设置
if (productMachineVo.getMaxPower().compareTo(productMachineVo.getMinPower()) < 0){
productMachineVo.setMaxPower(productMachineVo.getMinPower());
@@ -205,10 +209,11 @@ public class LeaseProductServiceImpl extends ServiceImpl<LeaseProductMapper, Lea
}
//价格设置
if (productMachineVo.getMaxPrice().compareTo(productMachineVo.getMinPrice()) < 0){
BigDecimal power = PowerUnit.getPower(productMachineVo.getUnit()).divide(BigDecimal.valueOf(1000 * 1000),2,RoundingMode.HALF_UP);
productMachineVo.setMaxPrice(productMachineVo.getMinPrice().multiply(power));
productMachineVo.setMinPrice(productMachineVo.getMaxPrice().multiply(power));
productMachineVo.setMaxPrice(productMachineVo.getMinPrice());
productMachineVo.setMinPrice(productMachineVo.getMaxPrice());
}
System.out.println("请求参数"+ JSONUtil.toJsonPrettyStr(productMachineVo));
return productMachineVo;
}

View File

@@ -281,7 +281,8 @@ public class LeaseShoppingCartServiceImpl extends ServiceImpl<LeaseShoppingCartM
Map<Long, List<PayConfigDto>> payConfigMap = shopWalletInfo.stream()
.map(payConfigDto->{
payConfigDto.setDeductibleAmount(CoinCharge.getChargeByChainAndCoin(payConfigDto.getPayChain(), payConfigDto.getPayCoin()));
payConfigDto.setDeductibleAmount(CoinCharge.getDeductibleAmountByChainAndCoin(payConfigDto.getPayChain(), payConfigDto.getPayCoin()));
payConfigDto.setFee(CoinCharge.getChargeByChainAndCoin(payConfigDto.getPayChain(), payConfigDto.getPayCoin()));
return payConfigDto;
})
.collect(Collectors.groupingBy(PayConfigDto::getShopId));

View File

@@ -56,7 +56,7 @@ public class LeaseUserOwnedProductServiceImpl extends ServiceImpl<LeaseUserOwned
.eq(LeaseUserOwnedProduct::getUserId, SecurityUtils.getUsername())
.eq(LeaseUserOwnedProduct::getDel, false)
.orderByAsc(LeaseUserOwnedProduct::getStatus)
.orderByAsc(LeaseUserOwnedProduct::getEndTime));
.orderByDesc(LeaseUserOwnedProduct::getEndTime));
PageInfo<LeaseUserOwnedProduct> pageInfo = new PageInfo<>(leaseUserOwnedProducts);
if (leaseUserOwnedProducts.isEmpty()){
PageResult<UserOwnedProductDto> fail = PageResult.fail(null, "用户未购买商品");

View File

@@ -1,5 +1,6 @@
package com.m2pool.lease.service.impl;
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;

View File

@@ -3,16 +3,14 @@ package com.m2pool.lease.task;
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.common.core.utils.bean.BeanUtils;
import com.m2pool.lease.constant.PowerUnit;
import com.m2pool.lease.dto.*;
import com.m2pool.lease.entity.*;
import com.m2pool.lease.mapper.*;
import com.m2pool.lease.mq.message.RabbitmqDeleteWalletMessage;
import com.m2pool.lease.mq.message.RabbitmqPayAutoMessage;
import com.m2pool.lease.service.LeaseOrderItemService;
import com.m2pool.lease.service.LeasePayRecordMessageService;
import com.m2pool.lease.service.LeaseProductService;
import com.m2pool.lease.service.LeaseUserOwnedProductService;
import com.m2pool.lease.service.*;
import com.m2pool.lease.utils.HashUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Configuration;
@@ -65,19 +63,19 @@ public class OrderAndPayTask {
@Resource
private LeaseAutoAddressMapper leaseAutoAddressMapper;
@Resource
private LeaseProductService leaseProductService;
@Resource
private LeaseShopConfigMapper leaseShopConfigMapper;
@Resource
private LeaseOrderItemService leaseOrderItemService;
@Resource
private LeasePayRecordMessageInfoService leasePayRecordMessageInfoService;
/**
* 检查钱包半年内是否有 支付,充值,提现操作
*/
//@Scheduled(cron = "0 5 1 * * ? ")
@Scheduled(cron = "0 0/1 * * * ? ")
@Scheduled(cron = "0 5 1 * * ? ")
//@Scheduled(cron = "0 0/1 * * * ? ")
@Transactional
public void checkOperator(){
//1.查询lease_auto_address 表 状态为1 已使用 的钱包
@@ -192,6 +190,7 @@ public class OrderAndPayTask {
RabbitmqPayAutoMessage build = RabbitmqPayAutoMessage.builder()
.queue_id(queueId)
.order_id(String.valueOf(orderId))
.shopId(leaseOrderItem.getShopId())
.chain(leaseOrderItem.getChain())
.symbol(leaseOrderItem.getSymbol())
.fee(orderInfo.getFee())
@@ -372,9 +371,9 @@ public class OrderAndPayTask {
//6.根据这些订单发送今天的支付消息到mq
if (!rabbitmqPayAutoMessages.isEmpty()){
List<LeasePayRecordMessage> collect = new ArrayList<>();
List<LeasePayRecordMessageInfo> collect = new ArrayList<>();
for (RabbitmqPayAutoMessage rabbitmqPayAutoMessage : rabbitmqPayAutoMessages) {
collect.add( LeasePayRecordMessage.builder()
collect.add( LeasePayRecordMessageInfo.builder()
.orderId(rabbitmqPayAutoMessage.getOrder_id())
.orderNumber(rabbitmqPayAutoMessage.getQueue_id())
.queueId(rabbitmqPayAutoMessage.getQueue_id())
@@ -392,7 +391,7 @@ public class OrderAndPayTask {
.toSymbol(rabbitmqPayAutoMessage.getSymbol())
.build());
}
leasePayRecordMessageService.saveBatch(collect);
leasePayRecordMessageInfoService.saveBatch(collect);
}
}
@@ -432,41 +431,29 @@ public class OrderAndPayTask {
}
/**
* 订单完成后---发送支付消息到mq 一个买家对应一个卖家
* @param orderIds
*/
public void sendMessageToMq(List<Long> orderIds){
List<LeasePayRecordMessage> leasePayRecordMessages = leasePayRecordMessageMapper.selectList(new LambdaQueryWrapper<LeasePayRecordMessage>()
.in(LeasePayRecordMessage::getOrderId, orderIds));
List<LeaseOrderInfo> leaseOrderInfos = leaseOrderInfoMapper.selectList(new LambdaQueryWrapper<LeaseOrderInfo>()
.select(LeaseOrderInfo::getFee,LeaseOrderInfo::getOrderNumber)
.in(LeaseOrderInfo::getId, orderIds));
Map<String, BigDecimal> feeMap = leaseOrderInfos.stream()
.collect(Collectors.toMap(LeaseOrderInfo::getOrderNumber, LeaseOrderInfo::getFee));
sendMessageToMq(leasePayRecordMessages,feeMap);
}
/**
*订单完成后---发送支付消息到mq 一个买家对应一个卖家
* @param leasePayRecordMessages
* @param feeMap
* @param orderIds
*/
public void sendMessageToMq(List<LeasePayRecordMessage> leasePayRecordMessages,Map<String, BigDecimal> feeMap){
Map<String, List<LeasePayRecordMessage>> collect = leasePayRecordMessages.stream()
.collect(Collectors.groupingBy(LeasePayRecordMessage::getOrderId));
public void sendMessageToMq(List<Long> orderIds){
List<LeasePayRecordMessageInfo> leasePayRecordMessages = leasePayRecordMessageInfoService.list(new LambdaQueryWrapper<LeasePayRecordMessageInfo>()
.in(LeasePayRecordMessageInfo::getOrderId, orderIds));
Map<String, BigDecimal> feeMap = getFee(orderIds);
Map<String, List<LeasePayRecordMessageInfo>> collect = leasePayRecordMessages.stream()
.collect(Collectors.groupingBy(LeasePayRecordMessageInfo::getOrderId));
List<LeasePayRecordMessage> reocrdList = new ArrayList<>();
//遍历按订单id分组后的map
collect.forEach((orderId, payRecordMessagesList) -> {
long timestamp = System.currentTimeMillis()/1000;
LeasePayRecordMessage initForm = payRecordMessagesList.get(0);
LeasePayRecordMessageInfo initForm = payRecordMessagesList.get(0);
RabbitmqPayAutoMessage build = RabbitmqPayAutoMessage.builder()
.queue_id(initForm.getQueueId())
.chain(initForm.getFromChain())
.symbol(initForm.getFromSymbol())
.fee(feeMap.get(orderId))
.from_address(initForm.getFromAddress())
.to_address(initForm.getToAddress())
.fee(feeMap.get(orderId))
.amount(BigDecimal.ZERO)
.blockAmount(BigDecimal.ZERO)
.needAmount(BigDecimal.ZERO)
@@ -474,20 +461,55 @@ public class OrderAndPayTask {
.sign(HashUtils.sha256(timestamp))
.build();
for (LeasePayRecordMessage leasePayRecordMessage : payRecordMessagesList) {
for (LeasePayRecordMessageInfo leasePayRecordMessage : payRecordMessagesList) {
build.setAmount(build.getAmount().add(leasePayRecordMessage.getRealAmount()));
build.setBlockAmount(build.getBlockAmount().add(leasePayRecordMessage.getBlockAmount()));
build.setNeedAmount(build.getNeedAmount().add(leasePayRecordMessage.getNeedAmount()));
}
LeasePayRecordMessage build1 = LeasePayRecordMessage.builder()
.queueId(initForm.getQueueId())
.fromAddress(initForm.getFromAddress())
.toAddress(initForm.getToAddress())
.orderNumber(initForm.getOrderNumber())
.orderId(orderId)
.shopId(initForm.getShopId())
.userId(initForm.getUserId())
.blockAmount(build.getBlockAmount())
.amount(build.getAmount())
.realAmount(build.getAmount())
.needAmount(build.getNeedAmount())
.fromSymbol(initForm.getFromSymbol())
.fromChain(initForm.getFromChain())
.toSymbol(initForm.getToSymbol())
.toChain(initForm.getToChain())
.build();
try {
rabbitTemplate.convertAndSend(PAY_AUTO_QUEUE, build);
}catch (Exception e){
System.out.println("消息发送失败(5分)"+e.getMessage());
//设置状态为消息发送失败
build1.setStatus(4);
System.out.println("消息发送失败"+e.getMessage());
}finally {
reocrdList.add(build1);
}
});
leasePayRecordMessageService.saveBatch(reocrdList);
}
/**
* 获取手续费
* @param orderIds
* @return
*/
private Map<String, BigDecimal> getFee(List< Long> orderIds){
List<LeaseOrderInfo> leaseOrderInfos = leaseOrderInfoMapper.selectList(new LambdaQueryWrapper<LeaseOrderInfo>()
.select(LeaseOrderInfo::getFee,LeaseOrderInfo::getOrderNumber)
.in(LeaseOrderInfo::getId, orderIds));
return leaseOrderInfos.stream()
.collect(Collectors.toMap(LeaseOrderInfo::getOrderNumber, LeaseOrderInfo::getFee));
}
///**
// * 订单完成后---发送支付消息到mq 一个买家对应多个卖家
// * @param orderIds
@@ -546,15 +568,41 @@ public class OrderAndPayTask {
@Scheduled(cron = "0 0 0/1 * * ? ")
@Transactional
public void checkPushFailPayMessage(){
//查找出状态为三 消息发送失败的订单 再次发送支付消息。直到成功为止
//查找出状态为3 校验失败 4 发送消息失败 的消息需要重发
List<LeasePayRecordMessage> list = leasePayRecordMessageService.list(new LambdaQueryWrapper<LeasePayRecordMessage>()
.eq(LeasePayRecordMessage::getStatus, 3)
.ge(LeasePayRecordMessage::getCreateTime, LocalDateTime.now().minusHours(3)));
.ge(LeasePayRecordMessage::getCreateTime, LocalDateTime.now().minusHours(3))
.or().eq(LeasePayRecordMessage::getStatus, 4));
if (list.isEmpty()){
return;
}
List<Long> orderIds = list.stream().map(leasePayRecordMessage-> Long.valueOf(leasePayRecordMessage.getOrderId())).distinct().collect(Collectors.toList());
sendMessageToMq(orderIds);
List<Long> orderIds = list.stream().map(leasePayRecordMessage->Long.valueOf(leasePayRecordMessage.getOrderId())).collect(Collectors.toList());
Map<String, BigDecimal> feeMap = getFee(orderIds);
List<LeasePayRecordMessage> againSendList = new ArrayList<>();
for (LeasePayRecordMessage leasePayRecordMessage : list) {
Long timestamp = System.currentTimeMillis()/1000;
RabbitmqPayAutoMessage build = RabbitmqPayAutoMessage.builder()
.queue_id(leasePayRecordMessage.getQueueId())
.order_id(leasePayRecordMessage.getOrderId())
.chain(leasePayRecordMessage.getFromChain())
.symbol(leasePayRecordMessage.getFromSymbol())
.from_address(leasePayRecordMessage.getFromAddress())
.to_address(leasePayRecordMessage.getToAddress())
.fee(feeMap.get(leasePayRecordMessage.getOrderId()))
.amount(leasePayRecordMessage.getAmount())
.timestamp(timestamp)
.sign(HashUtils.sha256(timestamp))
.build();
try {
rabbitTemplate.convertAndSend(PAY_AUTO_QUEUE, build);
leasePayRecordMessage.setStatus(2);
againSendList.add(leasePayRecordMessage);
}catch (Exception e){
System.out.println("消息发送失败"+e.getMessage());
}
}
leasePayRecordMessageService.updateBatchById(againSendList);
}

View File

@@ -11,6 +11,8 @@ 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;
@@ -73,7 +75,12 @@ public class RealPowerInsetTask {
public List<ProductMachineDto> getRealPower(String coin){
List<LeaseProductMachine> leaseProductMachines = leaseProductMachineMapper.selectList(new LambdaQueryWrapper<LeaseProductMachine>()
.eq(LeaseProductMachine::getDel, false));
return leaseProductMachineMapper.getRecentlyFiveMinutesData(leaseProductMachines, coin);
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;
}

View File

@@ -0,0 +1,27 @@
<?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="com.m2pool.lease.mapper.LeasePayRecordMessageInfoMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.m2pool.lease.entity.LeasePayRecordMessage">
<id column="id" property="id" />
<result column="queue_id" property="queueId" />
<result column="from_address" property="fromAddress" />
<result column="to_address" property="toAddress" />
<result column="amount" property="amount" />
<result column="to_chain" property="toChain" />
<result column="to_symbol" property="toSymbol" />
<result column="from_chain" property="fromChain" />
<result column="from_symbol" property="fromSymbol" />
<result column="order_id" property="orderId" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="status" property="status" />
<result column="del" property="del" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, queue_id, from_address, to_address, amount, `to_chain`, to_symbol,from_chain,from_symbol, order_id,create_time, status, del
</sql>
</mapper>

View File

@@ -38,7 +38,17 @@
(from_address = #{item.fromAddress} AND `from_chain` = #{item.fromChain} AND from_symbol = #{item.fromSymbol})
</foreach>)
AND create_time >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 6 MONTH) AND del = 0
GROUP BY from_address, from_chain, from_symbol;
GROUP BY from_address, from_chain, from_symbol
UNION
SELECT DISTINCT from_address as fromAddress,from_chain as fromChain,from_symbol as fromSymbol, true AS hasOperator
FROM lease_pay_record_message_info
WHERE
(<foreach collection="list" item="item" separator="OR">
(from_address = #{item.fromAddress} AND `from_chain` = #{item.fromChain} AND from_symbol = #{item.fromSymbol})
</foreach>)
AND create_time >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 6 MONTH) AND del = 0
GROUP BY from_address, from_chain, from_symbol
</select>
<select id="balancePayList" resultType="com.m2pool.lease.dto.PayRecordMessageDto">
select