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
e5a79fed
"git@web.lueluesay.top:chenxi/sub2api.git" did not exist on "ec6bcfeb83bd362ec5d6ec5e5935b404cd2353c3"
Commit
e5a79fed
authored
Dec 30, 2025
by
yangjianbo
Browse files
Merge branch 'test-dev'
parents
148048b0
b9a753cd
Changes
2
Show whitespace changes
Inline
Side-by-side
.gitignore
View file @
e5a79fed
...
@@ -108,9 +108,11 @@ backend/.installed
...
@@ -108,9 +108,11 @@ backend/.installed
# ===================
# ===================
tests
tests
CLAUDE.md
CLAUDE.md
AGENTS.md
.claude
.claude
scripts
scripts
.code-review-state
.code-review-state
openspec/
openspec/
code-reviews/
docs/
docs/
code-reviews/
AGENTS.md
backend/internal/repository/account_repo.go
View file @
e5a79fed
...
@@ -457,10 +457,11 @@ func (r *accountRepository) ListSchedulableByPlatform(ctx context.Context, platf
...
@@ -457,10 +457,11 @@ func (r *accountRepository) ListSchedulableByPlatform(ctx context.Context, platf
}
}
func
(
r
*
accountRepository
)
ListSchedulableByGroupIDAndPlatform
(
ctx
context
.
Context
,
groupID
int64
,
platform
string
)
([]
service
.
Account
,
error
)
{
func
(
r
*
accountRepository
)
ListSchedulableByGroupIDAndPlatform
(
ctx
context
.
Context
,
groupID
int64
,
platform
string
)
([]
service
.
Account
,
error
)
{
// 单平台查询复用多平台逻辑,保持过滤条件与排序策略一致。
return
r
.
queryAccountsByGroup
(
ctx
,
groupID
,
accountGroupQueryOptions
{
return
r
.
queryAccountsByGroup
(
ctx
,
groupID
,
accountGroupQueryOptions
{
status
:
service
.
StatusActive
,
status
:
service
.
StatusActive
,
schedulable
:
true
,
schedulable
:
true
,
platform
:
platform
,
platform
s
:
[]
string
{
platform
}
,
})
})
}
}
...
@@ -468,50 +469,35 @@ func (r *accountRepository) ListSchedulableByPlatforms(ctx context.Context, plat
...
@@ -468,50 +469,35 @@ func (r *accountRepository) ListSchedulableByPlatforms(ctx context.Context, plat
if
len
(
platforms
)
==
0
{
if
len
(
platforms
)
==
0
{
return
nil
,
nil
return
nil
,
nil
}
}
var
accounts
[]
accountModel
// 仅返回可调度的活跃账号,并过滤处于过载/限流窗口的账号。
// 代理与分组信息统一在 accountsToService 中批量加载,避免 N+1 查询。
now
:=
time
.
Now
()
now
:=
time
.
Now
()
err
:=
r
.
db
.
WithContext
(
ctx
)
.
accounts
,
err
:=
r
.
client
.
Account
.
Query
()
.
Where
(
"platform IN ?"
,
platforms
)
.
Where
(
Where
(
"status = ? AND schedulable = ?"
,
service
.
StatusActive
,
true
)
.
dbaccount
.
PlatformIn
(
platforms
...
),
Where
(
"(overload_until IS NULL OR overload_until <= ?)"
,
now
)
.
dbaccount
.
StatusEQ
(
service
.
StatusActive
),
Where
(
"(rate_limit_reset_at IS NULL OR rate_limit_reset_at <= ?)"
,
now
)
.
dbaccount
.
SchedulableEQ
(
true
),
Preload
(
"Proxy"
)
.
dbaccount
.
Or
(
dbaccount
.
OverloadUntilIsNil
(),
dbaccount
.
OverloadUntilLTE
(
now
)),
Order
(
"priority ASC"
)
.
dbaccount
.
Or
(
dbaccount
.
RateLimitResetAtIsNil
(),
dbaccount
.
RateLimitResetAtLTE
(
now
)),
Find
(
&
accounts
)
.
Error
)
.
Order
(
dbent
.
Asc
(
dbaccount
.
FieldPriority
))
.
All
(
ctx
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
outAccounts
:=
make
([]
service
.
Account
,
0
,
len
(
accounts
))
return
r
.
accountsToService
(
ctx
,
accounts
)
for
i
:=
range
accounts
{
outAccounts
=
append
(
outAccounts
,
*
accountModelToService
(
&
accounts
[
i
]))
}
return
outAccounts
,
nil
}
}
func
(
r
*
accountRepository
)
ListSchedulableByGroupIDAndPlatforms
(
ctx
context
.
Context
,
groupID
int64
,
platforms
[]
string
)
([]
service
.
Account
,
error
)
{
func
(
r
*
accountRepository
)
ListSchedulableByGroupIDAndPlatforms
(
ctx
context
.
Context
,
groupID
int64
,
platforms
[]
string
)
([]
service
.
Account
,
error
)
{
if
len
(
platforms
)
==
0
{
if
len
(
platforms
)
==
0
{
return
nil
,
nil
return
nil
,
nil
}
}
var
accounts
[]
accountModel
// 复用按分组查询逻辑,保证分组优先级 + 账号优先级的排序与筛选一致。
now
:=
time
.
Now
()
return
r
.
queryAccountsByGroup
(
ctx
,
groupID
,
accountGroupQueryOptions
{
err
:=
r
.
db
.
WithContext
(
ctx
)
.
status
:
service
.
StatusActive
,
Joins
(
"JOIN account_groups ON account_groups.account_id = accounts.id"
)
.
schedulable
:
true
,
Where
(
"account_groups.group_id = ?"
,
groupID
)
.
platforms
:
platforms
,
Where
(
"accounts.platform IN ?"
,
platforms
)
.
})
Where
(
"accounts.status = ? AND accounts.schedulable = ?"
,
service
.
StatusActive
,
true
)
.
Where
(
"(accounts.overload_until IS NULL OR accounts.overload_until <= ?)"
,
now
)
.
Where
(
"(accounts.rate_limit_reset_at IS NULL OR accounts.rate_limit_reset_at <= ?)"
,
now
)
.
Preload
(
"Proxy"
)
.
Order
(
"account_groups.priority ASC, accounts.priority ASC"
)
.
Find
(
&
accounts
)
.
Error
if
err
!=
nil
{
return
nil
,
err
}
outAccounts
:=
make
([]
service
.
Account
,
0
,
len
(
accounts
))
for
i
:=
range
accounts
{
outAccounts
=
append
(
outAccounts
,
*
accountModelToService
(
&
accounts
[
i
]))
}
return
outAccounts
,
nil
}
}
func
(
r
*
accountRepository
)
SetRateLimited
(
ctx
context
.
Context
,
id
int64
,
resetAt
time
.
Time
)
error
{
func
(
r
*
accountRepository
)
SetRateLimited
(
ctx
context
.
Context
,
id
int64
,
resetAt
time
.
Time
)
error
{
...
@@ -666,20 +652,21 @@ func (r *accountRepository) BulkUpdate(ctx context.Context, ids []int64, updates
...
@@ -666,20 +652,21 @@ func (r *accountRepository) BulkUpdate(ctx context.Context, ids []int64, updates
type
accountGroupQueryOptions
struct
{
type
accountGroupQueryOptions
struct
{
status
string
status
string
schedulable
bool
schedulable
bool
platform
string
platform
s
[]
string
// 允许的多个平台,空切片表示不进行平台过滤
}
}
func
(
r
*
accountRepository
)
queryAccountsByGroup
(
ctx
context
.
Context
,
groupID
int64
,
opts
accountGroupQueryOptions
)
([]
service
.
Account
,
error
)
{
func
(
r
*
accountRepository
)
queryAccountsByGroup
(
ctx
context
.
Context
,
groupID
int64
,
opts
accountGroupQueryOptions
)
([]
service
.
Account
,
error
)
{
q
:=
r
.
client
.
AccountGroup
.
Query
()
.
q
:=
r
.
client
.
AccountGroup
.
Query
()
.
Where
(
dbaccountgroup
.
GroupIDEQ
(
groupID
))
Where
(
dbaccountgroup
.
GroupIDEQ
(
groupID
))
// 通过 account_groups 中间表查询账号,并按需叠加状态/平台/调度能力过滤。
preds
:=
make
([]
dbpredicate
.
Account
,
0
,
6
)
preds
:=
make
([]
dbpredicate
.
Account
,
0
,
6
)
preds
=
append
(
preds
,
dbaccount
.
DeletedAtIsNil
())
preds
=
append
(
preds
,
dbaccount
.
DeletedAtIsNil
())
if
opts
.
status
!=
""
{
if
opts
.
status
!=
""
{
preds
=
append
(
preds
,
dbaccount
.
StatusEQ
(
opts
.
status
))
preds
=
append
(
preds
,
dbaccount
.
StatusEQ
(
opts
.
status
))
}
}
if
opts
.
platform
!=
""
{
if
len
(
opts
.
platform
s
)
>
0
{
preds
=
append
(
preds
,
dbaccount
.
Platform
EQ
(
opts
.
platform
))
preds
=
append
(
preds
,
dbaccount
.
Platform
In
(
opts
.
platform
s
...
))
}
}
if
opts
.
schedulable
{
if
opts
.
schedulable
{
now
:=
time
.
Now
()
now
:=
time
.
Now
()
...
...
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