From 1852a2e7200f81435c08d1b668b87393f4496a61 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Thu, 18 Jun 2026 16:00:32 +0800
Subject: [PATCH] fix(tokenview): 更新 Tokenview webhook 密钥配置

---
 src/main/java/cc/mrbird/febs/mall/quartz/ChatTrc20ChargeOkLinkTask.java |  149 +++++++++++++++----------------------------------
 1 files changed, 45 insertions(+), 104 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/mall/quartz/ChatTrc20ChargeOkLinkTask.java b/src/main/java/cc/mrbird/febs/mall/quartz/ChatTrc20ChargeOkLinkTask.java
index ace4816..c15c01e 100644
--- a/src/main/java/cc/mrbird/febs/mall/quartz/ChatTrc20ChargeOkLinkTask.java
+++ b/src/main/java/cc/mrbird/febs/mall/quartz/ChatTrc20ChargeOkLinkTask.java
@@ -1,180 +1,121 @@
 package cc.mrbird.febs.mall.quartz;
 
-import cc.mrbird.febs.common.enumerates.OrderStatusEnum;
-import cc.mrbird.febs.common.utils.RedisUtils;
-import cc.mrbird.febs.mall.controller.dependentStation.constant.OrderConstants;
-import cc.mrbird.febs.mall.controller.dependentStation.enums.SalesServiceEnums;
+import cc.mrbird.febs.mall.controller.dependentStation.TokenviewWebhookService;
 import cc.mrbird.febs.mall.controller.dependentStation.utils.OkHttpUtil2;
 import cc.mrbird.febs.mall.controller.dependentStation.utils.Trc20TokenviewContentModel;
 import cc.mrbird.febs.mall.controller.dependentStation.utils.Trc20TokenviewModel;
