Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
2b528c5f
Commit
2b528c5f
authored
Jan 07, 2026
by
LLLLLLiulei
Browse files
feat: auto-pause expired accounts
parent
d5ba7b80
Changes
32
Hide whitespace changes
Inline
Side-by-side
backend/cmd/server/wire.go
View file @
2b528c5f
...
@@ -63,6 +63,7 @@ func provideCleanup(
...
@@ -63,6 +63,7 @@ func provideCleanup(
entClient
*
ent
.
Client
,
entClient
*
ent
.
Client
,
rdb
*
redis
.
Client
,
rdb
*
redis
.
Client
,
tokenRefresh
*
service
.
TokenRefreshService
,
tokenRefresh
*
service
.
TokenRefreshService
,
accountExpiry
*
service
.
AccountExpiryService
,
pricing
*
service
.
PricingService
,
pricing
*
service
.
PricingService
,
emailQueue
*
service
.
EmailQueueService
,
emailQueue
*
service
.
EmailQueueService
,
billingCache
*
service
.
BillingCacheService
,
billingCache
*
service
.
BillingCacheService
,
...
@@ -84,6 +85,10 @@ func provideCleanup(
...
@@ -84,6 +85,10 @@ func provideCleanup(
tokenRefresh
.
Stop
()
tokenRefresh
.
Stop
()
return
nil
return
nil
}},
}},
{
"AccountExpiryService"
,
func
()
error
{
accountExpiry
.
Stop
()
return
nil
}},
{
"PricingService"
,
func
()
error
{
{
"PricingService"
,
func
()
error
{
pricing
.
Stop
()
pricing
.
Stop
()
return
nil
return
nil
...
...
backend/cmd/server/wire_gen.go
View file @
2b528c5f
...
@@ -87,6 +87,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
...
@@ -87,6 +87,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
geminiOAuthClient
:=
repository
.
NewGeminiOAuthClient
(
configConfig
)
geminiOAuthClient
:=
repository
.
NewGeminiOAuthClient
(
configConfig
)
geminiCliCodeAssistClient
:=
repository
.
NewGeminiCliCodeAssistClient
()
geminiCliCodeAssistClient
:=
repository
.
NewGeminiCliCodeAssistClient
()
geminiOAuthService
:=
service
.
NewGeminiOAuthService
(
proxyRepository
,
geminiOAuthClient
,
geminiCliCodeAssistClient
,
configConfig
)
geminiOAuthService
:=
service
.
NewGeminiOAuthService
(
proxyRepository
,
geminiOAuthClient
,
geminiCliCodeAssistClient
,
configConfig
)
antigravityOAuthService
:=
service
.
NewAntigravityOAuthService
(
proxyRepository
)
geminiQuotaService
:=
service
.
NewGeminiQuotaService
(
configConfig
,
settingRepository
)
geminiQuotaService
:=
service
.
NewGeminiQuotaService
(
configConfig
,
settingRepository
)
tempUnschedCache
:=
repository
.
NewTempUnschedCache
(
redisClient
)
tempUnschedCache
:=
repository
.
NewTempUnschedCache
(
redisClient
)
rateLimitService
:=
service
.
NewRateLimitService
(
accountRepository
,
usageLogRepository
,
configConfig
,
geminiQuotaService
,
tempUnschedCache
)
rateLimitService
:=
service
.
NewRateLimitService
(
accountRepository
,
usageLogRepository
,
configConfig
,
geminiQuotaService
,
tempUnschedCache
)
...
@@ -97,13 +98,12 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
...
@@ -97,13 +98,12 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
geminiTokenCache
:=
repository
.
NewGeminiTokenCache
(
redisClient
)
geminiTokenCache
:=
repository
.
NewGeminiTokenCache
(
redisClient
)
geminiTokenProvider
:=
service
.
NewGeminiTokenProvider
(
accountRepository
,
geminiTokenCache
,
geminiOAuthService
)
geminiTokenProvider
:=
service
.
NewGeminiTokenProvider
(
accountRepository
,
geminiTokenCache
,
geminiOAuthService
)
gatewayCache
:=
repository
.
NewGatewayCache
(
redisClient
)
gatewayCache
:=
repository
.
NewGatewayCache
(
redisClient
)
antigravityOAuthService
:=
service
.
NewAntigravityOAuthService
(
proxyRepository
)
antigravityTokenProvider
:=
service
.
NewAntigravityTokenProvider
(
accountRepository
,
geminiTokenCache
,
antigravityOAuthService
)
antigravityTokenProvider
:=
service
.
NewAntigravityTokenProvider
(
accountRepository
,
geminiTokenCache
,
antigravityOAuthService
)
httpUpstream
:=
repository
.
NewHTTPUpstream
(
configConfig
)
httpUpstream
:=
repository
.
NewHTTPUpstream
(
configConfig
)
antigravityGatewayService
:=
service
.
NewAntigravityGatewayService
(
accountRepository
,
gatewayCache
,
antigravityTokenProvider
,
rateLimitService
,
httpUpstream
,
settingService
)
antigravityGatewayService
:=
service
.
NewAntigravityGatewayService
(
accountRepository
,
gatewayCache
,
antigravityTokenProvider
,
rateLimitService
,
httpUpstream
,
settingService
)
accountTestService
:=
service
.
NewAccountTestService
(
accountRepository
,
geminiTokenProvider
,
antigravityGatewayService
,
httpUpstream
,
configConfig
)
accountTestService
:=
service
.
NewAccountTestService
(
accountRepository
,
geminiTokenProvider
,
antigravityGatewayService
,
httpUpstream
,
configConfig
)
concurrencyCache
:=
repository
.
ProvideConcurrencyCache
(
redisClient
,
configConfig
)
concurrencyCache
:=
repository
.
ProvideConcurrencyCache
(
redisClient
,
configConfig
)
concurrencyService
:=
service
.
New
ConcurrencyService
(
concurrencyCache
)
concurrencyService
:=
service
.
Provide
ConcurrencyService
(
concurrencyCache
,
accountRepository
,
configConfig
)
crsSyncService
:=
service
.
NewCRSSyncService
(
accountRepository
,
proxyRepository
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
configConfig
)
crsSyncService
:=
service
.
NewCRSSyncService
(
accountRepository
,
proxyRepository
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
configConfig
)
accountHandler
:=
admin
.
NewAccountHandler
(
adminService
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
,
rateLimitService
,
accountUsageService
,
accountTestService
,
concurrencyService
,
crsSyncService
)
accountHandler
:=
admin
.
NewAccountHandler
(
adminService
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
,
rateLimitService
,
accountUsageService
,
accountTestService
,
concurrencyService
,
crsSyncService
)
oAuthHandler
:=
admin
.
NewOAuthHandler
(
oAuthService
)
oAuthHandler
:=
admin
.
NewOAuthHandler
(
oAuthService
)
...
@@ -148,7 +148,8 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
...
@@ -148,7 +148,8 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
engine
:=
server
.
ProvideRouter
(
configConfig
,
handlers
,
jwtAuthMiddleware
,
adminAuthMiddleware
,
apiKeyAuthMiddleware
,
apiKeyService
,
subscriptionService
)
engine
:=
server
.
ProvideRouter
(
configConfig
,
handlers
,
jwtAuthMiddleware
,
adminAuthMiddleware
,
apiKeyAuthMiddleware
,
apiKeyService
,
subscriptionService
)
httpServer
:=
server
.
ProvideHTTPServer
(
configConfig
,
engine
)
httpServer
:=
server
.
ProvideHTTPServer
(
configConfig
,
engine
)
tokenRefreshService
:=
service
.
ProvideTokenRefreshService
(
accountRepository
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
,
configConfig
)
tokenRefreshService
:=
service
.
ProvideTokenRefreshService
(
accountRepository
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
,
configConfig
)
v
:=
provideCleanup
(
client
,
redisClient
,
tokenRefreshService
,
pricingService
,
emailQueueService
,
billingCacheService
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
)
accountExpiryService
:=
service
.
ProvideAccountExpiryService
(
accountRepository
)
v
:=
provideCleanup
(
client
,
redisClient
,
tokenRefreshService
,
accountExpiryService
,
pricingService
,
emailQueueService
,
billingCacheService
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
)
application
:=
&
Application
{
application
:=
&
Application
{
Server
:
httpServer
,
Server
:
httpServer
,
Cleanup
:
v
,
Cleanup
:
v
,
...
@@ -174,6 +175,7 @@ func provideCleanup(
...
@@ -174,6 +175,7 @@ func provideCleanup(
entClient
*
ent
.
Client
,
entClient
*
ent
.
Client
,
rdb
*
redis
.
Client
,
rdb
*
redis
.
Client
,
tokenRefresh
*
service
.
TokenRefreshService
,
tokenRefresh
*
service
.
TokenRefreshService
,
accountExpiry
*
service
.
AccountExpiryService
,
pricing
*
service
.
PricingService
,
pricing
*
service
.
PricingService
,
emailQueue
*
service
.
EmailQueueService
,
emailQueue
*
service
.
EmailQueueService
,
billingCache
*
service
.
BillingCacheService
,
billingCache
*
service
.
BillingCacheService
,
...
@@ -194,6 +196,10 @@ func provideCleanup(
...
@@ -194,6 +196,10 @@ func provideCleanup(
tokenRefresh
.
Stop
()
tokenRefresh
.
Stop
()
return
nil
return
nil
}},
}},
{
"AccountExpiryService"
,
func
()
error
{
accountExpiry
.
Stop
()
return
nil
}},
{
"PricingService"
,
func
()
error
{
{
"PricingService"
,
func
()
error
{
pricing
.
Stop
()
pricing
.
Stop
()
return
nil
return
nil
...
...
backend/ent/account.go
View file @
2b528c5f
...
@@ -49,6 +49,10 @@ type Account struct {
...
@@ -49,6 +49,10 @@ type Account struct {
ErrorMessage
*
string
`json:"error_message,omitempty"`
ErrorMessage
*
string
`json:"error_message,omitempty"`
// LastUsedAt holds the value of the "last_used_at" field.
// LastUsedAt holds the value of the "last_used_at" field.
LastUsedAt
*
time
.
Time
`json:"last_used_at,omitempty"`
LastUsedAt
*
time
.
Time
`json:"last_used_at,omitempty"`
// Account expiration time (NULL means no expiration).
ExpiresAt
*
time
.
Time
`json:"expires_at,omitempty"`
// Auto pause scheduling when account expires.
AutoPauseOnExpired
bool
`json:"auto_pause_on_expired,omitempty"`
// Schedulable holds the value of the "schedulable" field.
// Schedulable holds the value of the "schedulable" field.
Schedulable
bool
`json:"schedulable,omitempty"`
Schedulable
bool
`json:"schedulable,omitempty"`
// RateLimitedAt holds the value of the "rate_limited_at" field.
// RateLimitedAt holds the value of the "rate_limited_at" field.
...
@@ -129,13 +133,13 @@ func (*Account) scanValues(columns []string) ([]any, error) {
...
@@ -129,13 +133,13 @@ func (*Account) scanValues(columns []string) ([]any, error) {
switch
columns
[
i
]
{
switch
columns
[
i
]
{
case
account
.
FieldCredentials
,
account
.
FieldExtra
:
case
account
.
FieldCredentials
,
account
.
FieldExtra
:
values
[
i
]
=
new
([]
byte
)
values
[
i
]
=
new
([]
byte
)
case
account
.
FieldSchedulable
:
case
account
.
FieldAutoPauseOnExpired
,
account
.
FieldSchedulable
:
values
[
i
]
=
new
(
sql
.
NullBool
)
values
[
i
]
=
new
(
sql
.
NullBool
)
case
account
.
FieldID
,
account
.
FieldProxyID
,
account
.
FieldConcurrency
,
account
.
FieldPriority
:
case
account
.
FieldID
,
account
.
FieldProxyID
,
account
.
FieldConcurrency
,
account
.
FieldPriority
:
values
[
i
]
=
new
(
sql
.
NullInt64
)
values
[
i
]
=
new
(
sql
.
NullInt64
)
case
account
.
FieldName
,
account
.
FieldNotes
,
account
.
FieldPlatform
,
account
.
FieldType
,
account
.
FieldStatus
,
account
.
FieldErrorMessage
,
account
.
FieldSessionWindowStatus
:
case
account
.
FieldName
,
account
.
FieldNotes
,
account
.
FieldPlatform
,
account
.
FieldType
,
account
.
FieldStatus
,
account
.
FieldErrorMessage
,
account
.
FieldSessionWindowStatus
:
values
[
i
]
=
new
(
sql
.
NullString
)
values
[
i
]
=
new
(
sql
.
NullString
)
case
account
.
FieldCreatedAt
,
account
.
FieldUpdatedAt
,
account
.
FieldDeletedAt
,
account
.
FieldLastUsedAt
,
account
.
FieldRateLimitedAt
,
account
.
FieldRateLimitResetAt
,
account
.
FieldOverloadUntil
,
account
.
FieldSessionWindowStart
,
account
.
FieldSessionWindowEnd
:
case
account
.
FieldCreatedAt
,
account
.
FieldUpdatedAt
,
account
.
FieldDeletedAt
,
account
.
FieldLastUsedAt
,
account
.
FieldExpiresAt
,
account
.
FieldRateLimitedAt
,
account
.
FieldRateLimitResetAt
,
account
.
FieldOverloadUntil
,
account
.
FieldSessionWindowStart
,
account
.
FieldSessionWindowEnd
:
values
[
i
]
=
new
(
sql
.
NullTime
)
values
[
i
]
=
new
(
sql
.
NullTime
)
default
:
default
:
values
[
i
]
=
new
(
sql
.
UnknownType
)
values
[
i
]
=
new
(
sql
.
UnknownType
)
...
@@ -257,6 +261,19 @@ func (_m *Account) assignValues(columns []string, values []any) error {
...
@@ -257,6 +261,19 @@ func (_m *Account) assignValues(columns []string, values []any) error {
_m
.
LastUsedAt
=
new
(
time
.
Time
)
_m
.
LastUsedAt
=
new
(
time
.
Time
)
*
_m
.
LastUsedAt
=
value
.
Time
*
_m
.
LastUsedAt
=
value
.
Time
}
}
case
account
.
FieldExpiresAt
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullTime
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field expires_at"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
ExpiresAt
=
new
(
time
.
Time
)
*
_m
.
ExpiresAt
=
value
.
Time
}
case
account
.
FieldAutoPauseOnExpired
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullBool
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field auto_pause_on_expired"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
AutoPauseOnExpired
=
value
.
Bool
}
case
account
.
FieldSchedulable
:
case
account
.
FieldSchedulable
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullBool
);
!
ok
{
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullBool
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field schedulable"
,
values
[
i
])
return
fmt
.
Errorf
(
"unexpected type %T for field schedulable"
,
values
[
i
])
...
@@ -416,6 +433,14 @@ func (_m *Account) String() string {
...
@@ -416,6 +433,14 @@ func (_m *Account) String() string {
builder
.
WriteString
(
v
.
Format
(
time
.
ANSIC
))
builder
.
WriteString
(
v
.
Format
(
time
.
ANSIC
))
}
}
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
ExpiresAt
;
v
!=
nil
{
builder
.
WriteString
(
"expires_at="
)
builder
.
WriteString
(
v
.
Format
(
time
.
ANSIC
))
}
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"auto_pause_on_expired="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
AutoPauseOnExpired
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"schedulable="
)
builder
.
WriteString
(
"schedulable="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
Schedulable
))
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
Schedulable
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
", "
)
...
...
backend/ent/account/account.go
View file @
2b528c5f
...
@@ -45,6 +45,10 @@ const (
...
@@ -45,6 +45,10 @@ const (
FieldErrorMessage
=
"error_message"
FieldErrorMessage
=
"error_message"
// FieldLastUsedAt holds the string denoting the last_used_at field in the database.
// FieldLastUsedAt holds the string denoting the last_used_at field in the database.
FieldLastUsedAt
=
"last_used_at"
FieldLastUsedAt
=
"last_used_at"
// FieldExpiresAt holds the string denoting the expires_at field in the database.
FieldExpiresAt
=
"expires_at"
// FieldAutoPauseOnExpired holds the string denoting the auto_pause_on_expired field in the database.
FieldAutoPauseOnExpired
=
"auto_pause_on_expired"
// FieldSchedulable holds the string denoting the schedulable field in the database.
// FieldSchedulable holds the string denoting the schedulable field in the database.
FieldSchedulable
=
"schedulable"
FieldSchedulable
=
"schedulable"
// FieldRateLimitedAt holds the string denoting the rate_limited_at field in the database.
// FieldRateLimitedAt holds the string denoting the rate_limited_at field in the database.
...
@@ -115,6 +119,8 @@ var Columns = []string{
...
@@ -115,6 +119,8 @@ var Columns = []string{
FieldStatus
,
FieldStatus
,
FieldErrorMessage
,
FieldErrorMessage
,
FieldLastUsedAt
,
FieldLastUsedAt
,
FieldExpiresAt
,
FieldAutoPauseOnExpired
,
FieldSchedulable
,
FieldSchedulable
,
FieldRateLimitedAt
,
FieldRateLimitedAt
,
FieldRateLimitResetAt
,
FieldRateLimitResetAt
,
...
@@ -172,6 +178,8 @@ var (
...
@@ -172,6 +178,8 @@ var (
DefaultStatus
string
DefaultStatus
string
// StatusValidator is a validator for the "status" field. It is called by the builders before save.
// StatusValidator is a validator for the "status" field. It is called by the builders before save.
StatusValidator
func
(
string
)
error
StatusValidator
func
(
string
)
error
// DefaultAutoPauseOnExpired holds the default value on creation for the "auto_pause_on_expired" field.
DefaultAutoPauseOnExpired
bool
// DefaultSchedulable holds the default value on creation for the "schedulable" field.
// DefaultSchedulable holds the default value on creation for the "schedulable" field.
DefaultSchedulable
bool
DefaultSchedulable
bool
// SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save.
// SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save.
...
@@ -251,6 +259,16 @@ func ByLastUsedAt(opts ...sql.OrderTermOption) OrderOption {
...
@@ -251,6 +259,16 @@ func ByLastUsedAt(opts ...sql.OrderTermOption) OrderOption {
return
sql
.
OrderByField
(
FieldLastUsedAt
,
opts
...
)
.
ToFunc
()
return
sql
.
OrderByField
(
FieldLastUsedAt
,
opts
...
)
.
ToFunc
()
}
}
// ByExpiresAt orders the results by the expires_at field.
func
ByExpiresAt
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldExpiresAt
,
opts
...
)
.
ToFunc
()
}
// ByAutoPauseOnExpired orders the results by the auto_pause_on_expired field.
func
ByAutoPauseOnExpired
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldAutoPauseOnExpired
,
opts
...
)
.
ToFunc
()
}
// BySchedulable orders the results by the schedulable field.
// BySchedulable orders the results by the schedulable field.
func
BySchedulable
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
func
BySchedulable
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldSchedulable
,
opts
...
)
.
ToFunc
()
return
sql
.
OrderByField
(
FieldSchedulable
,
opts
...
)
.
ToFunc
()
...
...
backend/ent/account/where.go
View file @
2b528c5f
...
@@ -120,6 +120,16 @@ func LastUsedAt(v time.Time) predicate.Account {
...
@@ -120,6 +120,16 @@ func LastUsedAt(v time.Time) predicate.Account {
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldLastUsedAt
,
v
))
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldLastUsedAt
,
v
))
}
}
// ExpiresAt applies equality check predicate on the "expires_at" field. It's identical to ExpiresAtEQ.
func
ExpiresAt
(
v
time
.
Time
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldExpiresAt
,
v
))
}
// AutoPauseOnExpired applies equality check predicate on the "auto_pause_on_expired" field. It's identical to AutoPauseOnExpiredEQ.
func
AutoPauseOnExpired
(
v
bool
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldAutoPauseOnExpired
,
v
))
}
// Schedulable applies equality check predicate on the "schedulable" field. It's identical to SchedulableEQ.
// Schedulable applies equality check predicate on the "schedulable" field. It's identical to SchedulableEQ.
func
Schedulable
(
v
bool
)
predicate
.
Account
{
func
Schedulable
(
v
bool
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldSchedulable
,
v
))
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldSchedulable
,
v
))
...
@@ -855,6 +865,66 @@ func LastUsedAtNotNil() predicate.Account {
...
@@ -855,6 +865,66 @@ func LastUsedAtNotNil() predicate.Account {
return
predicate
.
Account
(
sql
.
FieldNotNull
(
FieldLastUsedAt
))
return
predicate
.
Account
(
sql
.
FieldNotNull
(
FieldLastUsedAt
))
}
}
// ExpiresAtEQ applies the EQ predicate on the "expires_at" field.
func
ExpiresAtEQ
(
v
time
.
Time
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldExpiresAt
,
v
))
}
// ExpiresAtNEQ applies the NEQ predicate on the "expires_at" field.
func
ExpiresAtNEQ
(
v
time
.
Time
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldNEQ
(
FieldExpiresAt
,
v
))
}
// ExpiresAtIn applies the In predicate on the "expires_at" field.
func
ExpiresAtIn
(
vs
...
time
.
Time
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldIn
(
FieldExpiresAt
,
vs
...
))
}
// ExpiresAtNotIn applies the NotIn predicate on the "expires_at" field.
func
ExpiresAtNotIn
(
vs
...
time
.
Time
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldNotIn
(
FieldExpiresAt
,
vs
...
))
}
// ExpiresAtGT applies the GT predicate on the "expires_at" field.
func
ExpiresAtGT
(
v
time
.
Time
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldGT
(
FieldExpiresAt
,
v
))
}
// ExpiresAtGTE applies the GTE predicate on the "expires_at" field.
func
ExpiresAtGTE
(
v
time
.
Time
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldGTE
(
FieldExpiresAt
,
v
))
}
// ExpiresAtLT applies the LT predicate on the "expires_at" field.
func
ExpiresAtLT
(
v
time
.
Time
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldLT
(
FieldExpiresAt
,
v
))
}
// ExpiresAtLTE applies the LTE predicate on the "expires_at" field.
func
ExpiresAtLTE
(
v
time
.
Time
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldLTE
(
FieldExpiresAt
,
v
))
}
// ExpiresAtIsNil applies the IsNil predicate on the "expires_at" field.
func
ExpiresAtIsNil
()
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldIsNull
(
FieldExpiresAt
))
}
// ExpiresAtNotNil applies the NotNil predicate on the "expires_at" field.
func
ExpiresAtNotNil
()
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldNotNull
(
FieldExpiresAt
))
}
// AutoPauseOnExpiredEQ applies the EQ predicate on the "auto_pause_on_expired" field.
func
AutoPauseOnExpiredEQ
(
v
bool
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldAutoPauseOnExpired
,
v
))
}
// AutoPauseOnExpiredNEQ applies the NEQ predicate on the "auto_pause_on_expired" field.
func
AutoPauseOnExpiredNEQ
(
v
bool
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldNEQ
(
FieldAutoPauseOnExpired
,
v
))
}
// SchedulableEQ applies the EQ predicate on the "schedulable" field.
// SchedulableEQ applies the EQ predicate on the "schedulable" field.
func
SchedulableEQ
(
v
bool
)
predicate
.
Account
{
func
SchedulableEQ
(
v
bool
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldSchedulable
,
v
))
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldSchedulable
,
v
))
...
...
backend/ent/account_create.go
View file @
2b528c5f
...
@@ -195,6 +195,34 @@ func (_c *AccountCreate) SetNillableLastUsedAt(v *time.Time) *AccountCreate {
...
@@ -195,6 +195,34 @@ func (_c *AccountCreate) SetNillableLastUsedAt(v *time.Time) *AccountCreate {
return
_c
return
_c
}
}
// SetExpiresAt sets the "expires_at" field.
func
(
_c
*
AccountCreate
)
SetExpiresAt
(
v
time
.
Time
)
*
AccountCreate
{
_c
.
mutation
.
SetExpiresAt
(
v
)
return
_c
}
// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil.
func
(
_c
*
AccountCreate
)
SetNillableExpiresAt
(
v
*
time
.
Time
)
*
AccountCreate
{
if
v
!=
nil
{
_c
.
SetExpiresAt
(
*
v
)
}
return
_c
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func
(
_c
*
AccountCreate
)
SetAutoPauseOnExpired
(
v
bool
)
*
AccountCreate
{
_c
.
mutation
.
SetAutoPauseOnExpired
(
v
)
return
_c
}
// SetNillableAutoPauseOnExpired sets the "auto_pause_on_expired" field if the given value is not nil.
func
(
_c
*
AccountCreate
)
SetNillableAutoPauseOnExpired
(
v
*
bool
)
*
AccountCreate
{
if
v
!=
nil
{
_c
.
SetAutoPauseOnExpired
(
*
v
)
}
return
_c
}
// SetSchedulable sets the "schedulable" field.
// SetSchedulable sets the "schedulable" field.
func
(
_c
*
AccountCreate
)
SetSchedulable
(
v
bool
)
*
AccountCreate
{
func
(
_c
*
AccountCreate
)
SetSchedulable
(
v
bool
)
*
AccountCreate
{
_c
.
mutation
.
SetSchedulable
(
v
)
_c
.
mutation
.
SetSchedulable
(
v
)
...
@@ -405,6 +433,10 @@ func (_c *AccountCreate) defaults() error {
...
@@ -405,6 +433,10 @@ func (_c *AccountCreate) defaults() error {
v
:=
account
.
DefaultStatus
v
:=
account
.
DefaultStatus
_c
.
mutation
.
SetStatus
(
v
)
_c
.
mutation
.
SetStatus
(
v
)
}
}
if
_
,
ok
:=
_c
.
mutation
.
AutoPauseOnExpired
();
!
ok
{
v
:=
account
.
DefaultAutoPauseOnExpired
_c
.
mutation
.
SetAutoPauseOnExpired
(
v
)
}
if
_
,
ok
:=
_c
.
mutation
.
Schedulable
();
!
ok
{
if
_
,
ok
:=
_c
.
mutation
.
Schedulable
();
!
ok
{
v
:=
account
.
DefaultSchedulable
v
:=
account
.
DefaultSchedulable
_c
.
mutation
.
SetSchedulable
(
v
)
_c
.
mutation
.
SetSchedulable
(
v
)
...
@@ -464,6 +496,9 @@ func (_c *AccountCreate) check() error {
...
@@ -464,6 +496,9 @@ func (_c *AccountCreate) check() error {
return
&
ValidationError
{
Name
:
"status"
,
err
:
fmt
.
Errorf
(
`ent: validator failed for field "Account.status": %w`
,
err
)}
return
&
ValidationError
{
Name
:
"status"
,
err
:
fmt
.
Errorf
(
`ent: validator failed for field "Account.status": %w`
,
err
)}
}
}
}
}
if
_
,
ok
:=
_c
.
mutation
.
AutoPauseOnExpired
();
!
ok
{
return
&
ValidationError
{
Name
:
"auto_pause_on_expired"
,
err
:
errors
.
New
(
`ent: missing required field "Account.auto_pause_on_expired"`
)}
}
if
_
,
ok
:=
_c
.
mutation
.
Schedulable
();
!
ok
{
if
_
,
ok
:=
_c
.
mutation
.
Schedulable
();
!
ok
{
return
&
ValidationError
{
Name
:
"schedulable"
,
err
:
errors
.
New
(
`ent: missing required field "Account.schedulable"`
)}
return
&
ValidationError
{
Name
:
"schedulable"
,
err
:
errors
.
New
(
`ent: missing required field "Account.schedulable"`
)}
}
}
...
@@ -555,6 +590,14 @@ func (_c *AccountCreate) createSpec() (*Account, *sqlgraph.CreateSpec) {
...
@@ -555,6 +590,14 @@ func (_c *AccountCreate) createSpec() (*Account, *sqlgraph.CreateSpec) {
_spec
.
SetField
(
account
.
FieldLastUsedAt
,
field
.
TypeTime
,
value
)
_spec
.
SetField
(
account
.
FieldLastUsedAt
,
field
.
TypeTime
,
value
)
_node
.
LastUsedAt
=
&
value
_node
.
LastUsedAt
=
&
value
}
}
if
value
,
ok
:=
_c
.
mutation
.
ExpiresAt
();
ok
{
_spec
.
SetField
(
account
.
FieldExpiresAt
,
field
.
TypeTime
,
value
)
_node
.
ExpiresAt
=
&
value
}
if
value
,
ok
:=
_c
.
mutation
.
AutoPauseOnExpired
();
ok
{
_spec
.
SetField
(
account
.
FieldAutoPauseOnExpired
,
field
.
TypeBool
,
value
)
_node
.
AutoPauseOnExpired
=
value
}
if
value
,
ok
:=
_c
.
mutation
.
Schedulable
();
ok
{
if
value
,
ok
:=
_c
.
mutation
.
Schedulable
();
ok
{
_spec
.
SetField
(
account
.
FieldSchedulable
,
field
.
TypeBool
,
value
)
_spec
.
SetField
(
account
.
FieldSchedulable
,
field
.
TypeBool
,
value
)
_node
.
Schedulable
=
value
_node
.
Schedulable
=
value
...
@@ -898,6 +941,36 @@ func (u *AccountUpsert) ClearLastUsedAt() *AccountUpsert {
...
@@ -898,6 +941,36 @@ func (u *AccountUpsert) ClearLastUsedAt() *AccountUpsert {
return
u
return
u
}
}
// SetExpiresAt sets the "expires_at" field.
func
(
u
*
AccountUpsert
)
SetExpiresAt
(
v
time
.
Time
)
*
AccountUpsert
{
u
.
Set
(
account
.
FieldExpiresAt
,
v
)
return
u
}
// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create.
func
(
u
*
AccountUpsert
)
UpdateExpiresAt
()
*
AccountUpsert
{
u
.
SetExcluded
(
account
.
FieldExpiresAt
)
return
u
}
// ClearExpiresAt clears the value of the "expires_at" field.
func
(
u
*
AccountUpsert
)
ClearExpiresAt
()
*
AccountUpsert
{
u
.
SetNull
(
account
.
FieldExpiresAt
)
return
u
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func
(
u
*
AccountUpsert
)
SetAutoPauseOnExpired
(
v
bool
)
*
AccountUpsert
{
u
.
Set
(
account
.
FieldAutoPauseOnExpired
,
v
)
return
u
}
// UpdateAutoPauseOnExpired sets the "auto_pause_on_expired" field to the value that was provided on create.
func
(
u
*
AccountUpsert
)
UpdateAutoPauseOnExpired
()
*
AccountUpsert
{
u
.
SetExcluded
(
account
.
FieldAutoPauseOnExpired
)
return
u
}
// SetSchedulable sets the "schedulable" field.
// SetSchedulable sets the "schedulable" field.
func
(
u
*
AccountUpsert
)
SetSchedulable
(
v
bool
)
*
AccountUpsert
{
func
(
u
*
AccountUpsert
)
SetSchedulable
(
v
bool
)
*
AccountUpsert
{
u
.
Set
(
account
.
FieldSchedulable
,
v
)
u
.
Set
(
account
.
FieldSchedulable
,
v
)
...
@@ -1308,6 +1381,41 @@ func (u *AccountUpsertOne) ClearLastUsedAt() *AccountUpsertOne {
...
@@ -1308,6 +1381,41 @@ func (u *AccountUpsertOne) ClearLastUsedAt() *AccountUpsertOne {
})
})
}
}
// SetExpiresAt sets the "expires_at" field.
func
(
u
*
AccountUpsertOne
)
SetExpiresAt
(
v
time
.
Time
)
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
SetExpiresAt
(
v
)
})
}
// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create.
func
(
u
*
AccountUpsertOne
)
UpdateExpiresAt
()
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
UpdateExpiresAt
()
})
}
// ClearExpiresAt clears the value of the "expires_at" field.
func
(
u
*
AccountUpsertOne
)
ClearExpiresAt
()
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
ClearExpiresAt
()
})
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func
(
u
*
AccountUpsertOne
)
SetAutoPauseOnExpired
(
v
bool
)
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
SetAutoPauseOnExpired
(
v
)
})
}
// UpdateAutoPauseOnExpired sets the "auto_pause_on_expired" field to the value that was provided on create.
func
(
u
*
AccountUpsertOne
)
UpdateAutoPauseOnExpired
()
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
UpdateAutoPauseOnExpired
()
})
}
// SetSchedulable sets the "schedulable" field.
// SetSchedulable sets the "schedulable" field.
func
(
u
*
AccountUpsertOne
)
SetSchedulable
(
v
bool
)
*
AccountUpsertOne
{
func
(
u
*
AccountUpsertOne
)
SetSchedulable
(
v
bool
)
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
...
@@ -1904,6 +2012,41 @@ func (u *AccountUpsertBulk) ClearLastUsedAt() *AccountUpsertBulk {
...
@@ -1904,6 +2012,41 @@ func (u *AccountUpsertBulk) ClearLastUsedAt() *AccountUpsertBulk {
})
})
}
}
// SetExpiresAt sets the "expires_at" field.
func
(
u
*
AccountUpsertBulk
)
SetExpiresAt
(
v
time
.
Time
)
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
SetExpiresAt
(
v
)
})
}
// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create.
func
(
u
*
AccountUpsertBulk
)
UpdateExpiresAt
()
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
UpdateExpiresAt
()
})
}
// ClearExpiresAt clears the value of the "expires_at" field.
func
(
u
*
AccountUpsertBulk
)
ClearExpiresAt
()
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
ClearExpiresAt
()
})
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func
(
u
*
AccountUpsertBulk
)
SetAutoPauseOnExpired
(
v
bool
)
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
SetAutoPauseOnExpired
(
v
)
})
}
// UpdateAutoPauseOnExpired sets the "auto_pause_on_expired" field to the value that was provided on create.
func
(
u
*
AccountUpsertBulk
)
UpdateAutoPauseOnExpired
()
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
UpdateAutoPauseOnExpired
()
})
}
// SetSchedulable sets the "schedulable" field.
// SetSchedulable sets the "schedulable" field.
func
(
u
*
AccountUpsertBulk
)
SetSchedulable
(
v
bool
)
*
AccountUpsertBulk
{
func
(
u
*
AccountUpsertBulk
)
SetSchedulable
(
v
bool
)
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
...
...
backend/ent/account_update.go
View file @
2b528c5f
...
@@ -247,6 +247,40 @@ func (_u *AccountUpdate) ClearLastUsedAt() *AccountUpdate {
...
@@ -247,6 +247,40 @@ func (_u *AccountUpdate) ClearLastUsedAt() *AccountUpdate {
return
_u
return
_u
}
}
// SetExpiresAt sets the "expires_at" field.
func
(
_u
*
AccountUpdate
)
SetExpiresAt
(
v
time
.
Time
)
*
AccountUpdate
{
_u
.
mutation
.
SetExpiresAt
(
v
)
return
_u
}
// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil.
func
(
_u
*
AccountUpdate
)
SetNillableExpiresAt
(
v
*
time
.
Time
)
*
AccountUpdate
{
if
v
!=
nil
{
_u
.
SetExpiresAt
(
*
v
)
}
return
_u
}
// ClearExpiresAt clears the value of the "expires_at" field.
func
(
_u
*
AccountUpdate
)
ClearExpiresAt
()
*
AccountUpdate
{
_u
.
mutation
.
ClearExpiresAt
()
return
_u
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func
(
_u
*
AccountUpdate
)
SetAutoPauseOnExpired
(
v
bool
)
*
AccountUpdate
{
_u
.
mutation
.
SetAutoPauseOnExpired
(
v
)
return
_u
}
// SetNillableAutoPauseOnExpired sets the "auto_pause_on_expired" field if the given value is not nil.
func
(
_u
*
AccountUpdate
)
SetNillableAutoPauseOnExpired
(
v
*
bool
)
*
AccountUpdate
{
if
v
!=
nil
{
_u
.
SetAutoPauseOnExpired
(
*
v
)
}
return
_u
}
// SetSchedulable sets the "schedulable" field.
// SetSchedulable sets the "schedulable" field.
func
(
_u
*
AccountUpdate
)
SetSchedulable
(
v
bool
)
*
AccountUpdate
{
func
(
_u
*
AccountUpdate
)
SetSchedulable
(
v
bool
)
*
AccountUpdate
{
_u
.
mutation
.
SetSchedulable
(
v
)
_u
.
mutation
.
SetSchedulable
(
v
)
...
@@ -610,6 +644,15 @@ func (_u *AccountUpdate) sqlSave(ctx context.Context) (_node int, err error) {
...
@@ -610,6 +644,15 @@ func (_u *AccountUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if
_u
.
mutation
.
LastUsedAtCleared
()
{
if
_u
.
mutation
.
LastUsedAtCleared
()
{
_spec
.
ClearField
(
account
.
FieldLastUsedAt
,
field
.
TypeTime
)
_spec
.
ClearField
(
account
.
FieldLastUsedAt
,
field
.
TypeTime
)
}
}
if
value
,
ok
:=
_u
.
mutation
.
ExpiresAt
();
ok
{
_spec
.
SetField
(
account
.
FieldExpiresAt
,
field
.
TypeTime
,
value
)
}
if
_u
.
mutation
.
ExpiresAtCleared
()
{
_spec
.
ClearField
(
account
.
FieldExpiresAt
,
field
.
TypeTime
)
}
if
value
,
ok
:=
_u
.
mutation
.
AutoPauseOnExpired
();
ok
{
_spec
.
SetField
(
account
.
FieldAutoPauseOnExpired
,
field
.
TypeBool
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Schedulable
();
ok
{
if
value
,
ok
:=
_u
.
mutation
.
Schedulable
();
ok
{
_spec
.
SetField
(
account
.
FieldSchedulable
,
field
.
TypeBool
,
value
)
_spec
.
SetField
(
account
.
FieldSchedulable
,
field
.
TypeBool
,
value
)
}
}
...
@@ -1016,6 +1059,40 @@ func (_u *AccountUpdateOne) ClearLastUsedAt() *AccountUpdateOne {
...
@@ -1016,6 +1059,40 @@ func (_u *AccountUpdateOne) ClearLastUsedAt() *AccountUpdateOne {
return
_u
return
_u
}
}
// SetExpiresAt sets the "expires_at" field.
func
(
_u
*
AccountUpdateOne
)
SetExpiresAt
(
v
time
.
Time
)
*
AccountUpdateOne
{
_u
.
mutation
.
SetExpiresAt
(
v
)
return
_u
}
// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil.
func
(
_u
*
AccountUpdateOne
)
SetNillableExpiresAt
(
v
*
time
.
Time
)
*
AccountUpdateOne
{
if
v
!=
nil
{
_u
.
SetExpiresAt
(
*
v
)
}
return
_u
}
// ClearExpiresAt clears the value of the "expires_at" field.
func
(
_u
*
AccountUpdateOne
)
ClearExpiresAt
()
*
AccountUpdateOne
{
_u
.
mutation
.
ClearExpiresAt
()
return
_u
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func
(
_u
*
AccountUpdateOne
)
SetAutoPauseOnExpired
(
v
bool
)
*
AccountUpdateOne
{
_u
.
mutation
.
SetAutoPauseOnExpired
(
v
)
return
_u
}
// SetNillableAutoPauseOnExpired sets the "auto_pause_on_expired" field if the given value is not nil.
func
(
_u
*
AccountUpdateOne
)
SetNillableAutoPauseOnExpired
(
v
*
bool
)
*
AccountUpdateOne
{
if
v
!=
nil
{
_u
.
SetAutoPauseOnExpired
(
*
v
)
}
return
_u
}
// SetSchedulable sets the "schedulable" field.
// SetSchedulable sets the "schedulable" field.
func
(
_u
*
AccountUpdateOne
)
SetSchedulable
(
v
bool
)
*
AccountUpdateOne
{
func
(
_u
*
AccountUpdateOne
)
SetSchedulable
(
v
bool
)
*
AccountUpdateOne
{
_u
.
mutation
.
SetSchedulable
(
v
)
_u
.
mutation
.
SetSchedulable
(
v
)
...
@@ -1409,6 +1486,15 @@ func (_u *AccountUpdateOne) sqlSave(ctx context.Context) (_node *Account, err er
...
@@ -1409,6 +1486,15 @@ func (_u *AccountUpdateOne) sqlSave(ctx context.Context) (_node *Account, err er
if
_u
.
mutation
.
LastUsedAtCleared
()
{
if
_u
.
mutation
.
LastUsedAtCleared
()
{
_spec
.
ClearField
(
account
.
FieldLastUsedAt
,
field
.
TypeTime
)
_spec
.
ClearField
(
account
.
FieldLastUsedAt
,
field
.
TypeTime
)
}
}
if
value
,
ok
:=
_u
.
mutation
.
ExpiresAt
();
ok
{
_spec
.
SetField
(
account
.
FieldExpiresAt
,
field
.
TypeTime
,
value
)
}
if
_u
.
mutation
.
ExpiresAtCleared
()
{
_spec
.
ClearField
(
account
.
FieldExpiresAt
,
field
.
TypeTime
)
}
if
value
,
ok
:=
_u
.
mutation
.
AutoPauseOnExpired
();
ok
{
_spec
.
SetField
(
account
.
FieldAutoPauseOnExpired
,
field
.
TypeBool
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Schedulable
();
ok
{
if
value
,
ok
:=
_u
.
mutation
.
Schedulable
();
ok
{
_spec
.
SetField
(
account
.
FieldSchedulable
,
field
.
TypeBool
,
value
)
_spec
.
SetField
(
account
.
FieldSchedulable
,
field
.
TypeBool
,
value
)
}
}
...
...
backend/ent/migrate/schema.go
View file @
2b528c5f
...
@@ -80,6 +80,8 @@ var (
...
@@ -80,6 +80,8 @@ var (
{
Name
:
"status"
,
Type
:
field
.
TypeString
,
Size
:
20
,
Default
:
"active"
},
{
Name
:
"status"
,
Type
:
field
.
TypeString
,
Size
:
20
,
Default
:
"active"
},
{
Name
:
"error_message"
,
Type
:
field
.
TypeString
,
Nullable
:
true
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"text"
}},
{
Name
:
"error_message"
,
Type
:
field
.
TypeString
,
Nullable
:
true
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"text"
}},
{
Name
:
"last_used_at"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"timestamptz"
}},
{
Name
:
"last_used_at"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"timestamptz"
}},
{
Name
:
"expires_at"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"timestamptz"
}},
{
Name
:
"auto_pause_on_expired"
,
Type
:
field
.
TypeBool
,
Default
:
true
},
{
Name
:
"schedulable"
,
Type
:
field
.
TypeBool
,
Default
:
true
},
{
Name
:
"schedulable"
,
Type
:
field
.
TypeBool
,
Default
:
true
},
{
Name
:
"rate_limited_at"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"timestamptz"
}},
{
Name
:
"rate_limited_at"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"timestamptz"
}},
{
Name
:
"rate_limit_reset_at"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"timestamptz"
}},
{
Name
:
"rate_limit_reset_at"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"timestamptz"
}},
...
@@ -97,7 +99,7 @@ var (
...
@@ -97,7 +99,7 @@ var (
ForeignKeys
:
[]
*
schema
.
ForeignKey
{
ForeignKeys
:
[]
*
schema
.
ForeignKey
{
{
{
Symbol
:
"accounts_proxies_proxy"
,
Symbol
:
"accounts_proxies_proxy"
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
2
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
4
]},
RefColumns
:
[]
*
schema
.
Column
{
ProxiesColumns
[
0
]},
RefColumns
:
[]
*
schema
.
Column
{
ProxiesColumns
[
0
]},
OnDelete
:
schema
.
SetNull
,
OnDelete
:
schema
.
SetNull
,
},
},
...
@@ -121,7 +123,7 @@ var (
...
@@ -121,7 +123,7 @@ var (
{
{
Name
:
"account_proxy_id"
,
Name
:
"account_proxy_id"
,
Unique
:
false
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
2
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
4
]},
},
},
{
{
Name
:
"account_priority"
,
Name
:
"account_priority"
,
...
@@ -136,22 +138,22 @@ var (
...
@@ -136,22 +138,22 @@ var (
{
{
Name
:
"account_schedulable"
,
Name
:
"account_schedulable"
,
Unique
:
false
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
5
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
7
]},
},
},
{
{
Name
:
"account_rate_limited_at"
,
Name
:
"account_rate_limited_at"
,
Unique
:
false
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
6
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
8
]},
},
},
{
{
Name
:
"account_rate_limit_reset_at"
,
Name
:
"account_rate_limit_reset_at"
,
Unique
:
false
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
7
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
9
]},
},
},
{
{
Name
:
"account_overload_until"
,
Name
:
"account_overload_until"
,
Unique
:
false
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
18
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
20
]},
},
},
{
{
Name
:
"account_deleted_at"
,
Name
:
"account_deleted_at"
,
...
...
backend/ent/mutation.go
View file @
2b528c5f
...
@@ -1006,6 +1006,8 @@ type AccountMutation struct {
...
@@ -1006,6 +1006,8 @@ type AccountMutation struct {
status
*
string
status
*
string
error_message
*
string
error_message
*
string
last_used_at
*
time
.
Time
last_used_at
*
time
.
Time
expires_at
*
time
.
Time
auto_pause_on_expired
*
bool
schedulable
*
bool
schedulable
*
bool
rate_limited_at
*
time
.
Time
rate_limited_at
*
time
.
Time
rate_limit_reset_at
*
time
.
Time
rate_limit_reset_at
*
time
.
Time
...
@@ -1770,6 +1772,91 @@ func (m *AccountMutation) ResetLastUsedAt() {
...
@@ -1770,6 +1772,91 @@ func (m *AccountMutation) ResetLastUsedAt() {
delete
(
m
.
clearedFields
,
account
.
FieldLastUsedAt
)
delete
(
m
.
clearedFields
,
account
.
FieldLastUsedAt
)
}
}
// SetExpiresAt sets the "expires_at" field.
func
(
m
*
AccountMutation
)
SetExpiresAt
(
t
time
.
Time
)
{
m
.
expires_at
=
&
t
}
// ExpiresAt returns the value of the "expires_at" field in the mutation.
func
(
m
*
AccountMutation
)
ExpiresAt
()
(
r
time
.
Time
,
exists
bool
)
{
v
:=
m
.
expires_at
if
v
==
nil
{
return
}
return
*
v
,
true
}
// OldExpiresAt returns the old "expires_at" field's value of the Account entity.
// If the Account object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func
(
m
*
AccountMutation
)
OldExpiresAt
(
ctx
context
.
Context
)
(
v
*
time
.
Time
,
err
error
)
{
if
!
m
.
op
.
Is
(
OpUpdateOne
)
{
return
v
,
errors
.
New
(
"OldExpiresAt is only allowed on UpdateOne operations"
)
}
if
m
.
id
==
nil
||
m
.
oldValue
==
nil
{
return
v
,
errors
.
New
(
"OldExpiresAt requires an ID field in the mutation"
)
}
oldValue
,
err
:=
m
.
oldValue
(
ctx
)
if
err
!=
nil
{
return
v
,
fmt
.
Errorf
(
"querying old value for OldExpiresAt: %w"
,
err
)
}
return
oldValue
.
ExpiresAt
,
nil
}
// ClearExpiresAt clears the value of the "expires_at" field.
func
(
m
*
AccountMutation
)
ClearExpiresAt
()
{
m
.
expires_at
=
nil
m
.
clearedFields
[
account
.
FieldExpiresAt
]
=
struct
{}{}
}
// ExpiresAtCleared returns if the "expires_at" field was cleared in this mutation.
func
(
m
*
AccountMutation
)
ExpiresAtCleared
()
bool
{
_
,
ok
:=
m
.
clearedFields
[
account
.
FieldExpiresAt
]
return
ok
}
// ResetExpiresAt resets all changes to the "expires_at" field.
func
(
m
*
AccountMutation
)
ResetExpiresAt
()
{
m
.
expires_at
=
nil
delete
(
m
.
clearedFields
,
account
.
FieldExpiresAt
)
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func
(
m
*
AccountMutation
)
SetAutoPauseOnExpired
(
b
bool
)
{
m
.
auto_pause_on_expired
=
&
b
}
// AutoPauseOnExpired returns the value of the "auto_pause_on_expired" field in the mutation.
func
(
m
*
AccountMutation
)
AutoPauseOnExpired
()
(
r
bool
,
exists
bool
)
{
v
:=
m
.
auto_pause_on_expired
if
v
==
nil
{
return
}
return
*
v
,
true
}
// OldAutoPauseOnExpired returns the old "auto_pause_on_expired" field's value of the Account entity.
// If the Account object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func
(
m
*
AccountMutation
)
OldAutoPauseOnExpired
(
ctx
context
.
Context
)
(
v
bool
,
err
error
)
{
if
!
m
.
op
.
Is
(
OpUpdateOne
)
{
return
v
,
errors
.
New
(
"OldAutoPauseOnExpired is only allowed on UpdateOne operations"
)
}
if
m
.
id
==
nil
||
m
.
oldValue
==
nil
{
return
v
,
errors
.
New
(
"OldAutoPauseOnExpired requires an ID field in the mutation"
)
}
oldValue
,
err
:=
m
.
oldValue
(
ctx
)
if
err
!=
nil
{
return
v
,
fmt
.
Errorf
(
"querying old value for OldAutoPauseOnExpired: %w"
,
err
)
}
return
oldValue
.
AutoPauseOnExpired
,
nil
}
// ResetAutoPauseOnExpired resets all changes to the "auto_pause_on_expired" field.
func
(
m
*
AccountMutation
)
ResetAutoPauseOnExpired
()
{
m
.
auto_pause_on_expired
=
nil
}
// SetSchedulable sets the "schedulable" field.
// SetSchedulable sets the "schedulable" field.
func
(
m
*
AccountMutation
)
SetSchedulable
(
b
bool
)
{
func
(
m
*
AccountMutation
)
SetSchedulable
(
b
bool
)
{
m
.
schedulable
=
&
b
m
.
schedulable
=
&
b
...
@@ -2269,7 +2356,7 @@ func (m *AccountMutation) Type() string {
...
@@ -2269,7 +2356,7 @@ func (m *AccountMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
// AddedFields().
func
(
m
*
AccountMutation
)
Fields
()
[]
string
{
func
(
m
*
AccountMutation
)
Fields
()
[]
string
{
fields
:=
make
([]
string
,
0
,
2
2
)
fields
:=
make
([]
string
,
0
,
2
4
)
if
m
.
created_at
!=
nil
{
if
m
.
created_at
!=
nil
{
fields
=
append
(
fields
,
account
.
FieldCreatedAt
)
fields
=
append
(
fields
,
account
.
FieldCreatedAt
)
}
}
...
@@ -2315,6 +2402,12 @@ func (m *AccountMutation) Fields() []string {
...
@@ -2315,6 +2402,12 @@ func (m *AccountMutation) Fields() []string {
if
m
.
last_used_at
!=
nil
{
if
m
.
last_used_at
!=
nil
{
fields
=
append
(
fields
,
account
.
FieldLastUsedAt
)
fields
=
append
(
fields
,
account
.
FieldLastUsedAt
)
}
}
if
m
.
expires_at
!=
nil
{
fields
=
append
(
fields
,
account
.
FieldExpiresAt
)
}
if
m
.
auto_pause_on_expired
!=
nil
{
fields
=
append
(
fields
,
account
.
FieldAutoPauseOnExpired
)
}
if
m
.
schedulable
!=
nil
{
if
m
.
schedulable
!=
nil
{
fields
=
append
(
fields
,
account
.
FieldSchedulable
)
fields
=
append
(
fields
,
account
.
FieldSchedulable
)
}
}
...
@@ -2374,6 +2467,10 @@ func (m *AccountMutation) Field(name string) (ent.Value, bool) {
...
@@ -2374,6 +2467,10 @@ func (m *AccountMutation) Field(name string) (ent.Value, bool) {
return
m
.
ErrorMessage
()
return
m
.
ErrorMessage
()
case
account
.
FieldLastUsedAt
:
case
account
.
FieldLastUsedAt
:
return
m
.
LastUsedAt
()
return
m
.
LastUsedAt
()
case
account
.
FieldExpiresAt
:
return
m
.
ExpiresAt
()
case
account
.
FieldAutoPauseOnExpired
:
return
m
.
AutoPauseOnExpired
()
case
account
.
FieldSchedulable
:
case
account
.
FieldSchedulable
:
return
m
.
Schedulable
()
return
m
.
Schedulable
()
case
account
.
FieldRateLimitedAt
:
case
account
.
FieldRateLimitedAt
:
...
@@ -2427,6 +2524,10 @@ func (m *AccountMutation) OldField(ctx context.Context, name string) (ent.Value,
...
@@ -2427,6 +2524,10 @@ func (m *AccountMutation) OldField(ctx context.Context, name string) (ent.Value,
return
m
.
OldErrorMessage
(
ctx
)
return
m
.
OldErrorMessage
(
ctx
)
case
account
.
FieldLastUsedAt
:
case
account
.
FieldLastUsedAt
:
return
m
.
OldLastUsedAt
(
ctx
)
return
m
.
OldLastUsedAt
(
ctx
)
case
account
.
FieldExpiresAt
:
return
m
.
OldExpiresAt
(
ctx
)
case
account
.
FieldAutoPauseOnExpired
:
return
m
.
OldAutoPauseOnExpired
(
ctx
)
case
account
.
FieldSchedulable
:
case
account
.
FieldSchedulable
:
return
m
.
OldSchedulable
(
ctx
)
return
m
.
OldSchedulable
(
ctx
)
case
account
.
FieldRateLimitedAt
:
case
account
.
FieldRateLimitedAt
:
...
@@ -2555,6 +2656,20 @@ func (m *AccountMutation) SetField(name string, value ent.Value) error {
...
@@ -2555,6 +2656,20 @@ func (m *AccountMutation) SetField(name string, value ent.Value) error {
}
}
m
.
SetLastUsedAt
(
v
)
m
.
SetLastUsedAt
(
v
)
return
nil
return
nil
case
account
.
FieldExpiresAt
:
v
,
ok
:=
value
.
(
time
.
Time
)
if
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field %s"
,
value
,
name
)
}
m
.
SetExpiresAt
(
v
)
return
nil
case
account
.
FieldAutoPauseOnExpired
:
v
,
ok
:=
value
.
(
bool
)
if
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field %s"
,
value
,
name
)
}
m
.
SetAutoPauseOnExpired
(
v
)
return
nil
case
account
.
FieldSchedulable
:
case
account
.
FieldSchedulable
:
v
,
ok
:=
value
.
(
bool
)
v
,
ok
:=
value
.
(
bool
)
if
!
ok
{
if
!
ok
{
...
@@ -2676,6 +2791,9 @@ func (m *AccountMutation) ClearedFields() []string {
...
@@ -2676,6 +2791,9 @@ func (m *AccountMutation) ClearedFields() []string {
if
m
.
FieldCleared
(
account
.
FieldLastUsedAt
)
{
if
m
.
FieldCleared
(
account
.
FieldLastUsedAt
)
{
fields
=
append
(
fields
,
account
.
FieldLastUsedAt
)
fields
=
append
(
fields
,
account
.
FieldLastUsedAt
)
}
}
if
m
.
FieldCleared
(
account
.
FieldExpiresAt
)
{
fields
=
append
(
fields
,
account
.
FieldExpiresAt
)
}
if
m
.
FieldCleared
(
account
.
FieldRateLimitedAt
)
{
if
m
.
FieldCleared
(
account
.
FieldRateLimitedAt
)
{
fields
=
append
(
fields
,
account
.
FieldRateLimitedAt
)
fields
=
append
(
fields
,
account
.
FieldRateLimitedAt
)
}
}
...
@@ -2723,6 +2841,9 @@ func (m *AccountMutation) ClearField(name string) error {
...
@@ -2723,6 +2841,9 @@ func (m *AccountMutation) ClearField(name string) error {
case
account
.
FieldLastUsedAt
:
case
account
.
FieldLastUsedAt
:
m
.
ClearLastUsedAt
()
m
.
ClearLastUsedAt
()
return
nil
return
nil
case
account
.
FieldExpiresAt
:
m
.
ClearExpiresAt
()
return
nil
case
account
.
FieldRateLimitedAt
:
case
account
.
FieldRateLimitedAt
:
m
.
ClearRateLimitedAt
()
m
.
ClearRateLimitedAt
()
return
nil
return
nil
...
@@ -2794,6 +2915,12 @@ func (m *AccountMutation) ResetField(name string) error {
...
@@ -2794,6 +2915,12 @@ func (m *AccountMutation) ResetField(name string) error {
case
account
.
FieldLastUsedAt
:
case
account
.
FieldLastUsedAt
:
m
.
ResetLastUsedAt
()
m
.
ResetLastUsedAt
()
return
nil
return
nil
case
account
.
FieldExpiresAt
:
m
.
ResetExpiresAt
()
return
nil
case
account
.
FieldAutoPauseOnExpired
:
m
.
ResetAutoPauseOnExpired
()
return
nil
case
account
.
FieldSchedulable
:
case
account
.
FieldSchedulable
:
m
.
ResetSchedulable
()
m
.
ResetSchedulable
()
return
nil
return
nil
...
...
backend/ent/runtime/runtime.go
View file @
2b528c5f
...
@@ -181,12 +181,16 @@ func init() {
...
@@ -181,12 +181,16 @@ func init() {
account
.
DefaultStatus
=
accountDescStatus
.
Default
.
(
string
)
account
.
DefaultStatus
=
accountDescStatus
.
Default
.
(
string
)
// account.StatusValidator is a validator for the "status" field. It is called by the builders before save.
// account.StatusValidator is a validator for the "status" field. It is called by the builders before save.
account
.
StatusValidator
=
accountDescStatus
.
Validators
[
0
]
.
(
func
(
string
)
error
)
account
.
StatusValidator
=
accountDescStatus
.
Validators
[
0
]
.
(
func
(
string
)
error
)
// accountDescAutoPauseOnExpired is the schema descriptor for auto_pause_on_expired field.
accountDescAutoPauseOnExpired
:=
accountFields
[
13
]
.
Descriptor
()
// account.DefaultAutoPauseOnExpired holds the default value on creation for the auto_pause_on_expired field.
account
.
DefaultAutoPauseOnExpired
=
accountDescAutoPauseOnExpired
.
Default
.
(
bool
)
// accountDescSchedulable is the schema descriptor for schedulable field.
// accountDescSchedulable is the schema descriptor for schedulable field.
accountDescSchedulable
:=
accountFields
[
1
2
]
.
Descriptor
()
accountDescSchedulable
:=
accountFields
[
1
4
]
.
Descriptor
()
// account.DefaultSchedulable holds the default value on creation for the schedulable field.
// account.DefaultSchedulable holds the default value on creation for the schedulable field.
account
.
DefaultSchedulable
=
accountDescSchedulable
.
Default
.
(
bool
)
account
.
DefaultSchedulable
=
accountDescSchedulable
.
Default
.
(
bool
)
// accountDescSessionWindowStatus is the schema descriptor for session_window_status field.
// accountDescSessionWindowStatus is the schema descriptor for session_window_status field.
accountDescSessionWindowStatus
:=
accountFields
[
18
]
.
Descriptor
()
accountDescSessionWindowStatus
:=
accountFields
[
20
]
.
Descriptor
()
// account.SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save.
// account.SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save.
account
.
SessionWindowStatusValidator
=
accountDescSessionWindowStatus
.
Validators
[
0
]
.
(
func
(
string
)
error
)
account
.
SessionWindowStatusValidator
=
accountDescSessionWindowStatus
.
Validators
[
0
]
.
(
func
(
string
)
error
)
accountgroupFields
:=
schema
.
AccountGroup
{}
.
Fields
()
accountgroupFields
:=
schema
.
AccountGroup
{}
.
Fields
()
...
...
backend/ent/schema/account.go
View file @
2b528c5f
...
@@ -118,6 +118,16 @@ func (Account) Fields() []ent.Field {
...
@@ -118,6 +118,16 @@ func (Account) Fields() []ent.Field {
Optional
()
.
Optional
()
.
Nillable
()
.
Nillable
()
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"timestamptz"
}),
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"timestamptz"
}),
// expires_at: 账户过期时间(可为空)
field
.
Time
(
"expires_at"
)
.
Optional
()
.
Nillable
()
.
Comment
(
"Account expiration time (NULL means no expiration)."
)
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"timestamptz"
}),
// auto_pause_on_expired: 过期后自动暂停调度
field
.
Bool
(
"auto_pause_on_expired"
)
.
Default
(
true
)
.
Comment
(
"Auto pause scheduling when account expires."
),
// ========== 调度和速率限制相关字段 ==========
// ========== 调度和速率限制相关字段 ==========
// 这些字段在 migrations/005_schema_parity.sql 中添加
// 这些字段在 migrations/005_schema_parity.sql 中添加
...
...
backend/internal/handler/admin/account_handler.go
View file @
2b528c5f
...
@@ -85,6 +85,8 @@ type CreateAccountRequest struct {
...
@@ -85,6 +85,8 @@ type CreateAccountRequest struct {
Concurrency
int
`json:"concurrency"`
Concurrency
int
`json:"concurrency"`
Priority
int
`json:"priority"`
Priority
int
`json:"priority"`
GroupIDs
[]
int64
`json:"group_ids"`
GroupIDs
[]
int64
`json:"group_ids"`
ExpiresAt
*
int64
`json:"expires_at"`
AutoPauseOnExpired
*
bool
`json:"auto_pause_on_expired"`
ConfirmMixedChannelRisk
*
bool
`json:"confirm_mixed_channel_risk"`
// 用户确认混合渠道风险
ConfirmMixedChannelRisk
*
bool
`json:"confirm_mixed_channel_risk"`
// 用户确认混合渠道风险
}
}
...
@@ -101,6 +103,8 @@ type UpdateAccountRequest struct {
...
@@ -101,6 +103,8 @@ type UpdateAccountRequest struct {
Priority
*
int
`json:"priority"`
Priority
*
int
`json:"priority"`
Status
string
`json:"status" binding:"omitempty,oneof=active inactive"`
Status
string
`json:"status" binding:"omitempty,oneof=active inactive"`
GroupIDs
*
[]
int64
`json:"group_ids"`
GroupIDs
*
[]
int64
`json:"group_ids"`
ExpiresAt
*
int64
`json:"expires_at"`
AutoPauseOnExpired
*
bool
`json:"auto_pause_on_expired"`
ConfirmMixedChannelRisk
*
bool
`json:"confirm_mixed_channel_risk"`
// 用户确认混合渠道风险
ConfirmMixedChannelRisk
*
bool
`json:"confirm_mixed_channel_risk"`
// 用户确认混合渠道风险
}
}
...
@@ -204,6 +208,8 @@ func (h *AccountHandler) Create(c *gin.Context) {
...
@@ -204,6 +208,8 @@ func (h *AccountHandler) Create(c *gin.Context) {
Concurrency
:
req
.
Concurrency
,
Concurrency
:
req
.
Concurrency
,
Priority
:
req
.
Priority
,
Priority
:
req
.
Priority
,
GroupIDs
:
req
.
GroupIDs
,
GroupIDs
:
req
.
GroupIDs
,
ExpiresAt
:
req
.
ExpiresAt
,
AutoPauseOnExpired
:
req
.
AutoPauseOnExpired
,
SkipMixedChannelCheck
:
skipCheck
,
SkipMixedChannelCheck
:
skipCheck
,
})
})
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -261,6 +267,8 @@ func (h *AccountHandler) Update(c *gin.Context) {
...
@@ -261,6 +267,8 @@ func (h *AccountHandler) Update(c *gin.Context) {
Priority
:
req
.
Priority
,
// 指针类型,nil 表示未提供
Priority
:
req
.
Priority
,
// 指针类型,nil 表示未提供
Status
:
req
.
Status
,
Status
:
req
.
Status
,
GroupIDs
:
req
.
GroupIDs
,
GroupIDs
:
req
.
GroupIDs
,
ExpiresAt
:
req
.
ExpiresAt
,
AutoPauseOnExpired
:
req
.
AutoPauseOnExpired
,
SkipMixedChannelCheck
:
skipCheck
,
SkipMixedChannelCheck
:
skipCheck
,
})
})
if
err
!=
nil
{
if
err
!=
nil
{
...
...
backend/internal/handler/dto/mappers.go
View file @
2b528c5f
// Package dto provides data transfer objects for HTTP handlers.
// Package dto provides data transfer objects for HTTP handlers.
package
dto
package
dto
import
"github.com/Wei-Shaw/sub2api/internal/service"
import
(
"time"
"github.com/Wei-Shaw/sub2api/internal/service"
)
func
UserFromServiceShallow
(
u
*
service
.
User
)
*
User
{
func
UserFromServiceShallow
(
u
*
service
.
User
)
*
User
{
if
u
==
nil
{
if
u
==
nil
{
...
@@ -120,6 +124,8 @@ func AccountFromServiceShallow(a *service.Account) *Account {
...
@@ -120,6 +124,8 @@ func AccountFromServiceShallow(a *service.Account) *Account {
Status
:
a
.
Status
,
Status
:
a
.
Status
,
ErrorMessage
:
a
.
ErrorMessage
,
ErrorMessage
:
a
.
ErrorMessage
,
LastUsedAt
:
a
.
LastUsedAt
,
LastUsedAt
:
a
.
LastUsedAt
,
ExpiresAt
:
timeToUnixSeconds
(
a
.
ExpiresAt
),
AutoPauseOnExpired
:
a
.
AutoPauseOnExpired
,
CreatedAt
:
a
.
CreatedAt
,
CreatedAt
:
a
.
CreatedAt
,
UpdatedAt
:
a
.
UpdatedAt
,
UpdatedAt
:
a
.
UpdatedAt
,
Schedulable
:
a
.
Schedulable
,
Schedulable
:
a
.
Schedulable
,
...
@@ -157,6 +163,14 @@ func AccountFromService(a *service.Account) *Account {
...
@@ -157,6 +163,14 @@ func AccountFromService(a *service.Account) *Account {
return
out
return
out
}
}
func
timeToUnixSeconds
(
value
*
time
.
Time
)
*
int64
{
if
value
==
nil
{
return
nil
}
ts
:=
value
.
Unix
()
return
&
ts
}
func
AccountGroupFromService
(
ag
*
service
.
AccountGroup
)
*
AccountGroup
{
func
AccountGroupFromService
(
ag
*
service
.
AccountGroup
)
*
AccountGroup
{
if
ag
==
nil
{
if
ag
==
nil
{
return
nil
return
nil
...
...
backend/internal/handler/dto/types.go
View file @
2b528c5f
...
@@ -60,21 +60,23 @@ type Group struct {
...
@@ -60,21 +60,23 @@ type Group struct {
}
}
type
Account
struct
{
type
Account
struct
{
ID
int64
`json:"id"`
ID
int64
`json:"id"`
Name
string
`json:"name"`
Name
string
`json:"name"`
Notes
*
string
`json:"notes"`
Notes
*
string
`json:"notes"`
Platform
string
`json:"platform"`
Platform
string
`json:"platform"`
Type
string
`json:"type"`
Type
string
`json:"type"`
Credentials
map
[
string
]
any
`json:"credentials"`
Credentials
map
[
string
]
any
`json:"credentials"`
Extra
map
[
string
]
any
`json:"extra"`
Extra
map
[
string
]
any
`json:"extra"`
ProxyID
*
int64
`json:"proxy_id"`
ProxyID
*
int64
`json:"proxy_id"`
Concurrency
int
`json:"concurrency"`
Concurrency
int
`json:"concurrency"`
Priority
int
`json:"priority"`
Priority
int
`json:"priority"`
Status
string
`json:"status"`
Status
string
`json:"status"`
ErrorMessage
string
`json:"error_message"`
ErrorMessage
string
`json:"error_message"`
LastUsedAt
*
time
.
Time
`json:"last_used_at"`
LastUsedAt
*
time
.
Time
`json:"last_used_at"`
CreatedAt
time
.
Time
`json:"created_at"`
ExpiresAt
*
int64
`json:"expires_at"`
UpdatedAt
time
.
Time
`json:"updated_at"`
AutoPauseOnExpired
bool
`json:"auto_pause_on_expired"`
CreatedAt
time
.
Time
`json:"created_at"`
UpdatedAt
time
.
Time
`json:"updated_at"`
Schedulable
bool
`json:"schedulable"`
Schedulable
bool
`json:"schedulable"`
...
...
backend/internal/repository/account_repo.go
View file @
2b528c5f
...
@@ -76,7 +76,8 @@ func (r *accountRepository) Create(ctx context.Context, account *service.Account
...
@@ -76,7 +76,8 @@ func (r *accountRepository) Create(ctx context.Context, account *service.Account
SetPriority
(
account
.
Priority
)
.
SetPriority
(
account
.
Priority
)
.
SetStatus
(
account
.
Status
)
.
SetStatus
(
account
.
Status
)
.
SetErrorMessage
(
account
.
ErrorMessage
)
.
SetErrorMessage
(
account
.
ErrorMessage
)
.
SetSchedulable
(
account
.
Schedulable
)
SetSchedulable
(
account
.
Schedulable
)
.
SetAutoPauseOnExpired
(
account
.
AutoPauseOnExpired
)
if
account
.
ProxyID
!=
nil
{
if
account
.
ProxyID
!=
nil
{
builder
.
SetProxyID
(
*
account
.
ProxyID
)
builder
.
SetProxyID
(
*
account
.
ProxyID
)
...
@@ -84,6 +85,9 @@ func (r *accountRepository) Create(ctx context.Context, account *service.Account
...
@@ -84,6 +85,9 @@ func (r *accountRepository) Create(ctx context.Context, account *service.Account
if
account
.
LastUsedAt
!=
nil
{
if
account
.
LastUsedAt
!=
nil
{
builder
.
SetLastUsedAt
(
*
account
.
LastUsedAt
)
builder
.
SetLastUsedAt
(
*
account
.
LastUsedAt
)
}
}
if
account
.
ExpiresAt
!=
nil
{
builder
.
SetExpiresAt
(
*
account
.
ExpiresAt
)
}
if
account
.
RateLimitedAt
!=
nil
{
if
account
.
RateLimitedAt
!=
nil
{
builder
.
SetRateLimitedAt
(
*
account
.
RateLimitedAt
)
builder
.
SetRateLimitedAt
(
*
account
.
RateLimitedAt
)
}
}
...
@@ -280,7 +284,8 @@ func (r *accountRepository) Update(ctx context.Context, account *service.Account
...
@@ -280,7 +284,8 @@ func (r *accountRepository) Update(ctx context.Context, account *service.Account
SetPriority
(
account
.
Priority
)
.
SetPriority
(
account
.
Priority
)
.
SetStatus
(
account
.
Status
)
.
SetStatus
(
account
.
Status
)
.
SetErrorMessage
(
account
.
ErrorMessage
)
.
SetErrorMessage
(
account
.
ErrorMessage
)
.
SetSchedulable
(
account
.
Schedulable
)
SetSchedulable
(
account
.
Schedulable
)
.
SetAutoPauseOnExpired
(
account
.
AutoPauseOnExpired
)
if
account
.
ProxyID
!=
nil
{
if
account
.
ProxyID
!=
nil
{
builder
.
SetProxyID
(
*
account
.
ProxyID
)
builder
.
SetProxyID
(
*
account
.
ProxyID
)
...
@@ -292,6 +297,11 @@ func (r *accountRepository) Update(ctx context.Context, account *service.Account
...
@@ -292,6 +297,11 @@ func (r *accountRepository) Update(ctx context.Context, account *service.Account
}
else
{
}
else
{
builder
.
ClearLastUsedAt
()
builder
.
ClearLastUsedAt
()
}
}
if
account
.
ExpiresAt
!=
nil
{
builder
.
SetExpiresAt
(
*
account
.
ExpiresAt
)
}
else
{
builder
.
ClearExpiresAt
()
}
if
account
.
RateLimitedAt
!=
nil
{
if
account
.
RateLimitedAt
!=
nil
{
builder
.
SetRateLimitedAt
(
*
account
.
RateLimitedAt
)
builder
.
SetRateLimitedAt
(
*
account
.
RateLimitedAt
)
}
else
{
}
else
{
...
@@ -570,6 +580,7 @@ func (r *accountRepository) ListSchedulable(ctx context.Context) ([]service.Acco
...
@@ -570,6 +580,7 @@ func (r *accountRepository) ListSchedulable(ctx context.Context) ([]service.Acco
dbaccount
.
StatusEQ
(
service
.
StatusActive
),
dbaccount
.
StatusEQ
(
service
.
StatusActive
),
dbaccount
.
SchedulableEQ
(
true
),
dbaccount
.
SchedulableEQ
(
true
),
tempUnschedulablePredicate
(),
tempUnschedulablePredicate
(),
notExpiredPredicate
(
now
),
dbaccount
.
Or
(
dbaccount
.
OverloadUntilIsNil
(),
dbaccount
.
OverloadUntilLTE
(
now
)),
dbaccount
.
Or
(
dbaccount
.
OverloadUntilIsNil
(),
dbaccount
.
OverloadUntilLTE
(
now
)),
dbaccount
.
Or
(
dbaccount
.
RateLimitResetAtIsNil
(),
dbaccount
.
RateLimitResetAtLTE
(
now
)),
dbaccount
.
Or
(
dbaccount
.
RateLimitResetAtIsNil
(),
dbaccount
.
RateLimitResetAtLTE
(
now
)),
)
.
)
.
...
@@ -596,6 +607,7 @@ func (r *accountRepository) ListSchedulableByPlatform(ctx context.Context, platf
...
@@ -596,6 +607,7 @@ func (r *accountRepository) ListSchedulableByPlatform(ctx context.Context, platf
dbaccount
.
StatusEQ
(
service
.
StatusActive
),
dbaccount
.
StatusEQ
(
service
.
StatusActive
),
dbaccount
.
SchedulableEQ
(
true
),
dbaccount
.
SchedulableEQ
(
true
),
tempUnschedulablePredicate
(),
tempUnschedulablePredicate
(),
notExpiredPredicate
(
now
),
dbaccount
.
Or
(
dbaccount
.
OverloadUntilIsNil
(),
dbaccount
.
OverloadUntilLTE
(
now
)),
dbaccount
.
Or
(
dbaccount
.
OverloadUntilIsNil
(),
dbaccount
.
OverloadUntilLTE
(
now
)),
dbaccount
.
Or
(
dbaccount
.
RateLimitResetAtIsNil
(),
dbaccount
.
RateLimitResetAtLTE
(
now
)),
dbaccount
.
Or
(
dbaccount
.
RateLimitResetAtIsNil
(),
dbaccount
.
RateLimitResetAtLTE
(
now
)),
)
.
)
.
...
@@ -629,6 +641,7 @@ func (r *accountRepository) ListSchedulableByPlatforms(ctx context.Context, plat
...
@@ -629,6 +641,7 @@ func (r *accountRepository) ListSchedulableByPlatforms(ctx context.Context, plat
dbaccount
.
StatusEQ
(
service
.
StatusActive
),
dbaccount
.
StatusEQ
(
service
.
StatusActive
),
dbaccount
.
SchedulableEQ
(
true
),
dbaccount
.
SchedulableEQ
(
true
),
tempUnschedulablePredicate
(),
tempUnschedulablePredicate
(),
notExpiredPredicate
(
now
),
dbaccount
.
Or
(
dbaccount
.
OverloadUntilIsNil
(),
dbaccount
.
OverloadUntilLTE
(
now
)),
dbaccount
.
Or
(
dbaccount
.
OverloadUntilIsNil
(),
dbaccount
.
OverloadUntilLTE
(
now
)),
dbaccount
.
Or
(
dbaccount
.
RateLimitResetAtIsNil
(),
dbaccount
.
RateLimitResetAtLTE
(
now
)),
dbaccount
.
Or
(
dbaccount
.
RateLimitResetAtIsNil
(),
dbaccount
.
RateLimitResetAtLTE
(
now
)),
)
.
)
.
...
@@ -727,6 +740,27 @@ func (r *accountRepository) SetSchedulable(ctx context.Context, id int64, schedu
...
@@ -727,6 +740,27 @@ func (r *accountRepository) SetSchedulable(ctx context.Context, id int64, schedu
return
err
return
err
}
}
func
(
r
*
accountRepository
)
AutoPauseExpiredAccounts
(
ctx
context
.
Context
,
now
time
.
Time
)
(
int64
,
error
)
{
result
,
err
:=
r
.
sql
.
ExecContext
(
ctx
,
`
UPDATE accounts
SET schedulable = FALSE,
updated_at = NOW()
WHERE deleted_at IS NULL
AND schedulable = TRUE
AND auto_pause_on_expired = TRUE
AND expires_at IS NOT NULL
AND expires_at <= $1
`
,
now
)
if
err
!=
nil
{
return
0
,
err
}
rows
,
err
:=
result
.
RowsAffected
()
if
err
!=
nil
{
return
0
,
err
}
return
rows
,
nil
}
func
(
r
*
accountRepository
)
UpdateExtra
(
ctx
context
.
Context
,
id
int64
,
updates
map
[
string
]
any
)
error
{
func
(
r
*
accountRepository
)
UpdateExtra
(
ctx
context
.
Context
,
id
int64
,
updates
map
[
string
]
any
)
error
{
if
len
(
updates
)
==
0
{
if
len
(
updates
)
==
0
{
return
nil
return
nil
...
@@ -861,6 +895,7 @@ func (r *accountRepository) queryAccountsByGroup(ctx context.Context, groupID in
...
@@ -861,6 +895,7 @@ func (r *accountRepository) queryAccountsByGroup(ctx context.Context, groupID in
preds
=
append
(
preds
,
preds
=
append
(
preds
,
dbaccount
.
SchedulableEQ
(
true
),
dbaccount
.
SchedulableEQ
(
true
),
tempUnschedulablePredicate
(),
tempUnschedulablePredicate
(),
notExpiredPredicate
(
now
),
dbaccount
.
Or
(
dbaccount
.
OverloadUntilIsNil
(),
dbaccount
.
OverloadUntilLTE
(
now
)),
dbaccount
.
Or
(
dbaccount
.
OverloadUntilIsNil
(),
dbaccount
.
OverloadUntilLTE
(
now
)),
dbaccount
.
Or
(
dbaccount
.
RateLimitResetAtIsNil
(),
dbaccount
.
RateLimitResetAtLTE
(
now
)),
dbaccount
.
Or
(
dbaccount
.
RateLimitResetAtIsNil
(),
dbaccount
.
RateLimitResetAtLTE
(
now
)),
)
)
...
@@ -971,6 +1006,14 @@ func tempUnschedulablePredicate() dbpredicate.Account {
...
@@ -971,6 +1006,14 @@ func tempUnschedulablePredicate() dbpredicate.Account {
})
})
}
}
func
notExpiredPredicate
(
now
time
.
Time
)
dbpredicate
.
Account
{
return
dbaccount
.
Or
(
dbaccount
.
ExpiresAtIsNil
(),
dbaccount
.
ExpiresAtGT
(
now
),
dbaccount
.
AutoPauseOnExpiredEQ
(
false
),
)
}
func
(
r
*
accountRepository
)
loadTempUnschedStates
(
ctx
context
.
Context
,
accountIDs
[]
int64
)
(
map
[
int64
]
tempUnschedSnapshot
,
error
)
{
func
(
r
*
accountRepository
)
loadTempUnschedStates
(
ctx
context
.
Context
,
accountIDs
[]
int64
)
(
map
[
int64
]
tempUnschedSnapshot
,
error
)
{
out
:=
make
(
map
[
int64
]
tempUnschedSnapshot
)
out
:=
make
(
map
[
int64
]
tempUnschedSnapshot
)
if
len
(
accountIDs
)
==
0
{
if
len
(
accountIDs
)
==
0
{
...
@@ -1086,6 +1129,8 @@ func accountEntityToService(m *dbent.Account) *service.Account {
...
@@ -1086,6 +1129,8 @@ func accountEntityToService(m *dbent.Account) *service.Account {
Status
:
m
.
Status
,
Status
:
m
.
Status
,
ErrorMessage
:
derefString
(
m
.
ErrorMessage
),
ErrorMessage
:
derefString
(
m
.
ErrorMessage
),
LastUsedAt
:
m
.
LastUsedAt
,
LastUsedAt
:
m
.
LastUsedAt
,
ExpiresAt
:
m
.
ExpiresAt
,
AutoPauseOnExpired
:
m
.
AutoPauseOnExpired
,
CreatedAt
:
m
.
CreatedAt
,
CreatedAt
:
m
.
CreatedAt
,
UpdatedAt
:
m
.
UpdatedAt
,
UpdatedAt
:
m
.
UpdatedAt
,
Schedulable
:
m
.
Schedulable
,
Schedulable
:
m
.
Schedulable
,
...
...
backend/internal/service/account.go
View file @
2b528c5f
...
@@ -9,21 +9,23 @@ import (
...
@@ -9,21 +9,23 @@ import (
)
)
type
Account
struct
{
type
Account
struct
{
ID
int64
ID
int64
Name
string
Name
string
Notes
*
string
Notes
*
string
Platform
string
Platform
string
Type
string
Type
string
Credentials
map
[
string
]
any
Credentials
map
[
string
]
any
Extra
map
[
string
]
any
Extra
map
[
string
]
any
ProxyID
*
int64
ProxyID
*
int64
Concurrency
int
Concurrency
int
Priority
int
Priority
int
Status
string
Status
string
ErrorMessage
string
ErrorMessage
string
LastUsedAt
*
time
.
Time
LastUsedAt
*
time
.
Time
CreatedAt
time
.
Time
ExpiresAt
*
time
.
Time
UpdatedAt
time
.
Time
AutoPauseOnExpired
bool
CreatedAt
time
.
Time
UpdatedAt
time
.
Time
Schedulable
bool
Schedulable
bool
...
@@ -60,6 +62,9 @@ func (a *Account) IsSchedulable() bool {
...
@@ -60,6 +62,9 @@ func (a *Account) IsSchedulable() bool {
return
false
return
false
}
}
now
:=
time
.
Now
()
now
:=
time
.
Now
()
if
a
.
AutoPauseOnExpired
&&
a
.
ExpiresAt
!=
nil
&&
!
now
.
Before
(
*
a
.
ExpiresAt
)
{
return
false
}
if
a
.
OverloadUntil
!=
nil
&&
now
.
Before
(
*
a
.
OverloadUntil
)
{
if
a
.
OverloadUntil
!=
nil
&&
now
.
Before
(
*
a
.
OverloadUntil
)
{
return
false
return
false
}
}
...
...
backend/internal/service/account_expiry_service.go
0 → 100644
View file @
2b528c5f
package
service
import
(
"context"
"log"
"sync"
"time"
)
// AccountExpiryService periodically pauses expired accounts when auto-pause is enabled.
type
AccountExpiryService
struct
{
accountRepo
AccountRepository
interval
time
.
Duration
stopCh
chan
struct
{}
stopOnce
sync
.
Once
wg
sync
.
WaitGroup
}
func
NewAccountExpiryService
(
accountRepo
AccountRepository
,
interval
time
.
Duration
)
*
AccountExpiryService
{
return
&
AccountExpiryService
{
accountRepo
:
accountRepo
,
interval
:
interval
,
stopCh
:
make
(
chan
struct
{}),
}
}
func
(
s
*
AccountExpiryService
)
Start
()
{
if
s
==
nil
||
s
.
accountRepo
==
nil
||
s
.
interval
<=
0
{
return
}
s
.
wg
.
Add
(
1
)
go
func
()
{
defer
s
.
wg
.
Done
()
ticker
:=
time
.
NewTicker
(
s
.
interval
)
defer
ticker
.
Stop
()
s
.
runOnce
()
for
{
select
{
case
<-
ticker
.
C
:
s
.
runOnce
()
case
<-
s
.
stopCh
:
return
}
}
}()
}
func
(
s
*
AccountExpiryService
)
Stop
()
{
if
s
==
nil
{
return
}
s
.
stopOnce
.
Do
(
func
()
{
close
(
s
.
stopCh
)
})
s
.
wg
.
Wait
()
}
func
(
s
*
AccountExpiryService
)
runOnce
()
{
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
5
*
time
.
Second
)
defer
cancel
()
updated
,
err
:=
s
.
accountRepo
.
AutoPauseExpiredAccounts
(
ctx
,
time
.
Now
())
if
err
!=
nil
{
log
.
Printf
(
"[AccountExpiry] Auto pause expired accounts failed: %v"
,
err
)
return
}
if
updated
>
0
{
log
.
Printf
(
"[AccountExpiry] Auto paused %d expired accounts"
,
updated
)
}
}
backend/internal/service/account_service.go
View file @
2b528c5f
...
@@ -38,6 +38,7 @@ type AccountRepository interface {
...
@@ -38,6 +38,7 @@ type AccountRepository interface {
BatchUpdateLastUsed
(
ctx
context
.
Context
,
updates
map
[
int64
]
time
.
Time
)
error
BatchUpdateLastUsed
(
ctx
context
.
Context
,
updates
map
[
int64
]
time
.
Time
)
error
SetError
(
ctx
context
.
Context
,
id
int64
,
errorMsg
string
)
error
SetError
(
ctx
context
.
Context
,
id
int64
,
errorMsg
string
)
error
SetSchedulable
(
ctx
context
.
Context
,
id
int64
,
schedulable
bool
)
error
SetSchedulable
(
ctx
context
.
Context
,
id
int64
,
schedulable
bool
)
error
AutoPauseExpiredAccounts
(
ctx
context
.
Context
,
now
time
.
Time
)
(
int64
,
error
)
BindGroups
(
ctx
context
.
Context
,
accountID
int64
,
groupIDs
[]
int64
)
error
BindGroups
(
ctx
context
.
Context
,
accountID
int64
,
groupIDs
[]
int64
)
error
ListSchedulable
(
ctx
context
.
Context
)
([]
Account
,
error
)
ListSchedulable
(
ctx
context
.
Context
)
([]
Account
,
error
)
...
@@ -71,29 +72,33 @@ type AccountBulkUpdate struct {
...
@@ -71,29 +72,33 @@ type AccountBulkUpdate struct {
// CreateAccountRequest 创建账号请求
// CreateAccountRequest 创建账号请求
type
CreateAccountRequest
struct
{
type
CreateAccountRequest
struct
{
Name
string
`json:"name"`
Name
string
`json:"name"`
Notes
*
string
`json:"notes"`
Notes
*
string
`json:"notes"`
Platform
string
`json:"platform"`
Platform
string
`json:"platform"`
Type
string
`json:"type"`
Type
string
`json:"type"`
Credentials
map
[
string
]
any
`json:"credentials"`
Credentials
map
[
string
]
any
`json:"credentials"`
Extra
map
[
string
]
any
`json:"extra"`
Extra
map
[
string
]
any
`json:"extra"`
ProxyID
*
int64
`json:"proxy_id"`
ProxyID
*
int64
`json:"proxy_id"`
Concurrency
int
`json:"concurrency"`
Concurrency
int
`json:"concurrency"`
Priority
int
`json:"priority"`
Priority
int
`json:"priority"`
GroupIDs
[]
int64
`json:"group_ids"`
GroupIDs
[]
int64
`json:"group_ids"`
ExpiresAt
*
time
.
Time
`json:"expires_at"`
AutoPauseOnExpired
*
bool
`json:"auto_pause_on_expired"`
}
}
// UpdateAccountRequest 更新账号请求
// UpdateAccountRequest 更新账号请求
type
UpdateAccountRequest
struct
{
type
UpdateAccountRequest
struct
{
Name
*
string
`json:"name"`
Name
*
string
`json:"name"`
Notes
*
string
`json:"notes"`
Notes
*
string
`json:"notes"`
Credentials
*
map
[
string
]
any
`json:"credentials"`
Credentials
*
map
[
string
]
any
`json:"credentials"`
Extra
*
map
[
string
]
any
`json:"extra"`
Extra
*
map
[
string
]
any
`json:"extra"`
ProxyID
*
int64
`json:"proxy_id"`
ProxyID
*
int64
`json:"proxy_id"`
Concurrency
*
int
`json:"concurrency"`
Concurrency
*
int
`json:"concurrency"`
Priority
*
int
`json:"priority"`
Priority
*
int
`json:"priority"`
Status
*
string
`json:"status"`
Status
*
string
`json:"status"`
GroupIDs
*
[]
int64
`json:"group_ids"`
GroupIDs
*
[]
int64
`json:"group_ids"`
ExpiresAt
*
time
.
Time
`json:"expires_at"`
AutoPauseOnExpired
*
bool
`json:"auto_pause_on_expired"`
}
}
// AccountService 账号管理服务
// AccountService 账号管理服务
...
@@ -134,6 +139,12 @@ func (s *AccountService) Create(ctx context.Context, req CreateAccountRequest) (
...
@@ -134,6 +139,12 @@ func (s *AccountService) Create(ctx context.Context, req CreateAccountRequest) (
Concurrency
:
req
.
Concurrency
,
Concurrency
:
req
.
Concurrency
,
Priority
:
req
.
Priority
,
Priority
:
req
.
Priority
,
Status
:
StatusActive
,
Status
:
StatusActive
,
ExpiresAt
:
req
.
ExpiresAt
,
}
if
req
.
AutoPauseOnExpired
!=
nil
{
account
.
AutoPauseOnExpired
=
*
req
.
AutoPauseOnExpired
}
else
{
account
.
AutoPauseOnExpired
=
true
}
}
if
err
:=
s
.
accountRepo
.
Create
(
ctx
,
account
);
err
!=
nil
{
if
err
:=
s
.
accountRepo
.
Create
(
ctx
,
account
);
err
!=
nil
{
...
@@ -224,6 +235,12 @@ func (s *AccountService) Update(ctx context.Context, id int64, req UpdateAccount
...
@@ -224,6 +235,12 @@ func (s *AccountService) Update(ctx context.Context, id int64, req UpdateAccount
if
req
.
Status
!=
nil
{
if
req
.
Status
!=
nil
{
account
.
Status
=
*
req
.
Status
account
.
Status
=
*
req
.
Status
}
}
if
req
.
ExpiresAt
!=
nil
{
account
.
ExpiresAt
=
req
.
ExpiresAt
}
if
req
.
AutoPauseOnExpired
!=
nil
{
account
.
AutoPauseOnExpired
=
*
req
.
AutoPauseOnExpired
}
// 先验证分组是否存在(在任何写操作之前)
// 先验证分组是否存在(在任何写操作之前)
if
req
.
GroupIDs
!=
nil
{
if
req
.
GroupIDs
!=
nil
{
...
...
backend/internal/service/account_service_delete_test.go
View file @
2b528c5f
...
@@ -103,6 +103,10 @@ func (s *accountRepoStub) SetSchedulable(ctx context.Context, id int64, schedula
...
@@ -103,6 +103,10 @@ func (s *accountRepoStub) SetSchedulable(ctx context.Context, id int64, schedula
panic
(
"unexpected SetSchedulable call"
)
panic
(
"unexpected SetSchedulable call"
)
}
}
func
(
s
*
accountRepoStub
)
AutoPauseExpiredAccounts
(
ctx
context
.
Context
,
now
time
.
Time
)
(
int64
,
error
)
{
panic
(
"unexpected AutoPauseExpiredAccounts call"
)
}
func
(
s
*
accountRepoStub
)
BindGroups
(
ctx
context
.
Context
,
accountID
int64
,
groupIDs
[]
int64
)
error
{
func
(
s
*
accountRepoStub
)
BindGroups
(
ctx
context
.
Context
,
accountID
int64
,
groupIDs
[]
int64
)
error
{
panic
(
"unexpected BindGroups call"
)
panic
(
"unexpected BindGroups call"
)
}
}
...
...
backend/internal/service/admin_service.go
View file @
2b528c5f
...
@@ -122,16 +122,18 @@ type UpdateGroupInput struct {
...
@@ -122,16 +122,18 @@ type UpdateGroupInput struct {
}
}
type
CreateAccountInput
struct
{
type
CreateAccountInput
struct
{
Name
string
Name
string
Notes
*
string
Notes
*
string
Platform
string
Platform
string
Type
string
Type
string
Credentials
map
[
string
]
any
Credentials
map
[
string
]
any
Extra
map
[
string
]
any
Extra
map
[
string
]
any
ProxyID
*
int64
ProxyID
*
int64
Concurrency
int
Concurrency
int
Priority
int
Priority
int
GroupIDs
[]
int64
GroupIDs
[]
int64
ExpiresAt
*
int64
AutoPauseOnExpired
*
bool
// SkipMixedChannelCheck skips the mixed channel risk check when binding groups.
// SkipMixedChannelCheck skips the mixed channel risk check when binding groups.
// This should only be set when the caller has explicitly confirmed the risk.
// This should only be set when the caller has explicitly confirmed the risk.
SkipMixedChannelCheck
bool
SkipMixedChannelCheck
bool
...
@@ -148,6 +150,8 @@ type UpdateAccountInput struct {
...
@@ -148,6 +150,8 @@ type UpdateAccountInput struct {
Priority
*
int
// 使用指针区分"未提供"和"设置为0"
Priority
*
int
// 使用指针区分"未提供"和"设置为0"
Status
string
Status
string
GroupIDs
*
[]
int64
GroupIDs
*
[]
int64
ExpiresAt
*
int64
AutoPauseOnExpired
*
bool
SkipMixedChannelCheck
bool
// 跳过混合渠道检查(用户已确认风险)
SkipMixedChannelCheck
bool
// 跳过混合渠道检查(用户已确认风险)
}
}
...
@@ -700,6 +704,15 @@ func (s *adminServiceImpl) CreateAccount(ctx context.Context, input *CreateAccou
...
@@ -700,6 +704,15 @@ func (s *adminServiceImpl) CreateAccount(ctx context.Context, input *CreateAccou
Status
:
StatusActive
,
Status
:
StatusActive
,
Schedulable
:
true
,
Schedulable
:
true
,
}
}
if
input
.
ExpiresAt
!=
nil
&&
*
input
.
ExpiresAt
>
0
{
expiresAt
:=
time
.
Unix
(
*
input
.
ExpiresAt
,
0
)
account
.
ExpiresAt
=
&
expiresAt
}
if
input
.
AutoPauseOnExpired
!=
nil
{
account
.
AutoPauseOnExpired
=
*
input
.
AutoPauseOnExpired
}
else
{
account
.
AutoPauseOnExpired
=
true
}
if
err
:=
s
.
accountRepo
.
Create
(
ctx
,
account
);
err
!=
nil
{
if
err
:=
s
.
accountRepo
.
Create
(
ctx
,
account
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -755,6 +768,17 @@ func (s *adminServiceImpl) UpdateAccount(ctx context.Context, id int64, input *U
...
@@ -755,6 +768,17 @@ func (s *adminServiceImpl) UpdateAccount(ctx context.Context, id int64, input *U
if
input
.
Status
!=
""
{
if
input
.
Status
!=
""
{
account
.
Status
=
input
.
Status
account
.
Status
=
input
.
Status
}
}
if
input
.
ExpiresAt
!=
nil
{
if
*
input
.
ExpiresAt
<=
0
{
account
.
ExpiresAt
=
nil
}
else
{
expiresAt
:=
time
.
Unix
(
*
input
.
ExpiresAt
,
0
)
account
.
ExpiresAt
=
&
expiresAt
}
}
if
input
.
AutoPauseOnExpired
!=
nil
{
account
.
AutoPauseOnExpired
=
*
input
.
AutoPauseOnExpired
}
// 先验证分组是否存在(在任何写操作之前)
// 先验证分组是否存在(在任何写操作之前)
if
input
.
GroupIDs
!=
nil
{
if
input
.
GroupIDs
!=
nil
{
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment