update 修复订单定时任务问题

This commit is contained in:
yyb
2026-01-27 15:54:17 +08:00
parent 1c52a34519
commit 93ebbe4074
8 changed files with 334 additions and 34 deletions

View File

@@ -0,0 +1,73 @@
package com.m2pool.lease.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 买家钱包查询结果DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BuyerWalletQueryDto implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
private Long id;
private Long authId;
/**
* 钱包地址
*/
private String fromAddress;
/**
* 余额
*/
private BigDecimal balance;
/**
* 冻结余额
*/
private BigDecimal blockedBalance;
/**
* 收款地址
*/
private String toAddress;
/**
* 币种
*/
private String fromSymbol;
/**
* 链名称
*/
private String fromChain;
/**
* 收款币种
*/
private String toSymbol;
/**
* 收款链名称
*/
private String toChain;
/**
* 未修改前冻结余额(乐观锁)
*/
private BigDecimal lock;
}

View File

@@ -0,0 +1,54 @@
package com.m2pool.lease.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 卖家钱包查询结果DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SellerWalletQueryDto implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
private Long id;
private String shopId;
/**
* 链名称
*/
private String chain;
/**
* 币种
*/
private String payCoin;
/**
* 支付地址
*/
private String payAddress;
/**
* 余额
*/
private BigDecimal balance;
/**
* 未修改前余额(乐观锁)
*/
private BigDecimal lock;
}

View File

@@ -63,12 +63,17 @@ public interface LeaseShopConfigMapper extends BaseMapper<LeaseShopConfig> {
*/
ShopWalletInfoDto getShopWalletInfo(@Param("shopId") Long shopId,@Param("address") String address,@Param("chain") String chain,@Param("coin") String coin);
/**
* 根据支付记录修改余额
* @param reocrdList 钱包信息
* 根据卖家钱包信息批量更新余额
* @param list 卖家钱包信息列表
* @return 更新数量
*/
int updateBalance(@Param("list") List<LeasePayRecordMessage> reocrdList);
int updateBalanceById(@Param("list") List<SellerWalletQueryDto> list);
/**
* 根据支付记录批量查询卖家钱包配置信息
* @param list 支付记录列表
* @return 卖家钱包配置信息列表
*/
List<SellerWalletQueryDto> selectSellerWalletsByPayRecords(@Param("list") List<LeasePayRecordMessage> list);
}

View File

@@ -1,6 +1,7 @@
package com.m2pool.lease.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.m2pool.lease.dto.BuyerWalletQueryDto;
import com.m2pool.lease.dto.ChainAndCoinDto;
import com.m2pool.lease.dto.UserWalletDataDto;
import com.m2pool.lease.entity.LeasePayRecordMessage;
@@ -51,11 +52,17 @@ public interface LeaseUserWalletDataMapper extends BaseMapper<LeaseUserWalletDat
*/
List<LeaseUserWalletData> selectWalletByChainAndCoinAndUsername(@Param("list") Set<ChainAndCoinDto> chainAndCoinSet,@Param("authId") Long authId);
/**
* 根据支付记录修改余额及冻结余额
* @param reocrdList 钱包信息
* 根据买家钱包信息批量更新余额及冻结余额
* @param list 买家钱包信息列表
* @return 更新数量
*/
int updateBalanceAndBlockBalance(@Param("list") List<LeasePayRecordMessage> reocrdList);
int updateBalanceAndBlockBalanceById(@Param("list") List<BuyerWalletQueryDto> list);
/**
* 根据支付记录批量查询买家钱包信息
* @param list 支付记录列表
* @return 买家钱包信息列表
*/
List<BuyerWalletQueryDto> selectBuyerWalletsByPayRecords(@Param("list") List<LeasePayRecordMessage> list);
}

View File

