diff --git a/app/admin/apis/wm_transfer_item.go b/app/admin/apis/wm_transfer_item.go index e7c2d6c..7245157 100644 --- a/app/admin/apis/wm_transfer_item.go +++ b/app/admin/apis/wm_transfer_item.go @@ -43,7 +43,7 @@ func (e WmTransferItem) GetPage(c *gin.Context) { } p := actions.GetPermissionFromContext(c) - list := make([]models.WmTransferItem, 0) + list := make([]dto.WmTransferItemResp, 0) var count int64 err = s.GetPage(&req, p, &list, &count) @@ -262,3 +262,23 @@ func (e WmTransferItem) GetAutoTransferLogPage(c *gin.Context) { } e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功") } + +// 清除自动转账 +func (e WmTransferItem) ClearAutoLog(c *gin.Context) { + s := service.WmTransferItem{} + err := e.MakeContext(c). + MakeOrm(). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + err = s.ClearAutoLog() + if err != nil { + e.Error(500, err, fmt.Sprintf("清除自动转账日志失败,\r\n失败信息 %s", err.Error())) + return + } + e.OK(nil, "清除成功") +} diff --git a/app/admin/apis/wm_wallet_info.go b/app/admin/apis/wm_wallet_info.go index 0ddafb2..fc1661b 100644 --- a/app/admin/apis/wm_wallet_info.go +++ b/app/admin/apis/wm_wallet_info.go @@ -174,3 +174,49 @@ func (e WmWalletInfo) ClearAll(c *gin.Context) { } e.OK(nil, "清空成功") } + +// 根据excel导入钱包信息 +func (e WmWalletInfo) ExcelImport(c *gin.Context) { + s := service.WmWalletInfo{} + err := e.MakeContext(c). + MakeOrm(). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + errs := s.ExcelImport(c) + + e.OK(strings.Join(errs, "
"), "创建成功") +} + +// UpdateRemark 更新备注信息 +func (e WmWalletInfo) UpdateRemark(c *gin.Context) { + s := service.WmWalletInfo{} + req := dto.WmWalletInfoBatchUpdateReq{} + + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + // 设置更新人 + req.SetUpdateBy(user.GetUserId(c)) + + err = s.BatchUpdateRemark(&req) + if err != nil { + e.Error(500, err, fmt.Sprintf("更新备注信息失败,\r\n失败信息 %s", err.Error())) + return + } + + e.OK(nil, "更新成功") +} diff --git a/app/admin/models/wm_transfer.go b/app/admin/models/wm_transfer.go index c9bd0e7..9f7ca08 100644 --- a/app/admin/models/wm_transfer.go +++ b/app/admin/models/wm_transfer.go @@ -17,6 +17,8 @@ type WmTransfer struct { Sucess int `json:"sucess" gorm:"-"` Fail int `json:"fail" gorm:"-"` Pending int `json:"pending" gorm:"-"` + NetworkName string `json:"networkName" gorm:"-"` + TokenName string `json:"tokenName" gorm:"-"` models.ModelTime models.ControlBy } diff --git a/app/admin/models/wm_wallet_info.go b/app/admin/models/wm_wallet_info.go index 5041a68..a18af14 100644 --- a/app/admin/models/wm_wallet_info.go +++ b/app/admin/models/wm_wallet_info.go @@ -12,6 +12,7 @@ type WmWalletInfo struct { PrivateKey string `json:"privateKey" gorm:"type:varchar(50);comment:钱包私钥"` Address string `json:"address" gorm:"type:varchar(50);comment:钱包地址"` UsdcAmount decimal.Decimal `json:"usdcAmount" gorm:"type:decimal(18,8);comment:USDC余额"` + Remark string `json:"remark" gorm:"type:varchar(255);comment:备注信息"` models.ModelTime models.ControlBy } diff --git a/app/admin/router/wm_transfer_item.go b/app/admin/router/wm_transfer_item.go index d6b837c..70b0035 100644 --- a/app/admin/router/wm_transfer_item.go +++ b/app/admin/router/wm_transfer_item.go @@ -24,6 +24,7 @@ func registerWmTransferItemRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJW r.PUT("/:id", actions.PermissionAction(), api.Update) r.DELETE("", api.Delete) + r.DELETE("/clear", api.ClearAutoLog) r.GET("/export", actions.PermissionAction(), api.Export) r.GET("/export-auto-log", actions.PermissionAction(), api.ExportAutoLog) r.GET("/auto-log", actions.PermissionAction(), api.GetAutoTransferLogPage) diff --git a/app/admin/router/wm_wallet_info.go b/app/admin/router/wm_wallet_info.go index 949d073..5c2f2ab 100644 --- a/app/admin/router/wm_wallet_info.go +++ b/app/admin/router/wm_wallet_info.go @@ -24,5 +24,8 @@ func registerWmWalletInfoRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTM // r.PUT("/:id", actions.PermissionAction(), api.Update) r.DELETE("", api.Delete) r.DELETE("clear", api.ClearAll) + + r.POST("/excel-import", api.ExcelImport) //根据excel导入数据 + r.PUT("/batch", api.UpdateRemark) //批量更新备注 } } diff --git a/app/admin/service/dto/wm_token.go b/app/admin/service/dto/wm_token.go index 37f74f5..3af02e1 100644 --- a/app/admin/service/dto/wm_token.go +++ b/app/admin/service/dto/wm_token.go @@ -13,6 +13,7 @@ type WmTokenGetPageReq struct { dto.Pagination `search:"-"` NetworkId string `form:"networkId" search:"type:contains;column:network_id;table:wm_token" comment:"网络id"` TokenName string `form:"tokenName" search:"type:contains;column:token_name;table:wm_token" comment:"代币名称"` + TransType int `form:"transType" search:"-" comment:"转账类型 1-百分比 2-实际金额"` WmTokenOrder } diff --git a/app/admin/service/dto/wm_transfer.go b/app/admin/service/dto/wm_transfer.go index 8f4084e..65df912 100644 --- a/app/admin/service/dto/wm_transfer.go +++ b/app/admin/service/dto/wm_transfer.go @@ -2,9 +2,11 @@ package dto import ( "errors" + "fmt" "go-admin/app/admin/models" "go-admin/common/dto" common "go-admin/common/models" + "go-admin/utils/ethtransferhelper" "strings" "github.com/shopspring/decimal" @@ -105,6 +107,12 @@ func (s *WmTransferInsertReq) Valid() error { } } + for _, content := range contents { + if !ethtransferhelper.IsValidAddress(content) { + return fmt.Errorf("%s 地址格式错误", content) + } + } + return nil } diff --git a/app/admin/service/dto/wm_transfer_item.go b/app/admin/service/dto/wm_transfer_item.go index 27d0e25..1e1489f 100644 --- a/app/admin/service/dto/wm_transfer_item.go +++ b/app/admin/service/dto/wm_transfer_item.go @@ -17,7 +17,10 @@ type WmTransferItemGetPageReq struct { type WmTransferItemAutoLogPageReq struct { dto.Pagination `search:"-"` - NetworkId int `form:"networkId" search:"type:exact;column:network_id;table:wm_transfer_item"` + NetworkId int `form:"networkId" search:"type:exact;column:network_id;table:wm_transfer_item"` + StartAmount float64 `form:"startAmount" search:"-"` + EndAmount float64 `form:"endAmount" search:"-"` + Status int `form:"status" search:"-"` WmTransferItemOrder } @@ -146,6 +149,8 @@ type WmTransferItemExportReq struct { } type WmTransferItemExportData struct { + NetworkName string `json:"networkName" excel:"网络名称"` + TokenName string `json:"tokenName" excel:"代币名称"` PrivateKey string `json:"privateKey" excel:"私钥"` TokenAddress string `json:"tokenAddress" excel:"代币地址"` FromAddress string `json:"fromAddress" excel:"来源地址"` diff --git a/app/admin/service/dto/wm_wallet_info.go b/app/admin/service/dto/wm_wallet_info.go index ae21b21..450345a 100644 --- a/app/admin/service/dto/wm_wallet_info.go +++ b/app/admin/service/dto/wm_wallet_info.go @@ -10,7 +10,7 @@ import ( type WmWalletInfoGetPageReq struct { dto.Pagination `search:"-"` - PrivateKey string `form:"privateKey" search:"type:exact;column:private_key;table:wm_wallet_info" comment:"钱包私钥"` + PrivateKey string `form:"privateKey" search:"-" comment:"钱包私钥"` WmWalletInfoOrder } @@ -30,7 +30,8 @@ func (m *WmWalletInfoGetPageReq) GetNeedSearch() interface{} { } type WmWalletInfoBatchInsertReq struct { - Keys string `json:"keys"` + Keys string `json:"keys"` + Remark string `json:"remark"` common.ControlBy } @@ -103,3 +104,14 @@ type WmWalletInfoDeleteReq struct { func (s *WmWalletInfoDeleteReq) GetId() interface{} { return s.Ids } + +type WmWalletExcelImportReq struct { + PrivateKey string `json:"privateKey" excel:"钱包私钥"` + Remark string `json:"remark" excel:"备注"` +} + +type WmWalletInfoBatchUpdateReq struct { + Ids []int `json:"ids" form:"ids"` + Remark string `json:"remark" form:"remark"` + common.ControlBy +} diff --git a/app/admin/service/wm_token.go b/app/admin/service/wm_token.go index 8973f8a..8950a13 100644 --- a/app/admin/service/wm_token.go +++ b/app/admin/service/wm_token.go @@ -25,13 +25,18 @@ type WmToken struct { func (e *WmToken) GetPage(c *dto.WmTokenGetPageReq, p *actions.DataPermission, list *[]models.WmToken, count *int64) error { var err error var data models.WmToken - - err = e.Orm.Model(&data). + query := e.Orm.Model(&data). Scopes( cDto.MakeCondition(c.GetNeedSearch()), cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), actions.Permission(data.TableName(), p), - ). + ) + + if c.TransType > 0 { + query.Where("trans_type = ?", c.TransType) + } + + err = query. Find(list).Limit(-1).Offset(-1). Count(count).Error if err != nil { diff --git a/app/admin/service/wm_transfer.go b/app/admin/service/wm_transfer.go index 1001ae6..e403169 100644 --- a/app/admin/service/wm_transfer.go +++ b/app/admin/service/wm_transfer.go @@ -56,6 +56,10 @@ func (e *WmTransfer) GetPage(c *dto.WmTransferGetPageReq, p *actions.DataPermiss } itemData, _ := e.GetItemData(transferIds) + networkService := WmNetwork{Service: e.Service} + networks, _ := networkService.GetAll() + tokenService := WmToken{Service: e.Service} + tokens, _ := tokenService.GetAll() for i := range *list { var total int @@ -74,6 +78,20 @@ func (e *WmTransfer) GetPage(c *dto.WmTransferGetPageReq, p *actions.DataPermiss } } + for _, network := range networks { + if network.Id == (*list)[i].NetworkId { + (*list)[i].NetworkName = network.NetworkName + break + } + } + + for _, token := range tokens { + if token.NetworkId == (*list)[i].NetworkId && token.TokenAddress == (*list)[i].TokenAddress { + (*list)[i].TokenName = token.TokenName + break + } + } + (*list)[i].Total = total } @@ -196,6 +214,7 @@ func (e *WmTransfer) Insert(c *dto.WmTransferInsertReq) error { caches[i].TransferId = data.Id caches[i].IsAuto = 2 caches[i].TokenAddress = c.TokenAddress + caches[i].Decimals = token.Decimals } if err := tx.CreateInBatches(&caches, 100).Error; err != nil { @@ -226,7 +245,7 @@ func (e *WmTransfer) getPrivateKeyAmount(privateKey, tokenAddress string, decima return amount, errors.New("连接区块链失败") } - amount, err = ethbalanceofhelper.GetERC20Balance(client, tokenAddress, accountAddress.String(), decimals) + amount, err = ethbalanceofhelper.GetBalance(client, tokenAddress, accountAddress.String(), decimals) if err != nil { return amount, errors.New("查询主账号余额失败") @@ -372,11 +391,11 @@ func (e *WmTransfer) CheckHashStatus() error { // 清理数据 func (e *WmTransfer) ClearAll() error { err := e.Orm.Transaction(func(tx *gorm.DB) error { - if err1 := tx.Exec("truncate table wm_transfer_item").Error; err1 != nil { + if err1 := tx.Exec("delete from wm_transfer_item where is_auto = 2").Error; err1 != nil { return err1 } - if err2 := tx.Exec("truncate table wm_transfer").Error; err2 != nil { + if err2 := tx.Exec("delete from wm_transfer ").Error; err2 != nil { return err2 } diff --git a/app/admin/service/wm_transfer_item.go b/app/admin/service/wm_transfer_item.go index b79d512..d026037 100644 --- a/app/admin/service/wm_transfer_item.go +++ b/app/admin/service/wm_transfer_item.go @@ -21,9 +21,10 @@ type WmTransferItem struct { } // GetPage 获取WmTransferItem列表 -func (e *WmTransferItem) GetPage(c *dto.WmTransferItemGetPageReq, p *actions.DataPermission, list *[]models.WmTransferItem, count *int64) error { +func (e *WmTransferItem) GetPage(c *dto.WmTransferItemGetPageReq, p *actions.DataPermission, list *[]dto.WmTransferItemResp, count *int64) error { var err error var data models.WmTransferItem + var datas []models.WmTransferItem err = e.Orm.Model(&data). Scopes( @@ -31,15 +32,48 @@ func (e *WmTransferItem) GetPage(c *dto.WmTransferItemGetPageReq, p *actions.Dat cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), actions.Permission(data.TableName(), p), ). - Find(list).Limit(-1).Offset(-1). + Find(&datas).Limit(-1).Offset(-1). Count(count).Error if err != nil { e.Log.Errorf("WmTransferItemService GetPage error:%s \r\n", err) return err } - for i := 0; i < len(*list); i++ { - (*list)[i].PrivateKey = stringhelper.DesensitizeWalletAddress(aeshelper.AesEcbDecrypt((*list)[i].PrivateKey)) + networkService := WmNetwork{Service: e.Service} + networks, _ := networkService.GetAll() + tokenService := WmToken{Service: e.Service} + tokens, _ := tokenService.GetAll() + + for i := 0; i < len(datas); i++ { + item := dto.WmTransferItemResp{} + item.Id = datas[i].Id + item.PrivateKey = stringhelper.DesensitizeWalletAddress(aeshelper.AesEcbDecrypt(datas[i].PrivateKey)) + item.FromAddress = datas[i].FromAddress + item.ToAddress = datas[i].ToAddress + item.TokenAddress = datas[i].TokenAddress + item.Amount = datas[i].Amount + item.Status = datas[i].Status + item.Remark = datas[i].Remark + item.Type = datas[i].Type + item.TypeValue = datas[i].TypeValue + item.Hash = datas[i].Hash + item.CreateAt = datas[i].CreatedAt + + for _, network := range networks { + if network.Id == datas[i].NetworkId { + item.NetworkName = network.NetworkName + break + } + } + + for _, token := range tokens { + if token.NetworkId == datas[i].NetworkId && token.TokenAddress == datas[i].TokenAddress { + item.TokenName = token.TokenName + break + } + } + + *list = append(*list, item) } return nil @@ -50,9 +84,22 @@ func (e *WmTransferItem) GetAutoTransferLogPage(c *dto.WmTransferItemAutoLogPage var err error var data models.WmTransferItem var datas []models.WmTransferItem + query := e.Orm.Model(&data). + Where("is_auto = 1") - err = e.Orm.Model(&data). - Where("is_auto = 1"). + if c.StartAmount >= 0 { + query.Where("amount >=?", c.StartAmount) + } + + if c.EndAmount > 0 { + query.Where("amount <=?", c.EndAmount) + } + + if c.Status > 0 { + query.Where("status =?", c.Status) + } + + err = query. Scopes( cDto.MakeCondition(c.GetNeedSearch()), cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), @@ -111,8 +158,21 @@ func (e *WmTransferItem) ExportAutoLog(req *dto.WmTransferItemAutoLogPageReq, c var err error var data models.WmTransferItem exportDatas := make([]dto.WmTransferItemResp, 0) + query := e.Orm.Model(&data) - err = e.Orm.Model(&data). + if req.StartAmount >= 0 { + query.Where("amount >=?", req.StartAmount) + } + + if req.EndAmount > 0 { + query.Where("amount <=?", req.EndAmount) + } + + if req.Status > 0 { + query.Where("status =?", req.Status) + } + + err = query. Where("is_auto = 1"). Scopes( cDto.MakeCondition(req.GetNeedSearch()), @@ -259,6 +319,11 @@ func (e *WmTransferItem) ExportExcel(req *dto.WmTransferItemExportReq, p *action return err } + networkService := WmNetwork{Service: e.Service} + networks, _ := networkService.GetAll() + tokenService := WmToken{Service: e.Service} + tokens, _ := tokenService.GetAll() + for i := 0; i < len(datas); i++ { (datas)[i].PrivateKey = stringhelper.DesensitizeWalletAddress(aeshelper.AesEcbDecrypt((datas)[i].PrivateKey)) exportData := dto.WmTransferItemExportData{ @@ -281,6 +346,21 @@ func (e *WmTransferItem) ExportExcel(req *dto.WmTransferItemExportReq, p *action default: exportData.Status = "默认" } + + for _, network := range networks { + if network.Id == datas[i].NetworkId { + exportData.NetworkName = network.NetworkName + break + } + } + + for _, token := range tokens { + if token.NetworkId == datas[i].NetworkId && token.TokenAddress == datas[i].TokenAddress { + exportData.TokenName = token.TokenName + break + } + } + exportDatas = append(exportDatas, exportData) } @@ -290,3 +370,13 @@ func (e *WmTransferItem) ExportExcel(req *dto.WmTransferItemExportReq, p *action return excelhelper.ExportExcel(c, "转账明细", exportDatas, []string{}) } + +// 批量删除自动转账日志 +func (e *WmTransferItem) ClearAutoLog() error { + if err := e.Orm.Where("is_auto=1").Unscoped().Delete(&models.WmTransferItem{}).Error; err != nil { + e.Log.Errorf("Service ClearAutoLog error:%s \r\n", err) + return err + } + + return nil +} diff --git a/app/admin/service/wm_wallet_info.go b/app/admin/service/wm_wallet_info.go index 746338d..495f9fa 100644 --- a/app/admin/service/wm_wallet_info.go +++ b/app/admin/service/wm_wallet_info.go @@ -4,6 +4,7 @@ import ( "errors" "strings" + "github.com/gin-gonic/gin" "github.com/go-admin-team/go-admin-core/sdk/service" "github.com/shopspring/decimal" "gorm.io/gorm" @@ -16,6 +17,7 @@ import ( "go-admin/utils/aeshelper" "go-admin/utils/ethbalanceofhelper" "go-admin/utils/ethtransferhelper" + "go-admin/utils/excelhelper" "go-admin/utils/stringhelper" ) @@ -27,8 +29,13 @@ type WmWalletInfo struct { func (e *WmWalletInfo) GetPage(c *dto.WmWalletInfoGetPageReq, p *actions.DataPermission, list *[]models.WmWalletInfo, count *int64) error { var err error var data models.WmWalletInfo + query := e.Orm.Model(&data) + if c.PrivateKey != "" { + key := aeshelper.AesEcbDecrypt(c.PrivateKey) + query.Where("private_key =?", key) + } - err = e.Orm.Model(&data). + err = query. Scopes( cDto.MakeCondition(c.GetNeedSearch()), cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), @@ -174,7 +181,7 @@ func (e *WmWalletInfo) ScheduledTask() error { } for i := range datas { - amount, err := ethbalanceofhelper.GetERC20Balance(client, token.TokenAddress, datas[i].Address, token.Decimals) + amount, err := ethbalanceofhelper.GetBalance(client, token.TokenAddress, datas[i].Address, token.Decimals) if err != nil { e.Log.Errorf("GetERC20Balance error:%s", err) @@ -245,3 +252,65 @@ func (e *WmWalletInfo) ClearAll() error { return err } + +// 根据excel导入数据 +func (e *WmWalletInfo) ExcelImport(c *gin.Context) []string { + dataRows, headers, err := excelhelper.GetExcelContent(c) + errors := []string{} + + if err != nil { + errors = append(errors, err.Error()) + return errors + } + + datas, err := excelhelper.MapExcelToStruct[dto.WmWalletExcelImportReq](dataRows, headers) + + if err != nil { + errors = append(errors, err.Error()) + return errors + } + // entitys := make([]models.WmWalletInfo, 0) + var count int64 + for _, data := range datas { + privateKey := strings.ReplaceAll(data.PrivateKey, " ", "") + if privateKey == "" { + continue + } + + _, address, _ := ethtransferhelper.GetAddressFromPrivateKey(privateKey) + entity := models.WmWalletInfo{ + PrivateKey: aeshelper.AesEcbEncrypt(privateKey), + Address: address.String(), + Remark: data.Remark, + } + + if err := e.Orm.Model(entity).Where("private_key =?", entity.PrivateKey).Count(&count).Error; err != nil { + e.Log.Errorf("db error:%s", err) + } + if count == 0 { + if err := e.Orm.Create(&entity).Error; err != nil { + e.Log.Errorf("db error:%s", err) + errors = append(errors, err.Error()) + } + } + // entitys = append(entitys, entity) + } + + // if len(entitys) > 0 { + // if err := e.Orm.CreateInBatches(entitys, 100).Error; err != nil { + // e.Log.Errorf("定时转账保存数据库失败 error:%s", err) + // return err + // } + // } + + return errors +} + +// 批量修改备注 +func (e *WmWalletInfo) BatchUpdateRemark(req *dto.WmWalletInfoBatchUpdateReq) error { + if err := e.Orm.Model(&models.WmWalletInfo{}).Where("id in ?", req.Ids).Update("remark", req.Remark).Error; err != nil { + return err + } + + return nil +} diff --git a/static/excel/钱包导入模板.xlsx b/static/excel/钱包导入模板.xlsx new file mode 100644 index 0000000..08f068d Binary files /dev/null and b/static/excel/钱包导入模板.xlsx differ diff --git a/utils/ethbalanceofhelper/baalanceof_helper.go b/utils/ethbalanceofhelper/balanceof_helper.go similarity index 74% rename from utils/ethbalanceofhelper/baalanceof_helper.go rename to utils/ethbalanceofhelper/balanceof_helper.go index 93ddf16..47dd514 100644 --- a/utils/ethbalanceofhelper/baalanceof_helper.go +++ b/utils/ethbalanceofhelper/balanceof_helper.go @@ -36,6 +36,30 @@ const erc20ABI = `[ } ]` +// GetBalance 查询 余额并转换为正常单位 (使用 decimal) +func GetBalance(client *ethclient.Client, tokenAddress, accountAddress string, decimals int) (decimal.Decimal, error) { + switch tokenAddress { + case "0": + return GetEthBalance(client, accountAddress, decimals) + default: + return GetERC20Balance(client, tokenAddress, accountAddress, decimals) + } +} + +// GetEthBalance 查询以太坊余额并转换为正常单位 (使用 decimal) +func GetEthBalance(client *ethclient.Client, accountAddress string, decimals int) (decimal.Decimal, error) { + account := common.HexToAddress(accountAddress) + balance, err := client.BalanceAt(context.Background(), account, nil) + if err != nil { + return decimal.Zero, fmt.Errorf("查询余额失败 err:%v", err) + } + balanceDecimal := decimal.NewFromBigInt(balance, 0) // Create decimal from big.Int + decimalFactor := decimal.NewFromInt(10).Pow(decimal.NewFromInt(int64(decimals))) + readableBalance := balanceDecimal.Div(decimalFactor) + + return readableBalance, nil +} + // GetERC20Balance 查询 ERC-20 代币余额并转换为正常单位 (使用 decimal) // tokenAddress: 代币合约地址 // accountAddress: 账户地址 diff --git a/utils/ethbalanceofhelper/balanceof_helper_test.go b/utils/ethbalanceofhelper/balanceof_helper_test.go new file mode 100644 index 0000000..7aba80c --- /dev/null +++ b/utils/ethbalanceofhelper/balanceof_helper_test.go @@ -0,0 +1,25 @@ +package ethbalanceofhelper + +import ( + "fmt" + "testing" +) + +func TestBalanceOfHelper(t *testing.T) { + api := "https://stylish-cool-fire.ethereum-sepolia.quiknode.pro/17572db4c091accfa5dc6faa0c60a805e5173459" + proxy := "http://127.0.0.1:7890" + client, err := EthClientWithProxy(api, proxy) + + if err != nil { + t.Error(err) + } + + address := "0x5079a681a2a2344f4da79a21e187d6ed075ba90a" + balance, err := GetBalance(client, "0", address, 18) + + if err != nil { + t.Error(err) + } + + fmt.Println("余额:", balance) +} diff --git a/utils/ethtransferhelper/transfer_helper.go b/utils/ethtransferhelper/transfer_helper.go index 7a778da..1bc368d 100644 --- a/utils/ethtransferhelper/transfer_helper.go +++ b/utils/ethtransferhelper/transfer_helper.go @@ -28,7 +28,7 @@ func TransferErc20( tokenAmount decimal.Decimal, tokenDecimals uint8) (*types.Transaction, error) { switch tokenAddress { - case "": + case "0": return TransferEth(client, fromPrivateKey, toAddress, tokenAmount) default: return TransferErc20Token(client, fromPrivateKey, tokenAddress, toAddress, tokenAmount, tokenDecimals) @@ -81,7 +81,7 @@ func TransferEth(client *ethclient.Client, fromPrivateKey string, toAddress stri } // 9. (预估gas+基础费用)*1.1 作为 GasLimit - gasLimit = (gasLimit + 21000) * 12 / 10 // 增加 20% + gasLimit = (gasLimit + 21000) * 19 / 10 // 增加 90% if gasLimit < 23000 { gasLimit = 23000 // 最小 Gas 限制 } @@ -182,7 +182,7 @@ func TransferErc20Token( } // 9. (预估gas+基础费用)*1.1 作为 GasLimit - gasLimit = (gasLimit + 21000) * 12 / 10 // 增加 20% + gasLimit = (gasLimit + 21000) * 19 / 10 // 增加 90% if gasLimit < 23000 { gasLimit = 23000 // 最小 Gas 限制 } @@ -274,5 +274,5 @@ func IsValidAddress(address string) bool { } checksumAddress := common.HexToAddress(address).String() - return address == checksumAddress + return strings.EqualFold(address, checksumAddress) } diff --git a/utils/excelhelper/excel_helper.go b/utils/excelhelper/excel_helper.go index a4884d5..48ced98 100644 --- a/utils/excelhelper/excel_helper.go +++ b/utils/excelhelper/excel_helper.go @@ -167,3 +167,46 @@ func MapExcelToStruct[T any](rows [][]string, headers []string) ([]T, error) { return results, nil } + +// 获取上传文件的数据 +func GetExcelContent(c *gin.Context) (dataRows [][]string, headers []string, err error) { + // 获取上传的文件 + file, err := c.FormFile("file") + if err != nil { + err = errors.New("文件上传失败") + return + } + + // 打开上传的文件 + src, err := file.Open() + if err != nil { + err = errors.New("文件打开失败") + return + } + defer src.Close() + + // 使用 excelize 读取 Excel 文件 + xlFile, err := excelize.OpenReader(src) + if err != nil { + err = errors.New("读取 Excel 文件失败") + return + } + + sheetName := xlFile.GetSheetName(0) + + // 假设读取第一个工作表中的数据 + rows, err := xlFile.GetRows(sheetName) + if err != nil { + err = errors.New("读取 Excel 行数据失败") + return + } + + if len(rows) < 1 { + err = errors.New("没有数据内容") + return + } + + headers = rows[0] // First row is the header + dataRows = rows[1:] + return +}