Compare commits
	
		
			2 Commits
		
	
	
		
			fbdf54603b
			...
			68f3105dff
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 68f3105dff | |||
| f170d4ea3b | 
| @ -47,7 +47,7 @@ func (e TmRechargeLog) GetPage(c *gin.Context) { | ||||
|  | ||||
| // 创建充值订单 | ||||
| func (e TmRechargeLog) CreateOrder(c *gin.Context) { | ||||
| 	req := dto.TmRechargeCreateOrderReq{} | ||||
| 	req := dto.CustomCreateOrderReq{} | ||||
| 	s := service.TmRechargeLog{} | ||||
| 	err := e.MakeContext(c). | ||||
| 		MakeOrm(). | ||||
| @ -62,6 +62,10 @@ func (e TmRechargeLog) CreateOrder(c *gin.Context) { | ||||
|  | ||||
| 	apiKey := c.GetString("apiKey") | ||||
|  | ||||
| 	if code := req.Validate(); code != statuscode.Success { | ||||
| 		e.Error(code, nil, statuscode.ErrorMessage[code]) | ||||
| 	} | ||||
|  | ||||
| 	code := s.CreateOrder(&req, apiKey) | ||||
| 	if code != statuscode.Success { | ||||
| 		e.OK(code, statuscode.ErrorMessage[code]) | ||||
|  | ||||
							
								
								
									
										221
									
								
								app/admin/apis/tm_recharge_package.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								app/admin/apis/tm_recharge_package.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,221 @@ | ||||
| package apis | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/api" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" | ||||
| 	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response" | ||||
|  | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/app/admin/service" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	"go-admin/common/actions" | ||||
| 	"go-admin/common/statuscode" | ||||
| ) | ||||
|  | ||||
| type TmRechargePackage struct { | ||||
| 	api.Api | ||||
| } | ||||
|  | ||||
| // GetPage 获取tm_recharge_package列表 | ||||
| // @Summary 获取tm_recharge_package列表 | ||||
| // @Description 获取tm_recharge_package列表 | ||||
| // @Tags tm_recharge_package | ||||
| // @Param platformId query int64 false "平台id" | ||||
| // @Param status query int64 false "状态 1-启用 2-禁用" | ||||
| // @Param pageSize query int false "页条数" | ||||
| // @Param pageIndex query int false "页码" | ||||
| // @Success 200 {object} response.Response{data=response.Page{list=[]models.TmRechargePackage}} "{"code": 200, "data": [...]}" | ||||
| // @Router /api/v1/tm-recharge-package [get] | ||||
| // @Security Bearer | ||||
| func (e TmRechargePackage) GetPage(c *gin.Context) { | ||||
| 	req := dto.TmRechargePackageGetPageReq{} | ||||
| 	s := service.TmRechargePackage{} | ||||
| 	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 | ||||
| 	} | ||||
|  | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
| 	list := make([]models.TmRechargePackage, 0) | ||||
| 	var count int64 | ||||
|  | ||||
| 	err = s.GetPage(&req, p, &list, &count) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("获取tm_recharge_package失败,\r\n失败信息 %s", err.Error())) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功") | ||||
| } | ||||
|  | ||||
| // Get 获取tm_recharge_package | ||||
| // @Summary 获取tm_recharge_package | ||||
| // @Description 获取tm_recharge_package | ||||
| // @Tags tm_recharge_package | ||||
| // @Param id path int false "id" | ||||
| // @Success 200 {object} response.Response{data=models.TmRechargePackage} "{"code": 200, "data": [...]}" | ||||
| // @Router /api/v1/tm-recharge-package/{id} [get] | ||||
| // @Security Bearer | ||||
| func (e TmRechargePackage) Get(c *gin.Context) { | ||||
| 	req := dto.TmRechargePackageGetReq{} | ||||
| 	s := service.TmRechargePackage{} | ||||
| 	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 | ||||
| 	} | ||||
| 	var object models.TmRechargePackage | ||||
|  | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
| 	err = s.Get(&req, p, &object) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("获取tm_recharge_package失败,\r\n失败信息 %s", err.Error())) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	e.OK(object, "查询成功") | ||||
| } | ||||
|  | ||||
| // Insert 创建tm_recharge_package | ||||
| // @Summary 创建tm_recharge_package | ||||
| // @Description 创建tm_recharge_package | ||||
| // @Tags tm_recharge_package | ||||
| // @Accept application/json | ||||
| // @Product application/json | ||||
| // @Param data body dto.TmRechargePackageInsertReq true "data" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}" | ||||
| // @Router /api/v1/tm-recharge-package [post] | ||||
| // @Security Bearer | ||||
| func (e TmRechargePackage) Insert(c *gin.Context) { | ||||
| 	req := dto.TmRechargePackageInsertReq{} | ||||
| 	s := service.TmRechargePackage{} | ||||
| 	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.SetCreateBy(user.GetUserId(c)) | ||||
|  | ||||
| 	err = s.Insert(&req) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("创建tm_recharge_package失败,\r\n失败信息 %s", err.Error())) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	e.OK(req.GetId(), "创建成功") | ||||
| } | ||||
|  | ||||
| // Update 修改tm_recharge_package | ||||
| // @Summary 修改tm_recharge_package | ||||
| // @Description 修改tm_recharge_package | ||||
| // @Tags tm_recharge_package | ||||
| // @Accept application/json | ||||
| // @Product application/json | ||||
| // @Param id path int true "id" | ||||
| // @Param data body dto.TmRechargePackageUpdateReq true "body" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}" | ||||
| // @Router /api/v1/tm-recharge-package/{id} [put] | ||||
| // @Security Bearer | ||||
| func (e TmRechargePackage) Update(c *gin.Context) { | ||||
| 	req := dto.TmRechargePackageUpdateReq{} | ||||
| 	s := service.TmRechargePackage{} | ||||
| 	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)) | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
|  | ||||
| 	err = s.Update(&req, p) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("修改tm_recharge_package失败,\r\n失败信息 %s", err.Error())) | ||||
| 		return | ||||
| 	} | ||||
| 	e.OK(req.GetId(), "修改成功") | ||||
| } | ||||
|  | ||||
| // Delete 删除tm_recharge_package | ||||
| // @Summary 删除tm_recharge_package | ||||
| // @Description 删除tm_recharge_package | ||||
| // @Tags tm_recharge_package | ||||
| // @Param data body dto.TmRechargePackageDeleteReq true "body" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}" | ||||
| // @Router /api/v1/tm-recharge-package [delete] | ||||
| // @Security Bearer | ||||
| func (e TmRechargePackage) Delete(c *gin.Context) { | ||||
| 	s := service.TmRechargePackage{} | ||||
| 	req := dto.TmRechargePackageDeleteReq{} | ||||
| 	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)) | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
|  | ||||
| 	err = s.Remove(&req, p) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("删除tm_recharge_package失败,\r\n失败信息 %s", err.Error())) | ||||
| 		return | ||||
| 	} | ||||
| 	e.OK(req.GetId(), "删除成功") | ||||
| } | ||||
|  | ||||
| // GetFrontList 获取前端列表 | ||||
| func (e TmRechargePackage) GetFrontList(c *gin.Context) { | ||||
| 	req := dto.TmRechargePackageGetListReq{} | ||||
| 	s := service.TmRechargePackage{} | ||||
| 	err := e.MakeContext(c). | ||||
| 		MakeOrm(). | ||||
| 		Bind(&req). | ||||
| 		MakeService(&s.Service). | ||||
| 		Errors | ||||
| 	if err != nil { | ||||
| 		e.Logger.Error(err) | ||||
| 		e.Error(statuscode.ServerError, nil, statuscode.ErrorMessage[statuscode.ServerError]) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	userId := user.GetUserId(c) | ||||
| 	list := make([]dto.TmRechargePackageGetListResp, 0) | ||||
|  | ||||
| 	code := s.GetFrontList(&req, userId, &list) | ||||
| 	if code != statuscode.Success { | ||||
| 		e.Error(code, nil, statuscode.ErrorMessage[code]) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	e.OK(list, "success") | ||||
| } | ||||
| @ -16,7 +16,7 @@ type Translate struct { | ||||
| } | ||||
|  | ||||
| // 公开翻译接口 | ||||
| func (e *Translate) Translate(c *gin.Context) { | ||||
| func (e Translate) Translate(c *gin.Context) { | ||||
| 	req := dto.TranslateReq{} | ||||
| 	s := service.TranslatorService{} | ||||
|  | ||||
| @ -50,7 +50,7 @@ func (e *Translate) Translate(c *gin.Context) { | ||||
| } | ||||
|  | ||||
| // 获取个人翻译统计 | ||||
| func (e *Translate) GetTranslateStatistic(c *gin.Context) { | ||||
| func (e Translate) GetTranslateStatistic(c *gin.Context) { | ||||
| 	req := dto.TranslateStatisticReq{} | ||||
| 	s := service.TmMember{} | ||||
| 	err := e.MakeContext(c). | ||||
|  | ||||
| @ -14,7 +14,7 @@ type TmPlatform struct { | ||||
| 	ApiBaseUrl  string          `json:"apiBaseUrl" gorm:"type:varchar(500);comment:平台接口地址"` | ||||
| 	Description string          `json:"description" gorm:"type:varchar(255);comment:描述"` | ||||
| 	Code        string          `json:"code" gorm:"type:varchar(20);comment:平台编码(字典 tm_platform)"` | ||||
| 	Character   string          `json:"character" gorm:"type:int;comment:字符数"` | ||||
| 	Character   int             `json:"character" gorm:"type:int;comment:字符数"` | ||||
| 	Price       decimal.Decimal `json:"price" gorm:"type:decimal(10,2);comment:单价"` | ||||
| 	models.ModelTime | ||||
| 	models.ControlBy | ||||
|  | ||||
| @ -10,19 +10,20 @@ import ( | ||||
| type TmRechargeLog struct { | ||||
| 	models.Model | ||||
|  | ||||
| 	Type           int             `json:"type" gorm:"column:type;type:tinyint;not null;comment:类型 1-充值 2-后台充值 3-赠送"` | ||||
| 	OrderNo        string          `json:"orderNo" gorm:"column:order_no;type:varchar(36);not null;comment:订单号"` | ||||
| 	UserId         int             `json:"userId" gorm:"column:user_id;type:bigint;not null;comment:用户id"` | ||||
| 	MemberId       int             `json:"memberId" gorm:"column:member_id;type:bigint;not null;comment:翻译用户id"` | ||||
| 	PlatformId     int             `json:"platformId" gorm:"column:platform_id;type:bigint;not null;comment:平台id"` | ||||
| 	Status         int             `json:"status" gorm:"column:status;type:tinyint;not null;comment:状态 1-待支付 2-已支付 3-已取消 4-申请退款 5-已退款 6-已过期"` | ||||
| 	TotalChars     int             `json:"totalChars" gorm:"column:total_chars;type:bigint;not null;comment:充值字符数"` | ||||
| 	TxHash         string          `json:"txHash" gorm:"column:tx_hash;type:varchar(64);comment:交易hash"` | ||||
| 	Amount         decimal.Decimal `json:"amount" gorm:"column:amount;type:decimal(10,6);not null;comment:充值金额U"` | ||||
| 	ReceiveChannel string          `json:"receiveChannel" gorm:"column:receive_channel;type:varchar(100);not null;comment:充值渠道"` | ||||
| 	ReceiveAddress string          `json:"receiveAddress" gorm:"column:receive_address;type:varchar(100);not null;comment:充值地址"` | ||||
| 	PayTime        *time.Time      `json:"payTime" gorm:"column:pay_time;type:datetime;comment:支付时间"` | ||||
| 	ExpireAt       time.Time       `json:"expireAt" gorm:"column:expire_at;type:datetime;not null;comment:过期时间"` | ||||
| 	Type            int             `json:"type" gorm:"column:type;type:tinyint;not null;comment:类型 1-充值 2-后台充值 3-赠送"` | ||||
| 	OrderNo         string          `json:"orderNo" gorm:"column:order_no;type:varchar(36);not null;comment:订单号"` | ||||
| 	UserId          int             `json:"userId" gorm:"column:user_id;type:bigint;not null;comment:用户id"` | ||||
| 	MemberId        int             `json:"memberId" gorm:"column:member_id;type:bigint;not null;comment:翻译用户id"` | ||||
| 	PlatformId      int             `json:"platformId" gorm:"column:platform_id;type:bigint;not null;comment:平台id"` | ||||
| 	Status          int             `json:"status" gorm:"column:status;type:tinyint;not null;comment:状态 1-待支付 2-已支付 3-已取消 4-申请退款 5-已退款 6-已过期"` | ||||
| 	TotalChars      int             `json:"totalChars" gorm:"column:total_chars;type:bigint;not null;comment:充值字符数"` | ||||
| 	TxHash          string          `json:"txHash" gorm:"column:tx_hash;type:varchar(64);comment:交易hash"` | ||||
| 	Amount          decimal.Decimal `json:"amount" gorm:"column:amount;type:decimal(10,6);not null;comment:充值金额U"` | ||||
| 	ReceiveChannel  string          `json:"receiveChannel" gorm:"column:receive_channel;type:varchar(100);not null;comment:充值渠道"` | ||||
| 	ReceiveAddress  string          `json:"receiveAddress" gorm:"column:receive_address;type:varchar(100);not null;comment:充值地址"` | ||||
| 	PayTime         *time.Time      `json:"payTime" gorm:"column:pay_time;type:datetime;comment:支付时间"` | ||||
| 	ExpireAt        time.Time       `json:"expireAt" gorm:"column:expire_at;type:datetime;not null;comment:过期时间"` | ||||
| 	OrderExpireTime *time.Time      `json:"orderExpireTime" gorm:"column:order_expire_time;type:datetime;comment:订单过期时间"` | ||||
| 	models.ModelTime | ||||
| 	models.ControlBy | ||||
| } | ||||
|  | ||||
							
								
								
									
										30
									
								
								app/admin/models/tm_recharge_package.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								app/admin/models/tm_recharge_package.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| package models | ||||
|  | ||||
| import ( | ||||
| 	"go-admin/common/models" | ||||
|  | ||||
| 	"github.com/shopspring/decimal" | ||||
| ) | ||||
|  | ||||
| type TmRechargePackage struct { | ||||
| 	models.Model | ||||
|  | ||||
| 	PlatformId int             `json:"platformId" gorm:"type:bigint;comment:平台id"` | ||||
| 	Amount     decimal.Decimal `json:"amount" gorm:"type:decimal(10,6);comment:套餐金额(U)"` | ||||
| 	Status     int             `json:"status" gorm:"type:tinyint;comment:状态 1-启用 2-禁用"` | ||||
| 	models.ModelTime | ||||
| 	models.ControlBy | ||||
| } | ||||
|  | ||||
| func (TmRechargePackage) TableName() string { | ||||
| 	return "tm_recharge_package" | ||||
| } | ||||
|  | ||||
| func (e *TmRechargePackage) Generate() models.ActiveRecord { | ||||
| 	o := *e | ||||
| 	return &o | ||||
| } | ||||
|  | ||||
| func (e *TmRechargePackage) GetId() interface{} { | ||||
| 	return e.Id | ||||
| } | ||||
							
								
								
									
										27
									
								
								app/admin/router/tm_recharge_package.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/admin/router/tm_recharge_package.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| package router | ||||
|  | ||||
| import ( | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" | ||||
|  | ||||
| 	"go-admin/app/admin/apis" | ||||
| 	"go-admin/common/middleware" | ||||
| 	"go-admin/common/actions" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	routerCheckRole = append(routerCheckRole, registerTmRechargePackageRouter) | ||||
| } | ||||
|  | ||||
| // registerTmRechargePackageRouter | ||||
| func registerTmRechargePackageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { | ||||
| 	api := apis.TmRechargePackage{} | ||||
| 	r := v1.Group("/tm-recharge-package").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) | ||||
| 	{ | ||||
| 		r.GET("", actions.PermissionAction(), api.GetPage) | ||||
| 		r.GET("/:id", actions.PermissionAction(), api.Get) | ||||
| 		r.POST("", api.Insert) | ||||
| 		r.PUT("/:id", actions.PermissionAction(), api.Update) | ||||
| 		r.DELETE("", api.Delete) | ||||
| 	} | ||||
| } | ||||
| @ -46,7 +46,7 @@ type TmPlatformInsertReq struct { | ||||
| 	ApiBaseUrl  string          `json:"apiBaseUrl" comment:"平台接口地址"` | ||||
| 	Description string          `json:"description" comment:"描述"` | ||||
| 	Code        string          `json:"code" comment:"平台编码(字典 tm_platform)"` | ||||
| 	Character   string          `json:"character" comment:"字符数"` | ||||
| 	Character   int             `json:"character" comment:"字符数"` | ||||
| 	Price       decimal.Decimal `json:"price" comment:"单价"` | ||||
| 	common.ControlBy | ||||
| } | ||||
| @ -83,7 +83,7 @@ type TmPlatformUpdateReq struct { | ||||
| 	ApiBaseUrl  string          `json:"apiBaseUrl" comment:"平台接口地址"` | ||||
| 	Description string          `json:"description" comment:"描述"` | ||||
| 	Code        string          `json:"code" comment:"平台编码(字典 tm_platform)"` | ||||
| 	Character   string          `json:"character" comment:"字符数"` | ||||
| 	Character   int             `json:"character" comment:"字符数"` | ||||
| 	Price       decimal.Decimal `json:"price" comment:"单价"` | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| @ -5,6 +5,7 @@ import ( | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/common/dto" | ||||
| 	common "go-admin/common/models" | ||||
| 	"go-admin/common/statuscode" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/shopspring/decimal" | ||||
| @ -93,7 +94,7 @@ type TmRechargeLogResp struct { | ||||
| 	CreatedAt      string          `json:"createdAt"` | ||||
| } | ||||
|  | ||||
| // 用户充值订单创建请求参数 | ||||
| // 后台-用户充值订单创建请求参数 | ||||
| type TmRechargeCreateOrderReq struct { | ||||
| 	Type           int             `json:"type" comment:"充值类型 1-用户充值 2-平台充值"` | ||||
| 	MemberId       int             `json:"memberId" comment:"会员id"` | ||||
| @ -108,6 +109,25 @@ type TmRechargeCreateOrderReq struct { | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| // 用户充值订单创建请求参数 | ||||
| type CustomCreateOrderReq struct { | ||||
| 	UserId     int             `json:"userId" comment:"用户id"` | ||||
| 	Amount     decimal.Decimal `json:"amount" comment:"充值金额"` | ||||
| 	PlatformId int             `json:"platformId" comment:"平台id"` | ||||
| } | ||||
|  | ||||
| func (e *CustomCreateOrderReq) Validate() int { | ||||
| 	if e.Amount.Cmp(decimal.Zero) <= 0 { | ||||
| 		return statuscode.RechargeAmountMustBeGreaterThanZero | ||||
| 	} | ||||
|  | ||||
| 	if e.PlatformId <= 0 { | ||||
| 		return statuscode.PlatformNotSupport | ||||
| 	} | ||||
|  | ||||
| 	return statuscode.Success | ||||
| } | ||||
|  | ||||
| func (e *TmRechargeCreateOrderReq) Validate() error { | ||||
| 	if e.ExpireDays <= 0 { | ||||
| 		return errors.New("过期天数必须大于0") | ||||
| @ -163,3 +183,25 @@ type TmRechargeLogFrontResp struct { | ||||
| 	TotalCharater  int    `json:"totalCharater"` | ||||
| 	RemainCharater int    `json:"remainCharater"` | ||||
| } | ||||
|  | ||||
| // TRC20Transfer 结构体用于解析 TRC20 转账记录 | ||||
| type TRC20Transfer struct { | ||||
| 	TransactionID string `json:"transaction_id"` | ||||
| 	BlockNumber   int64  `json:"block_number"` | ||||
| 	Timestamp     int64  `json:"block_timestamp"` | ||||
| 	FromAddress   string `json:"from"` | ||||
| 	ToAddress     string `json:"to"` | ||||
| 	Value         string `json:"value"` | ||||
| 	TokenInfo     struct { | ||||
| 		Symbol   string `json:"symbol"` | ||||
| 		Address  string `json:"address"` | ||||
| 		Decimals int    `json:"decimals"` | ||||
| 	} `json:"token_info"` | ||||
| } | ||||
|  | ||||
| type TmRechargeCallbackReq struct { | ||||
| 	PayableAmount decimal.Decimal `json:"payable_amount"` | ||||
| 	FromAddress   string          `json:"from_address"` | ||||
| 	ToAddress     string          `json:"to_address"` | ||||
| 	TxHash        string          `json:"tx_hash"` | ||||
| } | ||||
|  | ||||
							
								
								
									
										104
									
								
								app/admin/service/dto/tm_recharge_package.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								app/admin/service/dto/tm_recharge_package.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,104 @@ | ||||
| package dto | ||||
|  | ||||
| import ( | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/common/dto" | ||||
| 	common "go-admin/common/models" | ||||
|  | ||||
| 	"github.com/shopspring/decimal" | ||||
| ) | ||||
|  | ||||
| type TmRechargePackageGetPageReq struct { | ||||
| 	dto.Pagination `search:"-"` | ||||
| 	PlatformId     int64 `form:"platformId"  search:"type:exact;column:platform_id;table:tm_recharge_package" comment:"平台id"` | ||||
| 	Status         int64 `form:"status"  search:"type:exact;column:status;table:tm_recharge_package" comment:"状态 1-启用 2-禁用"` | ||||
| 	TmRechargePackageOrder | ||||
| } | ||||
|  | ||||
| type TmRechargePackageOrder struct { | ||||
| 	Id         string `form:"idOrder"  search:"type:order;column:id;table:tm_recharge_package"` | ||||
| 	PlatformId string `form:"platformIdOrder"  search:"type:order;column:platform_id;table:tm_recharge_package"` | ||||
| 	Amount     string `form:"amountOrder"  search:"type:order;column:amount;table:tm_recharge_package"` | ||||
| 	Status     string `form:"statusOrder"  search:"type:order;column:status;table:tm_recharge_package"` | ||||
| 	CreateBy   string `form:"createByOrder"  search:"type:order;column:create_by;table:tm_recharge_package"` | ||||
| 	UpdateBy   string `form:"updateByOrder"  search:"type:order;column:update_by;table:tm_recharge_package"` | ||||
| 	CreatedAt  string `form:"createdAtOrder"  search:"type:order;column:created_at;table:tm_recharge_package"` | ||||
| 	UpdatedAt  string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:tm_recharge_package"` | ||||
| 	DeletedAt  string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:tm_recharge_package"` | ||||
| } | ||||
|  | ||||
| func (m *TmRechargePackageGetPageReq) GetNeedSearch() interface{} { | ||||
| 	return *m | ||||
| } | ||||
|  | ||||
| type TmRechargePackageInsertReq struct { | ||||
| 	Id         int             `json:"-" comment:"主键id"` // 主键id | ||||
| 	PlatformId int             `json:"platformId" comment:"平台id"` | ||||
| 	Amount     decimal.Decimal `json:"amount" comment:"套餐金额(U)"` | ||||
| 	Status     int             `json:"status" comment:"状态 1-启用 2-禁用"` | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| func (s *TmRechargePackageInsertReq) Generate(model *models.TmRechargePackage) { | ||||
| 	if s.Id == 0 { | ||||
| 		model.Model = common.Model{Id: s.Id} | ||||
| 	} | ||||
| 	model.PlatformId = s.PlatformId | ||||
| 	model.Amount = s.Amount | ||||
| 	model.Status = s.Status | ||||
| 	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 | ||||
| } | ||||
|  | ||||
| func (s *TmRechargePackageInsertReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| type TmRechargePackageUpdateReq struct { | ||||
| 	Id         int             `uri:"id" comment:"主键id"` // 主键id | ||||
| 	PlatformId int             `json:"platformId" comment:"平台id"` | ||||
| 	Amount     decimal.Decimal `json:"amount" comment:"套餐金额(U)"` | ||||
| 	Status     int             `json:"status" comment:"状态 1-启用 2-禁用"` | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| func (s *TmRechargePackageUpdateReq) Generate(model *models.TmRechargePackage) { | ||||
| 	if s.Id == 0 { | ||||
| 		model.Model = common.Model{Id: s.Id} | ||||
| 	} | ||||
| 	model.PlatformId = s.PlatformId | ||||
| 	model.Amount = s.Amount | ||||
| 	model.Status = s.Status | ||||
| 	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 | ||||
| } | ||||
|  | ||||
| func (s *TmRechargePackageUpdateReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| // TmRechargePackageGetReq 功能获取请求参数 | ||||
| type TmRechargePackageGetReq struct { | ||||
| 	Id int `uri:"id"` | ||||
| } | ||||
|  | ||||
| func (s *TmRechargePackageGetReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| // TmRechargePackageDeleteReq 功能删除请求参数 | ||||
| type TmRechargePackageDeleteReq struct { | ||||
| 	Ids []int `json:"ids"` | ||||
| } | ||||
|  | ||||
| func (s *TmRechargePackageDeleteReq) GetId() interface{} { | ||||
| 	return s.Ids | ||||
| } | ||||
|  | ||||
| type TmRechargePackageGetListReq struct { | ||||
| 	PlatformId int `form:"platformId"  comment:"平台id"` | ||||
| } | ||||
|  | ||||
| type TmRechargePackageGetListResp struct { | ||||
| 	Id         int             `json:"id" comment:"主键id"` // 主键id | ||||
| 	PlatformId int             `json:"platformId" comment:"平台id"` | ||||
| 	Amount     decimal.Decimal `json:"amount" comment:"套餐金额(U)"` | ||||
| } | ||||
| @ -0,0 +1,12 @@ | ||||
| -- KEYS[1] = locked_payment_amounts | ||||
| -- KEYS[2] = locked_payment_expire_queue | ||||
| -- ARGV[1] = amount(字符串) | ||||
| -- ARGV[2] = expire_ts | ||||
|  | ||||
| if redis.call("HEXISTS", KEYS[1], ARGV[1]) == 1 then | ||||
|   return 0 | ||||
| end | ||||
|  | ||||
| redis.call("HSET", KEYS[1], ARGV[1], ARGV[2]) | ||||
| redis.call("ZADD", KEYS[2], ARGV[2], ARGV[1]) | ||||
| return 1 | ||||
| @ -0,0 +1,80 @@ | ||||
| package receiveaddressmanager | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/go-redis/redis/v8" | ||||
| ) | ||||
|  | ||||
| func LockAmount(ctx context.Context, rdb *redis.Client, amount string, ttl time.Duration) (bool, error) { | ||||
| 	lockKey := "locked_payment_amounts" | ||||
| 	queueKey := "locked_payment_expire_queue" | ||||
| 	expireTs := time.Now().Add(ttl).Unix() | ||||
|  | ||||
| 	script := ` | ||||
| 	if redis.call("HEXISTS", KEYS[1], ARGV[1]) == 1 then return 0 end | ||||
| 	redis.call("HSET", KEYS[1], ARGV[1], ARGV[2]) | ||||
| 	redis.call("ZADD", KEYS[2], ARGV[2], ARGV[1]) | ||||
| 	return 1 | ||||
| 	` | ||||
|  | ||||
| 	ok, err := rdb.Eval(ctx, script, []string{lockKey, queueKey}, amount, expireTs).Bool() | ||||
| 	return ok, err | ||||
| } | ||||
|  | ||||
| // 金额分配逻辑 | ||||
| func AllocatePaymentAmount(ctx context.Context, rdb *redis.Client, baseAmount float64, timeInterval int) (string, error) { | ||||
| 	ttl := time.Duration(timeInterval+1) * time.Minute | ||||
|  | ||||
| 	for i := 0; i < 100; i++ { | ||||
| 		amount := baseAmount + float64(i)*0.0001 | ||||
| 		amountStr := fmt.Sprintf("%.4f", amount) | ||||
| 		ok, err := LockAmount(ctx, rdb, amountStr, ttl) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| 		if ok { | ||||
| 			return amountStr, nil | ||||
| 		} | ||||
| 	} | ||||
| 	return "", errors.New("无法锁定可用金额,请稍后再试") | ||||
| } | ||||
|  | ||||
| // 清理过期锁 | ||||
| func CleanExpiredAmountLocks(ctx context.Context, rdb *redis.Client) error { | ||||
| 	now := time.Now().Unix() | ||||
| 	zsetKey := "locked_payment_expire_queue" | ||||
| 	hashKey := "locked_payment_amounts" | ||||
|  | ||||
| 	amounts, err := rdb.ZRangeByScore(ctx, zsetKey, &redis.ZRangeBy{ | ||||
| 		Min: "-inf", | ||||
| 		Max: fmt.Sprintf("%d", now), | ||||
| 	}).Result() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if len(amounts) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// 删除已过期锁 | ||||
|  | ||||
| 	if _, err := rdb.HDel(ctx, hashKey, amounts...).Result(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if _, err := rdb.ZRem(ctx, zsetKey, stringSliceToInterface(amounts)...).Result(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func stringSliceToInterface(slice []string) []interface{} { | ||||
| 	result := make([]interface{}, len(slice)) | ||||
| 	for i, v := range slice { | ||||
| 		result[i] = v | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
| @ -7,8 +7,10 @@ import ( | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	"go-admin/app/admin/service/quota_manager" | ||||
| 	receiveaddressmanager "go-admin/app/admin/service/receive_address_manager" | ||||
| 	"go-admin/common/actions" | ||||
| 	cDto "go-admin/common/dto" | ||||
| 	rediskey "go-admin/common/redis_key" | ||||
| 	"go-admin/common/statuscode" | ||||
| 	"go-admin/utils/redishelper" | ||||
| 	"go-admin/utils/utility" | ||||
| @ -17,6 +19,8 @@ import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/service" | ||||
| 	"github.com/go-redis/redis/v8" | ||||
| 	"github.com/shopspring/decimal" | ||||
| 	"gorm.io/gorm" | ||||
| ) | ||||
|  | ||||
| @ -149,28 +153,155 @@ func (e *TmRechargeLog) CreateOrderJudge(req *dto.TmRechargeCreateOrderReq) (mod | ||||
| 	return member, platform, memberPlatform, statuscode.Success | ||||
| } | ||||
|  | ||||
| // 用户发起充值 | ||||
| // 用户自己发起充值 | ||||
| // return code | ||||
| func (e TmRechargeLog) CreateOrder(req *dto.TmRechargeCreateOrderReq, apiKey string) int { | ||||
| 	// ctx := context.Background() | ||||
| 	// var data models.TmRechargeLog | ||||
| 	// member, platform, memberPlatform, code := e.CreateOrderJudge(req) | ||||
| func (e TmRechargeLog) CreateOrder(req *dto.CustomCreateOrderReq, apiKey string) int { | ||||
| 	ctx := context.Background() | ||||
| 	var amountStr string | ||||
| 	// var errReturn bool | ||||
|  | ||||
| 	// if code != statuscode.Success { | ||||
| 	// 	return code | ||||
| 	// } | ||||
| 	// req.Generate(&data) | ||||
| 	// now := time.Now() | ||||
| 	// data.OrderNo = utility.GenerateTraceID() | ||||
| 	// data.Type = 1 | ||||
| 	// data.Status = 1 | ||||
| 	// data.UserId = member.UserId | ||||
| 	// data.ExpireAt = time.Now().AddDate(0, 0, 30) | ||||
| 	// data.PaymentTime = &now | ||||
| 	//todo 如果没有成功取消金额锁 | ||||
| 	// defer func() { | ||||
| 	// 	if amountStr != "" && errReturn { | ||||
|  | ||||
| 	// 	} | ||||
| 	// }() | ||||
|  | ||||
| 	memberService := TmMember{Service: e.Service} | ||||
| 	member := models.TmMember{} | ||||
| 	if err1 := memberService.GetByUserId(req.UserId, &member); err1 != nil { | ||||
| 		e.Log.Errorf("获取翻译用户失败 :%v", err1) | ||||
| 		return statuscode.NotFindMember | ||||
| 	} else if member.Id == 0 { | ||||
| 		e.Log.Errorf("获取翻译用户失败 用户不存在") | ||||
| 	} | ||||
|  | ||||
| 	configService := SysConfig{Service: e.Service} | ||||
| 	config := dto.GetSysConfigByKEYForServiceResp{} | ||||
| 	orderExpireConfig := dto.GetSysConfigByKEYForServiceResp{} | ||||
| 	configReq := dto.SysConfigByKeyReq{} | ||||
| 	orderExpireConfigReq := dto.SysConfigByKeyReq{} | ||||
| 	configReq.ConfigKey = "trx_receive_address" | ||||
| 	orderExpireConfigReq.ConfigKey = "order_expire_minute" | ||||
|  | ||||
| 	err := configService.GetWithKey(&configReq, &config) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("获取配置信息失败:%s \r\n", err.Error()) | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
|  | ||||
| 	if err := configService.GetWithKey(&orderExpireConfigReq, &orderExpireConfig); err != nil { | ||||
| 		e.Log.Errorf("获取订单过期时间配置失败 %v", err) | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
|  | ||||
| 	timeInterval, err := strconv.Atoi(orderExpireConfig.ConfigValue) | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("获取订单过期时间失败 %v", err) | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
|  | ||||
| 	createReq := dto.TmRechargeCreateOrderReq{} | ||||
| 	createReq.MemberId = member.Id | ||||
| 	createReq.Amount = req.Amount | ||||
| 	createReq.PlatformId = req.PlatformId | ||||
| 	createReq.ReceiveAddress = config.ConfigValue | ||||
| 	createReq.ReceiveChannel = "TRX" | ||||
| 	createReq.Type = 1 | ||||
| 	createReq.UserId = req.UserId | ||||
|  | ||||
| 	amountStr, err = receiveaddressmanager.AllocatePaymentAmount(ctx, redishelper.DefaultRedis.GetClient(), req.Amount.InexactFloat64(), timeInterval) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("分配可用金额失败:%v \r\n", err) | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
|  | ||||
| 	createReq.Amount, err = decimal.NewFromString(amountStr) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("转换可用金额失败:%v \r\n", err) | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
|  | ||||
| 	_, platform, _, code := e.CreateOrderJudge(&createReq) | ||||
|  | ||||
| 	if code != statuscode.Success { | ||||
| 		return code | ||||
| 	} | ||||
|  | ||||
| 	data := models.TmRechargeLog{} | ||||
| 	data.Amount = createReq.Amount | ||||
| 	platformCharacter := int64(platform.Character * 1000000) | ||||
| 	data.TotalChars = int(createReq.Amount.Div(platform.Price).Mul(decimal.NewFromInt(platformCharacter)).IntPart()) | ||||
| 	now := time.Now() | ||||
| 	data.OrderNo = utility.GenerateTraceID() | ||||
| 	data.Type = createReq.Type | ||||
| 	data.Status = 1 | ||||
| 	data.UserId = member.UserId | ||||
| 	data.PlatformId = platform.Id | ||||
| 	data.ReceiveAddress = createReq.ReceiveAddress | ||||
| 	data.ReceiveChannel = createReq.ReceiveChannel | ||||
| 	orderExpireDruation := time.Duration(timeInterval) * time.Minute | ||||
| 	orderExpireTime := time.Now().Add(orderExpireDruation) | ||||
| 	data.OrderExpireTime = &orderExpireTime | ||||
| 	data.ExpireAt = time.Now().AddDate(0, 0, 30) | ||||
| 	data.PayTime = &now | ||||
|  | ||||
| 	cacheExpireDuration := time.Duration(timeInterval+1) * time.Minute | ||||
| 	key := fmt.Sprintf(rediskey.TM_RECHARGE_PRE_ORDER, amountStr) | ||||
|  | ||||
| 	err = e.Orm.Transaction(func(tx *gorm.DB) error { | ||||
| 		if err1 := e.Orm.Model(&models.TmRechargeLog{}).Save(&data).Error; err1 != nil { | ||||
| 			e.Log.Errorf("发起充值记录失败 error:%s \r\n", err1) | ||||
| 			return err1 | ||||
| 		} | ||||
|  | ||||
| 		if err1 := redishelper.DefaultRedis.SetStringExpire(key, data.OrderNo, cacheExpireDuration); err1 != nil { | ||||
| 			e.Log.Errorf("设置预充值订单缓存失败 error:%s \r\n") | ||||
| 			return err1 | ||||
| 		} | ||||
|  | ||||
| 		return nil | ||||
| 	}) | ||||
|  | ||||
| 	return statuscode.Success | ||||
| } | ||||
|  | ||||
| // 充值回调 | ||||
| func (e *TmRechargeLog) PayCallBack(logs *[]dto.TmRechargeCallbackReq) error { | ||||
| 	for _, log := range *logs { | ||||
| 		key := fmt.Sprintf(rediskey.TM_RECHARGE_PRE_ORDER, log.PayableAmount.String()) | ||||
| 		orderNo, err := redishelper.DefaultRedis.GetString(key) | ||||
|  | ||||
| 		if err != nil { | ||||
| 			if err != redis.Nil { | ||||
| 				e.Log.Errorf("获取预充值订单失败 error:%s \r\n", err) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		var data models.TmRechargeLog | ||||
| 		if err := e.Orm.Model(&models.TmRechargeLog{}).Where("order_no = ?", orderNo).First(&data).Error; err != nil { | ||||
| 			e.Log.Errorf("获取充值记录失败 error:%s \r\n", err) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if data.Status == 1 { | ||||
|  | ||||
| 		} else { | ||||
| 			e.Log.Errorf("订单状态异常:%s 状态:%d\r\n", orderNo, data.Status) | ||||
| 		} | ||||
|  | ||||
| 		if err := redishelper.DefaultRedis.DeleteString(key); err != nil { | ||||
| 			e.Log.Errorf("删除预充值订单缓存失败 error:%s \r\n", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // 分页查询 | ||||
| func (e *TmRechargeLog) GetPage(req *dto.TmRechargeLogGetPageReq, p *actions.DataPermission, datas *[]dto.TmRechargeLogResp, count *int64) error { | ||||
| 	var err error | ||||
|  | ||||
							
								
								
									
										134
									
								
								app/admin/service/tm_recharge_package.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								app/admin/service/tm_recharge_package.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,134 @@ | ||||
| package service | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
|  | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/service" | ||||
| 	"gorm.io/gorm" | ||||
|  | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	"go-admin/common/actions" | ||||
| 	cDto "go-admin/common/dto" | ||||
| 	"go-admin/common/statuscode" | ||||
| ) | ||||
|  | ||||
| type TmRechargePackage struct { | ||||
| 	service.Service | ||||
| } | ||||
|  | ||||
| // 获取前端查看的金额 | ||||
| func (e TmRechargePackage) GetFrontList(req *dto.TmRechargePackageGetListReq, userId int, resp *[]dto.TmRechargePackageGetListResp) int { | ||||
| 	var datas []models.TmRechargePackage | ||||
|  | ||||
| 	err := e.Orm.Model(&models.TmRechargePackage{}). | ||||
| 		Where("platform_id =?", req.PlatformId). | ||||
| 		Find(&datas).Error | ||||
|  | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("TmRechargePackageService GetFrontList error:%s \r\n", err) | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
|  | ||||
| 	for _, data := range datas { | ||||
| 		respData := dto.TmRechargePackageGetListResp{ | ||||
| 			Id:         data.Id, | ||||
| 			PlatformId: data.PlatformId, | ||||
| 			Amount:     data.Amount, | ||||
| 		} | ||||
| 		*resp = append(*resp, respData) | ||||
| 	} | ||||
| 	return statuscode.Success | ||||
| } | ||||
|  | ||||
| // GetPage 获取TmRechargePackage列表 | ||||
| func (e *TmRechargePackage) GetPage(c *dto.TmRechargePackageGetPageReq, p *actions.DataPermission, list *[]models.TmRechargePackage, count *int64) error { | ||||
| 	var err error | ||||
| 	var data models.TmRechargePackage | ||||
|  | ||||
| 	err = e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| 			cDto.MakeCondition(c.GetNeedSearch()), | ||||
| 			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), | ||||
| 			actions.Permission(data.TableName(), p), | ||||
| 		). | ||||
| 		Find(list).Limit(-1).Offset(-1). | ||||
| 		Count(count).Error | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("TmRechargePackageService GetPage error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Get 获取TmRechargePackage对象 | ||||
| func (e *TmRechargePackage) Get(d *dto.TmRechargePackageGetReq, p *actions.DataPermission, model *models.TmRechargePackage) error { | ||||
| 	var data models.TmRechargePackage | ||||
|  | ||||
| 	err := e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| 			actions.Permission(data.TableName(), p), | ||||
| 		). | ||||
| 		First(model, d.GetId()).Error | ||||
| 	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { | ||||
| 		err = errors.New("查看对象不存在或无权查看") | ||||
| 		e.Log.Errorf("Service GetTmRechargePackage error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("db error:%s", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Insert 创建TmRechargePackage对象 | ||||
| func (e *TmRechargePackage) Insert(c *dto.TmRechargePackageInsertReq) error { | ||||
| 	var err error | ||||
| 	var data models.TmRechargePackage | ||||
| 	c.Generate(&data) | ||||
| 	err = e.Orm.Create(&data).Error | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("TmRechargePackageService Insert error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Update 修改TmRechargePackage对象 | ||||
| func (e *TmRechargePackage) Update(c *dto.TmRechargePackageUpdateReq, p *actions.DataPermission) error { | ||||
| 	var err error | ||||
| 	var data = models.TmRechargePackage{} | ||||
| 	e.Orm.Scopes( | ||||
| 		actions.Permission(data.TableName(), p), | ||||
| 	).First(&data, c.GetId()) | ||||
| 	c.Generate(&data) | ||||
|  | ||||
| 	db := e.Orm.Save(&data) | ||||
| 	if err = db.Error; err != nil { | ||||
| 		e.Log.Errorf("TmRechargePackageService Save error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	if db.RowsAffected == 0 { | ||||
| 		return errors.New("无权更新该数据") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Remove 删除TmRechargePackage | ||||
| func (e *TmRechargePackage) Remove(d *dto.TmRechargePackageDeleteReq, p *actions.DataPermission) error { | ||||
| 	var data models.TmRechargePackage | ||||
|  | ||||
| 	db := e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| 			actions.Permission(data.TableName(), p), | ||||
| 		).Delete(&data, d.GetId()) | ||||
| 	if err := db.Error; err != nil { | ||||
| 		e.Log.Errorf("Service RemoveTmRechargePackage error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	if db.RowsAffected == 0 { | ||||
| 		return errors.New("无权删除该数据") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @ -4,7 +4,6 @@ import ( | ||||
| 	"fmt" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	"go-admin/utils/httphelper" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| @ -63,8 +62,12 @@ func (e *DeeplTranslator) Translate(text string, sourceLang, targetLang string) | ||||
| 		"Authorization": fmt.Sprintf("DeepL-Auth-Key %s", e.config.ApiKey), | ||||
| 		"Content-Type":  "application/json", | ||||
| 	} | ||||
| 	if sourceLang != "" || strings.ToLower(sourceLang) == "auto" { | ||||
|  | ||||
| 	switch sourceLang { | ||||
| 	case "", "auto", "AUTO": | ||||
| 		requestBody["source_lang"] = "" | ||||
| 	default: | ||||
| 		requestBody["source_lang"] = sourceLang | ||||
| 	} | ||||
|  | ||||
| 	var responseData deeplTranslationResponse | ||||
|  | ||||
							
								
								
									
										103
									
								
								app/jobs/trxpayment_job.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								app/jobs/trxpayment_job.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | ||||
| package jobs | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"go-admin/app/admin/service" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	"go-admin/config" | ||||
| 	"go-admin/utils/utility" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"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(args 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 | ||||
| 	} | ||||
|  | ||||
| 	rechargeService := service.TmRechargeLog{} | ||||
| 	rechargeService.Orm = GetDb() | ||||
| 	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 | ||||
|  | ||||
| 		logs = append(logs, item) | ||||
| 	} | ||||
|  | ||||
| 	if len(logs) > 0 { | ||||
| 		err := rechargeService.PayCallBack(&logs) | ||||
|  | ||||
| 		if err != nil { | ||||
| 			logger.Error("执行完毕,err:") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	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) | ||||
| 	} | ||||
| 	resp, err := http.Get(url) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to send request: %v", err) | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	body, err := ioutil.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"` | ||||
| 	} | ||||
| 	if err := json.Unmarshal(body, &result); err != nil { | ||||
| 		return nil, fmt.Errorf("failed to unmarshal response: %v", err) | ||||
| 	} | ||||
| 	return result.Data, nil | ||||
| } | ||||
| @ -12,3 +12,8 @@ const ( | ||||
| 	//用户剩余翻译字符数 {key} 只有前缀 | ||||
| 	TM_MEMBER_REMAIN_COUNT_PURE = "tm_member_remain_count" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	//用户充值预订单 {amount} | ||||
| 	TM_RECHARGE_PRE_ORDER = "tm_recharge_pre_order:%s" | ||||
| ) | ||||
|  | ||||
| @ -10,19 +10,20 @@ type Response struct { | ||||
| } | ||||
|  | ||||
| var ErrorMessage = map[int]string{ | ||||
| 	Success:                  "success", | ||||
| 	Unauthorized:             "unauthorized", | ||||
| 	ServerError:              "server error", | ||||
| 	NotFound:                 "not found", | ||||
| 	Forbidden:                "forbidden", | ||||
| 	InvalidParams:            "invalid params", | ||||
| 	InSufficRemainChar:       "insufficent remain char", | ||||
| 	PlatformNotSupport:       "platform not support", | ||||
| 	TransactionNotAvailable:  "transaction not available", | ||||
| 	ApiUnauthorized:          "api unauthorized", | ||||
| 	NotFindMember:            "not find member", | ||||
| 	NotFindApiKey:            "not find api key", | ||||
| 	MemberPlatformNotSupport: "member platform not support", | ||||
| 	Success:                             "success", | ||||
| 	Unauthorized:                        "unauthorized", | ||||
| 	ServerError:                         "server error", | ||||
| 	NotFound:                            "not found", | ||||
| 	Forbidden:                           "forbidden", | ||||
| 	InvalidParams:                       "invalid params", | ||||
| 	InSufficRemainChar:                  "insufficent remain char", | ||||
| 	PlatformNotSupport:                  "platform not support", | ||||
| 	TransactionNotAvailable:             "transaction not available", | ||||
| 	ApiUnauthorized:                     "api unauthorized", | ||||
| 	NotFindMember:                       "not find member", | ||||
| 	NotFindApiKey:                       "not find api key", | ||||
| 	MemberPlatformNotSupport:            "member platform not support", | ||||
| 	RechargeAmountMustBeGreaterThanZero: "recharge amount must be greater than zero", | ||||
| } | ||||
|  | ||||
| const ( | ||||
| @ -44,4 +45,8 @@ const ( | ||||
| 	NotFindMember            = 30001 //未找到用户 | ||||
| 	NotFindApiKey            = 30002 //未找到api key | ||||
| 	MemberPlatformNotSupport = 30003 //用户平台不支持 | ||||
|  | ||||
| 	//================ 充值相关 =============== | ||||
| 	RechargeAmountMustBeGreaterThanZero = 40001 //充值金额必须大于0 | ||||
|  | ||||
| ) | ||||
|  | ||||
| @ -10,8 +10,9 @@ var ExtConfig Extend | ||||
| // | ||||
| // 使用方法: config.ExtConfig......即可!! | ||||
| type Extend struct { | ||||
| 	AMap AMap // 这里配置对应配置文件的结构即可 | ||||
| 	Mq   MqConfig | ||||
| 	AMap       AMap // 这里配置对应配置文件的结构即可 | ||||
| 	Mq         MqConfig | ||||
| 	TrxGridUrl string `yaml:"trx_grid_url"` | ||||
| } | ||||
|  | ||||
| type AMap struct { | ||||
|  | ||||
| @ -53,6 +53,8 @@ settings: | ||||
|       username: admin | ||||
|       password: '123456' | ||||
|       pass: "123456" | ||||
|     #trx api | ||||
|     trx_grid_url: "https://api.trongrid.io" | ||||
|   cache: | ||||
|     redis: | ||||
|       addr: 127.0.0.1:6379 | ||||
|  | ||||
| @ -1,6 +1,10 @@ | ||||
| package utility | ||||
|  | ||||
| import "strings" | ||||
| import ( | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/shopspring/decimal" | ||||
| ) | ||||
|  | ||||
| // DesensitizeGeneric 通用脱敏函数: | ||||
| // startReserveCount: 从字符串开头保留的字符数 | ||||
| @ -61,3 +65,14 @@ func DesensitizeGeneric(text string, startReserveCount int, endReserveCount int, | ||||
|  | ||||
| 	return sb.String() | ||||
| } | ||||
|  | ||||
| func StringToDecimal(val string) decimal.Decimal { | ||||
| 	cleanedNum := strings.TrimRight(val, "\x00")         // 去除空字符 | ||||
| 	cleanedNum = strings.TrimSpace(cleanedNum)           // 去除空格 | ||||
| 	cleanedNum = strings.ReplaceAll(cleanedNum, ",", "") // 去除逗号 | ||||
| 	d, err := decimal.NewFromString(cleanedNum) | ||||
| 	if err != nil { | ||||
| 		return decimal.Zero | ||||
| 	} | ||||
| 	return d | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user