package cc.mrbird.febs.mall.chain.trcCoin.quartz;
|
|
import cc.mrbird.febs.common.enumerates.RunVipDataDictionaryEnum;
|
import cc.mrbird.febs.common.enumerates.YesOrNoEnum;
|
import cc.mrbird.febs.common.utils.AppContants;
|
import cc.mrbird.febs.common.utils.RedisUtils;
|
import cc.mrbird.febs.mall.chain.trcCoin.OkHttpUtil2;
|
import cc.mrbird.febs.mall.chain.trcCoin.OklinkDataPageDetailModel;
|
import cc.mrbird.febs.mall.chain.trcCoin.OklinkModel;
|
import cc.mrbird.febs.mall.entity.MallCharge;
|
import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper;
|
import cc.mrbird.febs.mall.mapper.MallChargeMapper;
|
import cc.mrbird.febs.rabbit.producter.AgentProducer;
|
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.util.StrUtil;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Component;
|
|
import javax.annotation.Resource;
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.nio.charset.StandardCharsets;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
@Slf4j
|
@Component
|
@ConditionalOnProperty(prefix = "chain", name = "trc", havingValue = "true")
|
public class ChainTrcListenerJob {
|
|
@Resource
|
private DataDictionaryCustomMapper dataDictionaryCustomMapper;
|
|
@Resource
|
private MallChargeMapper mallChargeMapper;
|
@Resource
|
private AgentProducer agentProducer;
|
@Resource
|
private RedisUtils redisUtils;
|
|
/**
|
* 五分钟 毫秒
|
*/
|
private final static long TIME_INTERVAL_1HOUR = 300000*12;
|
|
private final static String TRC20_TRANSFER_API = "https://www.oklink.com/api/v5/explorer/address/token-transaction-list";
|
public final static String TRC20_CONTRACT_ADDRESS = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t";
|
public final static String TRC20_NAME = "TRON";
|
public final static String TOKEN_20 = "token_20";
|
|
/**
|
* todo 替换成自己的API-KEY
|
*/
|
private final static String TRON_API_KEY = "21fc662e-03f1-4f60-9124-7b63c0d6c813";
|
|
private static Map<String, String> REQUEST_HEADER = new HashMap<>();
|
static {
|
REQUEST_HEADER.put("Ok-Access-Key", TRON_API_KEY);
|
}
|
|
@Scheduled(cron = "0 0/2 * * * ? ")
|
public void chainBlockUpdate() {
|
log.info("TRC20同步");
|
// String sysAddress = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
|
// RunVipDataDictionaryEnum.CHARGE_SYS_ADDRESS_TRC.getType(), RunVipDataDictionaryEnum.CHARGE_SYS_ADDRESS_TRC.getCode()
|
// ).getValue();
|
String sysAddress = "TExto1UjtFcXKw5QdJDRqtx7wTQ15D37GD";
|
String type = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
|
RunVipDataDictionaryEnum.CHARGE_TYPE_TRC.getType(), RunVipDataDictionaryEnum.CHARGE_TYPE_TRC.getCode()
|
).getValue();
|
|
if(StrUtil.isBlank(sysAddress)){
|
log.info("系统未设置充值地址");
|
return;
|
}
|
// 定时任务的执行时间和转账时间区间间隔5分钟
|
// 查询过去5分钟的记录
|
Map<String, String> param = new HashMap<>();
|
param.put("chainShortName", TRC20_NAME);
|
param.put("protocolType", TOKEN_20);
|
param.put("tokenContractAddress", TRC20_CONTRACT_ADDRESS);
|
param.put("address", sysAddress);
|
param.put("limit", "100");
|
long l = System.currentTimeMillis();
|
byte[] bytes = OkHttpUtil2.doGetSingle(TRC20_TRANSFER_API, REQUEST_HEADER, param, "application/json");
|
|
if (bytes == null) {
|
log.error("fyTrc20RechargeOklinkTask查询链上数据返回为空,传参:{}",param);
|
return;
|
}
|
|
String s = new String(bytes, StandardCharsets.UTF_8);
|
OklinkModel trc20TransfersModel = JSONObject.parseObject(s, OklinkModel.class);
|
List<OklinkDataPageDetailModel> tokenTransfers = trc20TransfersModel.getData().get(0).getTransactionList();
|
if (CollUtil.isEmpty(tokenTransfers)) {
|
return;
|
}
|
long l1 = System.currentTimeMillis();
|
log.info("查询trc耗时:{}", (l1 - l));
|
|
// 有记录
|
for (OklinkDataPageDetailModel tokenTransfer : tokenTransfers) {
|
String transactionTime = tokenTransfer.getTransactionTime();
|
|
Long transTime = Long.valueOf(transactionTime);
|
if ((transTime + TIME_INTERVAL_1HOUR) < l1) {
|
continue;
|
}
|
// 把1个小时前的数据过滤
|
log.info("链上时间:{}", transactionTime);
|
|
// 判断收款地址是否是设置的平台地址
|
if (sysAddress.equals(tokenTransfer.getTo())) {
|
|
String transactionId = tokenTransfer.getTxId();
|
LambdaQueryWrapper<MallCharge> mallChargeLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
mallChargeLambdaQueryWrapper.eq(MallCharge::getTransHash, transactionId);
|
List<MallCharge> list = mallChargeMapper.selectList(mallChargeLambdaQueryWrapper);
|
if(CollUtil.isNotEmpty(list)){
|
log.info("扫描到HASH已使用:{}",transactionId);
|
return;
|
}
|
String fromAddress = tokenTransfer.getFrom();
|
if (fromAddress.equals(sysAddress)) {
|
log.info("系统地址转出:{}", transactionId);
|
continue;
|
}
|
|
BigDecimal amount = new BigDecimal(tokenTransfer.getAmount()).setScale(2, RoundingMode.DOWN);
|
String chargeRedis = redisUtils.getString(AppContants.CHARGE_AMOUNT_PROFIX + amount);
|
if (StrUtil.isBlank(chargeRedis)) {
|
log.info("Redis未扫描到充值金额:{}",transactionId);
|
return;
|
}else{
|
redisUtils.del(AppContants.CHARGE_AMOUNT_PROFIX + amount);
|
log.info("Redis扫描到充值记录:{},{}",transactionId,chargeRedis);
|
}
|
LambdaQueryWrapper<MallCharge> queryWrapper = new LambdaQueryWrapper<>();
|
queryWrapper.eq(MallCharge::getSysAddress, sysAddress);
|
queryWrapper.eq(MallCharge::getAmountReal, amount);
|
queryWrapper.eq(MallCharge::getMemberId, Long.parseLong(chargeRedis));
|
queryWrapper.eq(MallCharge::getType, type);
|
queryWrapper.eq(MallCharge::getState, YesOrNoEnum.ING.getValue());
|
List<MallCharge> mallCharges = mallChargeMapper.selectList(queryWrapper);
|
if(CollUtil.isEmpty(mallCharges)){
|
log.info("未查询到匹配充值记录,充值地址:{},HASH:{}",fromAddress,transactionId);
|
continue;
|
}
|
|
MallCharge mallCharge = mallCharges.get(0);
|
mallCharge.setState(YesOrNoEnum.YES.getValue());
|
mallChargeMapper.updateById(mallCharge);
|
|
if(StrUtil.isNotEmpty(mallCharge.getVipCode())){
|
agentProducer.sendBuyVipSuccessMsg(mallCharge.getId());
|
}else{
|
agentProducer.sendChargeSuccessMsg(mallCharge.getId());
|
}
|
|
log.info("扫描到用户ID:{},地址:{},充值金额:{}", mallCharge.getMemberId(), fromAddress, amount);
|
}
|
}
|
}
|
|
}
|