2025-02-06 11:14:33 +08:00
package jobs
import (
"errors"
"fmt"
"go-admin/app/admin/models"
"go-admin/app/admin/service"
"go-admin/app/admin/service/dto"
"go-admin/common/const/rediskey"
2025-03-19 09:38:11 +08:00
"go-admin/common/global"
2025-02-06 11:14:33 +08:00
"go-admin/common/helper"
2025-10-14 19:58:59 +08:00
"go-admin/models/positiondto"
2025-03-19 09:38:11 +08:00
"go-admin/pkg/utility"
2025-02-06 11:14:33 +08:00
"time"
"github.com/bytedance/sonic"
2025-03-19 09:38:11 +08:00
"github.com/go-admin-team/go-admin-core/logger"
2025-02-06 11:14:33 +08:00
"github.com/go-admin-team/go-admin-core/sdk"
sysservice "github.com/go-admin-team/go-admin-core/sdk/service"
"gorm.io/gorm"
)
// InitJob
// 需要将定义的struct 添加到字典中;
// 字典 key 可以配置到 自动任务 调用目标 中;
func InitJob ( ) {
jobList = map [ string ] JobExec {
"ExamplesOne" : ExamplesOne { } ,
// ...
2025-02-25 16:57:59 +08:00
"DeleteExpireOrder" : DeleteExpireOrder { } , //定时删除过期数据
"UpRange" : UpRange { } , //更新涨跌幅
"InitFuturesSymbol" : InitFuturesSymbol { } , //定时更新合约交易对
"InitSpotSymbol" : InitSpotSymbol { } , //定时更新现货交易对
"ClearLogJob" : ClearLogJob { } , //定时清理日志
"AutoPlaceOrder" : AutoPlaceOrder { } , //定时下单
"LimitOrderTimeoutDuration" : LimitOrderTimeoutDuration { } , //定时取消限价单改下市价单
"ListenSymbol" : ListenSymbol { } , //交易对监听
"MemberExpirationJob" : MemberExpirationJob { } , //会员到期处理
"MemberRenwalOrderExpirationJob" : MemberRenwalOrderExpirationJob { } , //会员续费订单过期处理
2025-02-27 15:05:34 +08:00
"TrxQueryJobs" : TrxQueryJobs { } , //订单支付监听
2025-02-06 11:14:33 +08:00
}
}
// ExamplesOne
// 新添加的job 必须按照以下格式定义, 并实现Exec函数
type ExamplesOne struct {
}
func ( t ExamplesOne ) Exec ( arg interface { } ) error {
str := time . Now ( ) . Format ( timeFormat ) + " [INFO] JobCore ExamplesOne exec success"
// TODO: 这里需要注意 Examples 传入参数是 string 所以 arg.(string);请根据对应的类型进行转化;
switch arg . ( type ) {
case string :
if arg . ( string ) != "" {
fmt . Println ( "string" , arg . ( string ) )
fmt . Println ( str , arg . ( string ) )
} else {
fmt . Println ( "arg is nil" )
fmt . Println ( str , "arg is nil" )
}
break
}
return nil
}
// DeleteExpireOrder 清理过期订单
type DeleteExpireOrder struct {
}
func ( receiver DeleteExpireOrder ) Exec ( arg interface { } ) error {
dbs := sdk . Runtime . GetDb ( )
var db * gorm . DB
for _ , item := range dbs {
db = item
break
}
orders := make ( [ ] models . LinePreOrder , 0 )
2025-02-22 09:51:45 +08:00
err := db . Model ( & models . LinePreOrder { } ) . Where ( "status = '0' AND expire_time <= ? AND order_type = 0 AND pid=0" , time . Now ( ) ) . Find ( & orders ) . Error
2025-02-06 11:14:33 +08:00
if err != nil && ! errors . Is ( err , gorm . ErrRecordNotFound ) {
return err
}
for _ , order := range orders {
//删除止盈止损数据
db . Model ( & models . LinePreOrder { } ) . Where ( "pid = ?" , order . Id ) . Unscoped ( ) . Delete ( & models . LinePreOrder { } )
//删除缓存
list := dto . PreOrderRedisList {
Id : order . Id ,
Symbol : order . Symbol ,
Price : order . Price ,
Site : order . Site ,
ApiId : order . ApiId ,
OrderSn : order . OrderSn ,
QuoteSymbol : order . QuoteSymbol ,
}
marshal , _ := sonic . Marshal ( & list )
if order . SymbolType == 1 {
helper . DefaultRedis . LRem ( fmt . Sprintf ( rediskey . PreSpotOrderList , order . ExchangeType ) , string ( marshal ) )
} else {
helper . DefaultRedis . LRem ( fmt . Sprintf ( rediskey . PreFutOrderList , order . ExchangeType ) , string ( marshal ) )
}
//删除主单
db . Model ( & models . LinePreOrder { } ) . Where ( "id = ?" , order . Id ) . Unscoped ( ) . Delete ( & models . LinePreOrder { } )
}
2025-03-19 09:38:11 +08:00
//子订单 加仓、检查过期
childOrders := make ( [ ] models . LinePreOrder , 0 )
err = db . Model ( & models . LinePreOrder { } ) . Where ( "pid >0 AND order_type IN (0,4) AND status=0 AND expire_time <= ?" , time . Now ( ) ) . Select ( "id" , "order_category" , "order_type" ) . Find ( & childOrders ) . Error
if err != nil && ! errors . Is ( err , gorm . ErrRecordNotFound ) {
return err
}
removeExpirateChildOrder ( childOrders , db )
2025-02-06 11:14:33 +08:00
return nil
}
2025-03-19 09:38:11 +08:00
func removeExpirateChildOrder ( childOrders [ ] models . LinePreOrder , db * gorm . DB ) {
childOrderId := make ( [ ] int , 0 )
futAddKey := fmt . Sprintf ( rediskey . FuturesAddPositionList , global . EXCHANGE_BINANCE )
spotAddKey := fmt . Sprintf ( rediskey . SpotAddPositionList , global . EXCHANGE_BINANCE )
futReduceKey := fmt . Sprintf ( rediskey . FuturesReduceList , global . EXCHANGE_BINANCE )
spotReduceKey := fmt . Sprintf ( rediskey . SpotReduceList , global . EXCHANGE_BINANCE )
futAddPositionStr , _ := helper . DefaultRedis . GetAllList ( futAddKey )
spotAdPositionStr , _ := helper . DefaultRedis . GetAllList ( spotAddKey )
futReduceStr , _ := helper . DefaultRedis . GetAllList ( futReduceKey )
spotReduceStr , _ := helper . DefaultRedis . GetAllList ( spotReduceKey )
2025-10-14 19:58:59 +08:00
futAddPositionCache := positiondto . AddPositionList { }
spotAddPositionCache := positiondto . AddPositionList { }
futReduceCache := positiondto . ReduceListItem { }
spotReduceCache := positiondto . ReduceListItem { }
2025-03-19 09:38:11 +08:00
futAddPositionMap := map [ int ] string { }
spotAddPositionMap := map [ int ] string { }
futReduceMap := map [ int ] string { }
spotReduceMap := map [ int ] string { }
for _ , item := range futAddPositionStr {
sonic . Unmarshal ( [ ] byte ( item ) , & futAddPositionCache )
futAddPositionMap [ futAddPositionCache . Id ] = item
}
for _ , item := range spotAdPositionStr {
sonic . Unmarshal ( [ ] byte ( item ) , & spotAddPositionCache )
spotAddPositionMap [ spotAddPositionCache . Id ] = item
}
for _ , item := range futReduceStr {
sonic . Unmarshal ( [ ] byte ( item ) , & futReduceCache )
futReduceMap [ futReduceCache . Id ] = item
}
for _ , item := range spotReduceStr {
sonic . Unmarshal ( [ ] byte ( item ) , & spotReduceCache )
spotReduceMap [ spotReduceCache . Id ] = item
}
for _ , childOrder := range childOrders {
switch {
//加仓单
case childOrder . OrderType == 0 && childOrder . OrderCategory == 3 :
if val , ok := futAddPositionMap [ childOrder . Id ] ; ok {
helper . DefaultRedis . LRem ( futAddKey , val )
}
if val , ok := spotAddPositionMap [ childOrder . Id ] ; ok {
helper . DefaultRedis . LRem ( spotAddKey , val )
}
//减仓单
case childOrder . OrderType == 4 && childOrder . OrderCategory == 1 :
if val , ok := futReduceMap [ childOrder . Id ] ; ok {
helper . DefaultRedis . LRem ( futReduceKey , val )
}
if val , ok := spotReduceMap [ childOrder . Id ] ; ok {
helper . DefaultRedis . LRem ( spotReduceKey , val )
}
default :
continue
}
childOrderId = append ( childOrderId , childOrder . Id )
}
idArrays := utility . SplitSlice ( childOrderId , 1000 )
for _ , idArray := range idArrays {
if err := db . Delete ( & models . LinePreOrder { } , idArray ) . Error ; err != nil {
logger . Errorf ( "删除过期子订单失败,err" , err )
}
}
}
2025-02-06 11:14:33 +08:00
// UpRange 更新涨跌幅
type UpRange struct {
}
func ( receiver UpRange ) Exec ( arg interface { } ) error {
dbs := sdk . Runtime . GetDb ( )
var db * gorm . DB
for _ , item := range dbs {
db = item
break
}
limit := service . LinePriceLimit {
Service : sysservice . Service { Orm : db } ,
}
err := limit . UpRange ( )
if err != nil {
return err
}
return nil
}