@@ -759,9 +759,10 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl<LeaseOrderInfoMapper,
return Result.fail("购买的ASIC商品中,存在可售数量不足的商品!");
}
boolean isGpuPass = checkGpuMachine(gpuMachines);
if (!isGpuPass){
return Result.fail("购买的GPU商品中,存在客户端不在线的矿机!");
}
//开发环境
//if (!isGpuPass){
// return Result.fail("购买的GPU商品中,存在客户端不在线的矿机!");
//}
//存储相同链和币种的map集合
Map<String, Map<String, List<OrderInfoVo>>> chainAndCoinMap = new HashMap<>();
Map<Long, LeaseMachinePrice> orderTotalPriceGroupByChainAndCoin = leaseMachinePriceMapper.getOrderTotalPriceGroupByChainAndCoin(orderInfoVoList);
@@ -949,9 +950,10 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl<LeaseOrderInfoMapper,
if (i != machineIds.size()){
throw new OrderException("订单中已有商品售出,请刷新购物车删除已售出商品,重新结算生成订单");
}
if(!checkGpuMachine(gpuMachines)){
throw new OrderException("购买的GPU商品中,存在客户端不在线的矿机!");
}
//开发环境
//if(!checkGpuMachine(gpuMachines)){
// throw new OrderException("购买的GPU商品中,存在客户端不在线的矿机!");
//}
//gpu矿机处理 发送消息
sendMessageToClientAndInsertPurchasedMachine(SecurityUtils.getUserId(),userEmail,gpuMachines,orderMiningInfoDtoList,endMiningMap,machineOrderIdMap,machineOrderItemIdMap);

View File