-import cc.mrbird.febs.mall.entity.DataDictionaryCustom;
-import cc.mrbird.febs.mall.entity.MallOrderInfo;
-import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper;
-import cc.mrbird.febs.mall.mapper.MallOrderInfoMapper;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 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.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+
 @Slf4j
 @Component
 @ConditionalOnProperty(prefix = "system", name = "job", havingValue = "true")
 public class ChatTrc20ChargeOkLinkTask {
 
+    @Resource
+    private TokenviewWebhookService tokenviewWebhookService;
 
-    @Resource
-    private RedisUtils redisUtils;
-    @Resource
-    private MallOrderInfoMapper mallOrderInfoMapper;
-    @Resource
-    private DataDictionaryCustomMapper dataDictionaryCustomMapper;
     /**
-     * 五分钟  毫秒
+     * 30分钟(毫秒)
      */
-    private final static long TIME_INTERVAL = 300000*6;
+    private final static long TIME_INTERVAL = 300000 * 6;
 
-    private final static String TRC20_TRANSFER_API = "https://apilist.tronscanapi.com/api/token_trc20/transfers";
-
-    public final static String TRC20_CONTRACT_ADDRESS = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t";
-
-    private final static String TRON_API_KEY = "32c9841d-19ae-48cf-a535-cf56d9d25f1c";
+    private final static String TRON_API_KEY = "X8Np5zbDuhmG6cntbhLu";
 
     private static Map<String, String> REQUEST_HEADER = new HashMap<>();
     static {
         REQUEST_HEADER.put("TRON-PRO-API-KEY", TRON_API_KEY);
     }
 
-    @Scheduled(cron = "0 0/5 * * * ? ")
+    /**
+     * 每分钟轮询 Tokenview API,查询 TRC20-USDT 充值记录
+     * 充值匹配逻辑委托给 {@link TokenviewWebhookService}
+     */
+    @Scheduled(cron = "0 0/1 * * * ? ")
     public void recharge() {
-        // 查询过去5分钟的记录
-
-        DataDictionaryCustom dataDictionaryCustom = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
-                SalesServiceEnums.TRC_ADDRESS.getType(),
-                SalesServiceEnums.TRC_ADDRESS.getCode()
-        );
-        String receiveAddress = dataDictionaryCustom.getValue();
+        String receiveAddress = tokenviewWebhookService.getReceiveAddress();
         if (receiveAddress == null) {
             log.error("请先配置系统地址");
             return;
         }
-        String url = "https://services.tokenview.io/vipapi/trx/address/tokentrans/"+receiveAddress+"/TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t/1/10";
-        // 定时任务的执行时间和转账时间区间间隔5分钟
 
-        // 每次将上次的时间存入redis,第一次使用默认的时间
+        String url = "https://services.tokenview.io/vipapi/trx/address/tokentrans/"
+                + receiveAddress + "/TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t/1/10";
+
         long endTime = System.currentTimeMillis();
-        long startTime = endTime-TIME_INTERVAL;
+        long startTime = endTime - TIME_INTERVAL;
 
-        System.out.println(new Date()+" 自动充值定时任务fyTrc20RechargeTokenviewTask "+startTime+" "+endTime);
-        // 当前的充值地址 TRC20USDT_ADDRESS
+        log.info("自动充值定时任务 startTime={}, endTime={}", startTime, endTime);
+
         Map<String, String> param = new HashMap<>();
         param.put("timestampStart", startTime + "");
         param.put("timestampEnd", endTime + "");
         param.put("toAddress", receiveAddress);
         param.put("apikey", TRON_API_KEY);
-        long l = System.currentTimeMillis();
+
+        long start = System.currentTimeMillis();
         byte[] bytes = OkHttpUtil2.doGetSingle(url, REQUEST_HEADER, param, "application/json");
 
-        if (ObjectUtil.isEmpty( bytes )) {
-            log.error("FyTrc20RechargeTask查询链上数据返回为空,传参:{}",param);
+        if (ObjectUtil.isEmpty(bytes)) {
+            log.error("查询链上数据返回为空, param={}", param);
             return;
         }
 
-        String s = new String(bytes, StandardCharsets.UTF_8);
-        log.info("查询到的充值记录:{}", s);
-        Trc20TokenviewModel trc20TransfersModel = JSONObject.parseObject(s, Trc20TokenviewModel.class);
-        List<Trc20TokenviewContentModel> tokenTransfers = trc20TransfersModel.getData();
+        String response = new String(bytes, StandardCharsets.UTF_8);
+        log.info("查询到的充值记录:{}", response);
+
+        Trc20TokenviewModel model = JSONObject.parseObject(response, Trc20TokenviewModel.class);
+        List<Trc20TokenviewContentModel> tokenTransfers = model.getData();
         if (CollUtil.isEmpty(tokenTransfers)) {
-            //logger.error("FyTrc20RechargeTask查询链上数据返回没有token转账,返回结果:{}",s);
             return;
         }
-        long l1 = System.currentTimeMillis();
-        log.info("查询trc耗时:{}", (l1 - l));
-        log.info("查询到的充值记录:{}", JSONObject.toJSONString(trc20TransfersModel));
-        log.info("时间区间,start:{},end:{}", startTime, endTime);
-        // 有记录
-        for (Trc20TokenviewContentModel tokenTransfer : tokenTransfers) {
-            log.info("链上时间:{}", tokenTransfer.getTime());
-            // 从数据库
-            String transactionId = tokenTransfer.getTxid();
-            List<MallOrderInfo> chatOrders = mallOrderInfoMapper.selectList(
-                    Wrappers.lambdaQuery(MallOrderInfo.class)
-                    .eq(MallOrderInfo::getTradeHash, transactionId)
-            );
-            if(CollUtil.isNotEmpty(chatOrders)){
-                log.info("扫描到HASH已使用:{}",transactionId);
-                continue;
-            }
-            // 金额
-            String quant = tokenTransfer.getValue();
-            BigDecimal amount = new BigDecimal(quant).divide(new BigDecimal("1000000")).setScale(2, RoundingMode.DOWN);
-            String amountKey = OrderConstants.TRC20_ORDER_KEY + amount;
-            String orderCode = redisUtils.getString(amountKey);
-            if (StrUtil.isBlank(orderCode)) {
-                log.info("Redis未扫描到充值金额:{}",transactionId);
-                continue;
-            }
-            MallOrderInfo chatOrder = mallOrderInfoMapper.selectOne(
-                    Wrappers.lambdaQuery(MallOrderInfo.class)
-                            .eq(MallOrderInfo::getOrderNo, orderCode)
-            );
-            if(chatOrder==null){
-                log.error("未找到订单:{}",orderCode);
-                continue;
-            }
-            if(OrderStatusEnum.WAIT_PAY.getValue() != chatOrder.getStatus()){
-                log.error("订单不是待充值状态: {},订单编号:{}",transactionId,orderCode);
-                continue;
-            }
 
-            mallOrderInfoMapper.update(
-                    null,
-                    Wrappers.lambdaUpdate(MallOrderInfo.class)
-                            .set(MallOrderInfo::getStatus, OrderStatusEnum.WAIT_SHIPPING.getValue())
-                            .set(MallOrderInfo::getTradeHash, transactionId)
-                            .set(MallOrderInfo::getPayTime, new Date())
-                            .set(MallOrderInfo::getPayResult, "1")
-                            .eq(MallOrderInfo::getId, chatOrder.getId())
+        log.info("查询耗时:{}ms, 记录数:{}, 时间区间 [{}, {}]",
+                System.currentTimeMillis() - start, tokenTransfers.size(), startTime, endTime);
+
+        for (Trc20TokenviewContentModel transfer : tokenTransfers) {
+            log.info("链上时间: {}", transfer.getTime());
+            String result = tokenviewWebhookService.processPollTransaction(
+                    transfer.getTxid(),
+                    transfer.getValue(),
+                    receiveAddress
             );
-            redisUtils.del(amountKey);
-            log.info("Redis扫描到充值记录:{},订单编号:{}",transactionId,orderCode);
+            log.info("轮询处理结果: {}", result);
         }
     }
 
-
     public static void main(String[] args) {
         String receiveAddress = "TExto1UjtFcXKw5QdJDRqtx7wTQ15D37GD";
-        String url = "https://services.tokenview.io/vipapi/trx/address/tokentrans/"+receiveAddress+"/TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t/1/10";
-        // 定时任务的执行时间和转账时间区间间隔5分钟
+        String url = "https://services.tokenview.io/vipapi/trx/address/tokentrans/"
+                + receiveAddress + "/TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t/1/10";
 
-        // 每次将上次的时间存入redis,第一次使用默认的时间
         long endTime = System.currentTimeMillis();
-        long startTime = endTime-TIME_INTERVAL;
+        long startTime = endTime - TIME_INTERVAL;
 
-        System.out.println(new Date()+" 自动充值定时任务fyTrc20RechargeTokenviewTask "+startTime+" "+endTime);
-        // 当前的充值地址 TRC20USDT_ADDRESS
+        System.out.println(new Date() + " 自动充值定时任务 " + startTime + " " + endTime);
+
         Map<String, String> param = new HashMap<>();
         param.put("timestampStart", startTime + "");
         param.put("timestampEnd", endTime + "");
         param.put("toAddress", receiveAddress);
         param.put("apikey", TRON_API_KEY);
-        long l = System.currentTimeMillis();
+
         byte[] bytes = OkHttpUtil2.doGetSingle(url, REQUEST_HEADER, param, "application/json");
 
         if (bytes == null) {
-            log.error("FyTrc20RechargeTask查询链上数据返回为空,传参:{}",param);
+            System.out.println("查询链上数据返回为空, param=" + param);
             return;
         }
 

--
Gitblit v1.9.1