147 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package jobs
 | ||
| 
 | ||
| import (
 | ||
| 	"fmt"
 | ||
| 	"go-admin/app/admin/service"
 | ||
| 	"go-admin/app/admin/service/dto"
 | ||
| 	"go-admin/config"
 | ||
| 	"go-admin/utils/redishelper"
 | ||
| 	"go-admin/utils/utility"
 | ||
| 	"io"
 | ||
| 	"net/http"
 | ||
| 	"time"
 | ||
| 
 | ||
| 	"github.com/bytedance/sonic"
 | ||
| 	"github.com/go-admin-team/go-admin-core/logger"
 | ||
| 	"github.com/go-admin-team/go-admin-core/sdk"
 | ||
| 	"github.com/shopspring/decimal"
 | ||
| 	"gorm.io/gorm"
 | ||
| )
 | ||
| 
 | ||
| type TrxPaymentJob struct{}
 | ||
| 
 | ||
| const (
 | ||
| 	// tronGridURL         = "https://api.trongrid.io"            // TronGrid API 地址
 | ||
| 	UsdtContractAddress = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" //TRX USDT 合约地址
 | ||
| )
 | ||
| 
 | ||
| // trx 链上支付定时查询
 | ||
| func (j TrxPaymentJob) Exec(arg interface{}) error {
 | ||
| 	key := fmt.Sprintf("pre_order:%s", "*")
 | ||
| 	keys, err := redishelper.DefaultRedis.ScanKeys(key)
 | ||
| 
 | ||
| 	if err != nil {
 | ||
| 		logger.Error("查询redis key失败", err)
 | ||
| 		return nil
 | ||
| 	}
 | ||
| 
 | ||
| 	if len(keys) == 0 {
 | ||
| 		logger.Info("没有待处理订单")
 | ||
| 		return nil
 | ||
| 	}
 | ||
| 
 | ||
| 	configService := service.SysConfig{}
 | ||
| 	configService.Orm = GetDb()
 | ||
| 	req := dto.SysConfigByKeyReq{}
 | ||
| 	req.ConfigKey = "trx_receive_address"
 | ||
| 	configData := dto.GetSysConfigByKEYForServiceResp{}
 | ||
| 	configService.GetWithKey(&req, &configData)
 | ||
| 	if configData.ConfigValue == "" {
 | ||
| 		logger.Error("查询地址为空")
 | ||
| 		return nil
 | ||
| 	}
 | ||
| 
 | ||
| 	rechargeService := service.MemberRecharge{}
 | ||
| 	rechargeService.Orm = GetDb()
 | ||
| 	rechargeService.Log = logger.NewHelper(logger.DefaultLogger)
 | ||
| 
 | ||
| 	startTime := time.Now().UnixMilli()
 | ||
| 	endTime := time.Now().Add(-1 * time.Hour).UnixMilli()
 | ||
| 
 | ||
| 	transfers, err := GetTRC20Transfers(UsdtContractAddress, configData.ConfigValue, endTime, startTime)
 | ||
| 	if err != nil {
 | ||
| 		logger.Error("查询失败", err)
 | ||
| 		return nil
 | ||
| 	}
 | ||
| 
 | ||
| 	logs := make([]dto.TmRechargeCallbackReq, 0)
 | ||
| 	item := dto.TmRechargeCallbackReq{}
 | ||
| 
 | ||
| 	for _, transfer := range transfers {
 | ||
| 		if transfer.TransactionID == "" || transfer.ToAddress != configData.ConfigValue {
 | ||
| 			continue
 | ||
| 		}
 | ||
| 
 | ||
| 		//实际金额
 | ||
| 		payableAmount := utility.StringToDecimal(transfer.Value).Div(decimal.NewFromInt(10).Pow(decimal.NewFromInt(int64(transfer.TokenInfo.Decimals)))).Truncate(6)
 | ||
| 		item.TxHash = transfer.TransactionID
 | ||
| 		item.PayableAmount = payableAmount
 | ||
| 		item.FromAddress = transfer.FromAddress
 | ||
| 		item.ToAddress = transfer.ToAddress
 | ||
| 
 | ||
| 		logs = append(logs, item)
 | ||
| 	}
 | ||
| 
 | ||
| 	if len(logs) > 0 {
 | ||
| 		err := rechargeService.PayCallBack(&logs)
 | ||
| 
 | ||
| 		if err != nil {
 | ||
| 			logger.Error("执行完毕,err:", err.Error())
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // GetTRC20Transfers 获取指定 TRC20 代币的交易记录
 | ||
| func GetTRC20Transfers(contractAddress, accountAddress string, minTimestamp, maxTimestamp int64) ([]dto.TRC20Transfer, error) {
 | ||
| 	url := fmt.Sprintf("%s/v1/accounts/%s/transactions/trc20?contract_address=%s", config.ExtConfig.TrxGridUrl, accountAddress, contractAddress)
 | ||
| 
 | ||
| 	if minTimestamp > 0 {
 | ||
| 		url += fmt.Sprintf("&min_timestamp=%d", minTimestamp)
 | ||
| 	}
 | ||
| 	if maxTimestamp > 0 {
 | ||
| 		url += fmt.Sprintf("&max_timestamp=%d", maxTimestamp)
 | ||
| 	}
 | ||
| 	// logger.Info("查询地址:", url)
 | ||
| 	req, err := http.NewRequest("GET", url, nil)
 | ||
| 	if err != nil {
 | ||
| 		return nil, fmt.Errorf("failed to create request: %v", err)
 | ||
| 	}
 | ||
| 
 | ||
| 	// 设置请求头(包含 TronGrid API Key)
 | ||
| 	req.Header.Set("Accept", "*/*")
 | ||
| 	req.Header.Set("TRON-PRO-API-KEY", config.ExtConfig.TronApiKey) // 从配置读取 API Key
 | ||
| 
 | ||
| 	client := &http.Client{}
 | ||
| 	resp, err := client.Do(req)
 | ||
| 	if err != nil {
 | ||
| 		return nil, fmt.Errorf("failed to send request: %v", err)
 | ||
| 	}
 | ||
| 	defer resp.Body.Close()
 | ||
| 
 | ||
| 	body, err := io.ReadAll(resp.Body)
 | ||
| 	if err != nil {
 | ||
| 		return nil, fmt.Errorf("failed to read response body: %v", err)
 | ||
| 	}
 | ||
| 
 | ||
| 	var result struct {
 | ||
| 		Data []dto.TRC20Transfer `json:"data"`
 | ||
| 	}
 | ||
| 	// logger.Info("查询结果:", string(body))
 | ||
| 	if err := sonic.Unmarshal(body, &result); err != nil {
 | ||
| 		return nil, fmt.Errorf("failed to unmarshal response: %v", err)
 | ||
| 	}
 | ||
| 	return result.Data, nil
 | ||
| }
 | ||
| 
 | ||
| func GetDb() *gorm.DB {
 | ||
| 	dbs := sdk.Runtime.GetDb()
 | ||
| 
 | ||
| 	for _, db := range dbs {
 | ||
| 		return db
 | ||
| 	}
 | ||
| 
 | ||
| 	return nil
 | ||
| }
 |