@@ -230,6 +230,7 @@ public class OrderAndPayTask {
//已支付金额 + 实际待支付金额 + 实际平均算力
item.setAlreadyPayAmount(item.getAlreadyPayAmount().add(item.getPrice().multiply(BigDecimal.valueOf(item.getNumbers()))));
item.setSettlePayRealAmount(item.getSettlePayRealAmount().add(realPayAmount));
System.out.println("yyb-实时算力"+item.getPracticalPower() + "--"+practicalPower);
item.setPracticalPower(item.getPracticalPower().add(practicalPower)
.divide(BigDecimal.valueOf(2), 2, RoundingMode.HALF_UP));
saleIngList.add(item);
@@ -837,13 +838,35 @@ public class OrderAndPayTask {
});
leasePayRecordMessageService.saveBatch(reocrdList);
System.out.println("yyb-订单信息合并前"+JSONUtil.toJsonPrettyStr(reocrdList));
// 合并修改条件相同数据
List<LeasePayRecordMessage> mergedRecordList = mergePayRecordMessages(reocrdList);
System.out.println("yyb-订单信息合并后"+JSONUtil.toJsonPrettyStr(mergedRecordList));
// 合并修改买家条件相同数据(按 fromAddress, fromSymbol, fromChain
List<LeasePayRecordMessage> buyerRecordList = mergePayRecordMessages(reocrdList);
System.out.println("yyb-买家信息合并后"+JSONUtil.toJsonPrettyStr(buyerRecordList));
// 合并修改卖家条件相同数据(按 toAddress, fromSymbol, fromChain
List<LeasePayRecordMessage> sellerRecordList = mergeSellerPayRecordMessages(reocrdList);
System.out.println("yyb-卖家信息合并后"+JSONUtil.toJsonPrettyStr(sellerRecordList));
//订单详情结算待结算金额
leaseOrderItemMapper.updateSettleAmount(mergedRecordList);
int buyerUpdate = leaseUserWalletDataMapper.updateBalanceAndBlockBalance(mergedRecordList);
int sellerUpdate = leaseShopConfigMapper.updateBalance(mergedRecordList);
leaseOrderItemMapper.updateSettleAmount(buyerRecordList);
//批量查询买家钱包信息
List<BuyerWalletQueryDto> buyerWallets = leaseUserWalletDataMapper.selectBuyerWalletsByPayRecords(buyerRecordList);
//批量查询卖家钱包配置信息
List<SellerWalletQueryDto> sellerWallets = leaseShopConfigMapper.selectSellerWalletsByPayRecords(sellerRecordList);
//根据查询到的钱包信息,构建更新记录
List<BuyerWalletQueryDto> buyerUpdateRecords = updateBuyerRecordAmounts(buyerRecordList, buyerWallets);
List<SellerWalletQueryDto> sellerUpdateRecords = updateSellerRecordAmounts(sellerRecordList, sellerWallets);
System.out.println("yyb-买家钱包查询结果"+JSONUtil.toJsonPrettyStr(buyerWallets));
System.out.println("yyb-卖家钱包查询结果"+JSONUtil.toJsonPrettyStr(sellerWallets));
System.out.println("yyb-买家最终更新记录"+JSONUtil.toJsonPrettyStr(buyerUpdateRecords));
System.out.println("yyb-卖家最终更新记录"+JSONUtil.toJsonPrettyStr(sellerUpdateRecords));
//修改买家和卖家账户余额
int buyerUpdate = leaseUserWalletDataMapper.updateBalanceAndBlockBalanceById(buyerUpdateRecords);
int sellerUpdate = leaseShopConfigMapper.updateBalanceById(sellerUpdateRecords);
if (buyerUpdate > 0 || sellerUpdate > 0){
for (LeasePayRecordMessage item : reocrdList) {
recordLog(item);
@@ -851,6 +874,90 @@ public class OrderAndPayTask {
}
}
/**
* 合并相同卖家条件的支付记录消息(按 toAddress, fromSymbol, fromChain
* @param records 支付记录消息列表
* @return 合并后的支付记录消息列表
*/
private List<LeasePayRecordMessage> mergeSellerPayRecordMessages(List<LeasePayRecordMessage> records) {
if (records == null || records.isEmpty()) {
return new ArrayList<>();
}
return new ArrayList<>(records.stream()
.collect(Collectors.groupingBy(
r -> r.getToAddress() + "_" + r.getFromSymbol() + "_" + r.getFromChain(),
Collectors.collectingAndThen(
Collectors.toList(),
list -> {
LeasePayRecordMessage merged = list.get(0);
BigDecimal totalRealAmount = list.stream()
.map(r -> r.getRealAmount() != null ? r.getRealAmount() : BigDecimal.ZERO)
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalReceivedAmount = list.stream()
.map(r -> r.getReceivedAmount() != null ? r.getReceivedAmount() : BigDecimal.ZERO)
.reduce(BigDecimal.ZERO, BigDecimal::add);
merged.setRealAmount(totalRealAmount);
merged.setReceivedAmount(totalReceivedAmount);
return merged;
}
)
))
.values());
}
/**
* 根据查询到的买家钱包信息,更新余额并返回
* @param buyerRecords 买家记录列表
* @param buyerWallets 买家钱包列表
* @return 更新后的买家钱包列表
*/
private List<BuyerWalletQueryDto> updateBuyerRecordAmounts(List<LeasePayRecordMessage> buyerRecords, List<BuyerWalletQueryDto> buyerWallets) {
Map<String, LeasePayRecordMessage> recordMap = buyerRecords.stream()
.collect(Collectors.toMap(
record -> record.getFromAddress() + "_" + record.getFromSymbol() + "_" + record.getFromChain(),
Function.identity()
));
for (BuyerWalletQueryDto wallet : buyerWallets) {
String key = wallet.getFromAddress() + "_" + wallet.getFromSymbol() + "_" + wallet.getFromChain();
LeasePayRecordMessage record = recordMap.get(key);
if (record != null) {
// 修改钱包的余额和冻结余额
wallet.setBalance(wallet.getBalance().subtract(record.getRealAmount()));
wallet.setBlockedBalance(wallet.getBlockedBalance().subtract(record.getBlockAmount()));
}
}
return buyerWallets;
}
/**
* 根据查询到的卖家钱包信息,更新余额并返回
* @param sellerRecords 卖家记录列表
* @param sellerWallets 卖家钱包列表
* @return 更新后的卖家钱包列表
*/
private List<SellerWalletQueryDto> updateSellerRecordAmounts(List<LeasePayRecordMessage> sellerRecords, List<SellerWalletQueryDto> sellerWallets) {
Map<String, LeasePayRecordMessage> recordMap = sellerRecords.stream()
.collect(Collectors.toMap(
record -> record.getToAddress() + "_" + record.getFromSymbol() + "_" + record.getFromChain(),
Function.identity()
));
for (SellerWalletQueryDto wallet : sellerWallets) {
String key = wallet.getPayAddress() + "_" + wallet.getPayCoin() + "_" + wallet.getChain();
LeasePayRecordMessage record = recordMap.get(key);
if (record != null) {
// 修改钱包的余额
wallet.setBalance(wallet.getBalance().add(record.getReceivedAmount()));
}
}
return sellerWallets;
}
/**
* 记录日志
* @param item

View File

@@ -89,21 +89,45 @@
shop_id = #{shopId} AND pay_address = #{address} AND pay_coin = #{coin} AND chain = #{chain} AND del = 0
</select>
<update id="updateBalance">
<update id="updateBalanceById">
UPDATE lease_shop_config
SET balance = CASE
<foreach collection="list" item="item">
WHEN pay_address = #{item.toAddress} AND pay_coin = #{item.fromSymbol} AND chain = #{item.fromChain} AND del = false
THEN balance + #{item.receivedAmount}
WHEN id = #{item.id}
THEN #{item.balance}
</foreach>
ELSE balance
END
WHERE (pay_address,pay_coin,chain) IN(
WHERE id IN(
<foreach collection="list" item="item" separator=",">
(#{item.toAddress}, #{item.fromSymbol}, #{item.fromChain})
#{item.id}
</foreach>
) AND del = false
AND balance = CASE
<foreach collection="list" item="item">
WHEN id = #{item.id}
THEN #{item.lock}
</foreach>
ELSE balance
END
</update>
<select id="selectSellerWalletsByPayRecords" resultType="com.m2pool.lease.dto.SellerWalletQueryDto">
SELECT
id,
shop_id as shopId,
chain,
pay_coin as payCoin,
pay_address as payAddress,
balance,
balance as `lock`
FROM lease_shop_config
WHERE del = 0
AND (pay_address, pay_coin, chain) IN (
<foreach collection="list" item="item" separator=",">
(#{item.toAddress}, #{item.fromSymbol}, #{item.fromChain})
</foreach>
)
</select>
</mapper>

View File

@@ -106,29 +106,57 @@
)
</select>
<select id="selectBuyerWalletsByPayRecords" resultType="com.m2pool.lease.dto.BuyerWalletQueryDto">
SELECT
id,
auth_id as authId,
from_address as fromAddress,
balance,
blocked_balance as blockedBalance,
to_address as toAddress,
from_symbol as fromSymbol,
from_chain as fromChain,
to_symbol as toSymbol,
to_chain as toChain,
blocked_balance as `lock`
FROM lease_user_wallet_data
WHERE del = 0
AND (from_address, from_symbol, from_chain) IN (
<foreach collection="list" item="item" separator=",">
(#{item.fromAddress}, #{item.fromSymbol}, #{item.fromChain})
</foreach>
)
</select>
<update id="updateBalanceAndBlockBalance">
<update id="updateBalanceAndBlockBalanceById">
UPDATE lease_user_wallet_data
SET balance = CASE
<foreach collection="list" item="item">
WHEN from_address = #{item.fromAddress} AND from_symbol = #{item.fromSymbol} AND from_chain = #{item.fromChain} AND del = false
THEN balance - #{item.realAmount}
WHEN id = #{item.id}
THEN #{item.balance}
</foreach>
ELSE balance
END,
blocked_balance = CASE
<foreach collection="list" item="item">
WHEN from_address = #{item.fromAddress} AND from_symbol = #{item.fromSymbol} AND from_chain = #{item.fromChain} AND del = false
THEN blocked_balance - #{item.blockAmount}
WHEN id = #{item.id}
THEN #{item.blockedBalance}
</foreach>
ELSE blocked_balance
END
WHERE (from_address, from_symbol, from_chain) IN (
WHERE id IN (
<foreach collection="list" item="item" separator=",">
(#{item.fromAddress}, #{item.fromSymbol}, #{item.fromChain})
#{item.id}
</foreach>
)
AND del = false
AND blocked_balance = CASE
<foreach collection="list" item="item">
WHEN id = #{item.id}
THEN #{item.lock}
</foreach>
ELSE blocked_balance
END
</update>
</mapper>