Some checks failed
Build / build (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
build / Build (push) Has been cancelled
GitHub Actions Mirror / mirror_to_gitee (push) Has been cancelled
GitHub Actions Mirror / mirror_to_gitlab (push) Has been cancelled
Issue Close Require / issue-close-require (push) Has been cancelled
Issue Check Inactive / issue-check-inactive (push) Has been cancelled
159 lines
4.5 KiB
Go
159 lines
4.5 KiB
Go
package jobs
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"go-admin/app/admin/service"
|
||
"go-admin/app/admin/service/dto"
|
||
rediskey "go-admin/common/redis_key"
|
||
"go-admin/config"
|
||
"go-admin/utils/redishelper"
|
||
"go-admin/utils/utility"
|
||
"io"
|
||
"net/http"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/go-admin-team/go-admin-core/logger"
|
||
"github.com/shopspring/decimal"
|
||
)
|
||
|
||
type TrxPaymentJob struct{}
|
||
|
||
const (
|
||
// tronGridURL = "https://api.trongrid.io" // TronGrid API 地址
|
||
UsdtContractAddress = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" //TRX USDT 合约地址
|
||
)
|
||
|
||
// trx 链上支付定时查询
|
||
func (j TrxPaymentJob) Exec(arg interface{}) error {
|
||
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
|
||
}
|
||
|
||
key := fmt.Sprintf(rediskey.TM_RECHARGE_PRE_ORDER, "*")
|
||
keys, err := redishelper.DefaultRedis.ScanKeys(key)
|
||
|
||
if err != nil {
|
||
logger.Error("查询redis key失败", err)
|
||
return nil
|
||
}
|
||
|
||
if len(keys) == 0 {
|
||
logger.Info("没有待处理订单")
|
||
return nil
|
||
}
|
||
|
||
rechargeService := service.TmRechargeLog{}
|
||
rechargeService.Orm = GetDb()
|
||
rechargeService.Log = logger.NewHelper(logger.DefaultLogger)
|
||
platforms, err := rechargeService.GetPlatforms()
|
||
toAddresss := []string{}
|
||
|
||
if err != nil {
|
||
logger.Error("查询平台失败", err)
|
||
return err
|
||
}
|
||
|
||
for _, platform := range platforms {
|
||
if strings.ToLower(platform.BlockChain) == "trx" && !utility.ContainsString(toAddresss, platform.ReceiveAddress) {
|
||
toAddresss = append(toAddresss, platform.ReceiveAddress)
|
||
}
|
||
}
|
||
|
||
startTime := time.Now().UnixMilli()
|
||
endTime := time.Now().Add(-1 * time.Hour).UnixMilli()
|
||
|
||
for _, toAddress := range toAddresss {
|
||
transfers, err := GetTRC20Transfers(UsdtContractAddress, toAddress, 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 != toAddress {
|
||
logger.Infof("跳出插入 ", transfer)
|
||
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
|
||
|
||
if utility.ContainsString(toAddresss, item.ToAddress) {
|
||
logs = append(logs, item)
|
||
} else {
|
||
logger.Infof("没有写入logs ", item)
|
||
}
|
||
}
|
||
|
||
if len(logs) > 0 {
|
||
|
||
err := rechargeService.PayCallBack(&logs)
|
||
|
||
if err != nil {
|
||
logger.Error("执行完毕,err:", err.Error())
|
||
}
|
||
} else {
|
||
// logger.Infof("接收地址:%s 合约地址:%s 无数据", toAddress, UsdtContractAddress)
|
||
}
|
||
}
|
||
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 := json.Unmarshal(body, &result); err != nil {
|
||
return nil, fmt.Errorf("failed to unmarshal response: %v", err)
|
||
}
|
||
return result.Data, nil
|
||
}
|