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
68d7ec91
Unverified
Commit
68d7ec91
authored
Mar 24, 2026
by
Wesley Liddick
Committed by
GitHub
Mar 24, 2026
Browse files
Merge pull request #1220 from weak-fox/feat/account-privacy-mode-filter
feat: 管理员账号列表支持按 Privacy 状态筛选
parents
7537dce0
4838ab74
Changes
23
Show whitespace changes
Inline
Side-by-side
backend/internal/handler/admin/account_data.go
View file @
68d7ec91
...
@@ -352,7 +352,7 @@ func (h *AccountHandler) listAccountsFiltered(ctx context.Context, platform, acc
...
@@ -352,7 +352,7 @@ func (h *AccountHandler) listAccountsFiltered(ctx context.Context, platform, acc
pageSize
:=
dataPageCap
pageSize
:=
dataPageCap
var
out
[]
service
.
Account
var
out
[]
service
.
Account
for
{
for
{
items
,
total
,
err
:=
h
.
adminService
.
ListAccounts
(
ctx
,
page
,
pageSize
,
platform
,
accountType
,
status
,
search
,
0
)
items
,
total
,
err
:=
h
.
adminService
.
ListAccounts
(
ctx
,
page
,
pageSize
,
platform
,
accountType
,
status
,
search
,
0
,
""
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
backend/internal/handler/admin/account_handler.go
View file @
68d7ec91
...
@@ -219,6 +219,7 @@ func (h *AccountHandler) List(c *gin.Context) {
...
@@ -219,6 +219,7 @@ func (h *AccountHandler) List(c *gin.Context) {
accountType
:=
c
.
Query
(
"type"
)
accountType
:=
c
.
Query
(
"type"
)
status
:=
c
.
Query
(
"status"
)
status
:=
c
.
Query
(
"status"
)
search
:=
c
.
Query
(
"search"
)
search
:=
c
.
Query
(
"search"
)
privacyMode
:=
strings
.
TrimSpace
(
c
.
Query
(
"privacy_mode"
))
// 标准化和验证 search 参数
// 标准化和验证 search 参数
search
=
strings
.
TrimSpace
(
search
)
search
=
strings
.
TrimSpace
(
search
)
if
len
(
search
)
>
100
{
if
len
(
search
)
>
100
{
...
@@ -244,7 +245,7 @@ func (h *AccountHandler) List(c *gin.Context) {
...
@@ -244,7 +245,7 @@ func (h *AccountHandler) List(c *gin.Context) {
}
}
}
}
accounts
,
total
,
err
:=
h
.
adminService
.
ListAccounts
(
c
.
Request
.
Context
(),
page
,
pageSize
,
platform
,
accountType
,
status
,
search
,
groupID
)
accounts
,
total
,
err
:=
h
.
adminService
.
ListAccounts
(
c
.
Request
.
Context
(),
page
,
pageSize
,
platform
,
accountType
,
status
,
search
,
groupID
,
privacyMode
)
if
err
!=
nil
{
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
response
.
ErrorFrom
(
c
,
err
)
return
return
...
@@ -1936,7 +1937,7 @@ func (h *AccountHandler) BatchRefreshTier(c *gin.Context) {
...
@@ -1936,7 +1937,7 @@ func (h *AccountHandler) BatchRefreshTier(c *gin.Context) {
accounts
:=
make
([]
*
service
.
Account
,
0
)
accounts
:=
make
([]
*
service
.
Account
,
0
)
if
len
(
req
.
AccountIDs
)
==
0
{
if
len
(
req
.
AccountIDs
)
==
0
{
allAccounts
,
_
,
err
:=
h
.
adminService
.
ListAccounts
(
ctx
,
1
,
10000
,
"gemini"
,
"oauth"
,
""
,
""
,
0
)
allAccounts
,
_
,
err
:=
h
.
adminService
.
ListAccounts
(
ctx
,
1
,
10000
,
"gemini"
,
"oauth"
,
""
,
""
,
0
,
""
)
if
err
!=
nil
{
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
response
.
ErrorFrom
(
c
,
err
)
return
return
...
...
backend/internal/handler/admin/admin_service_stub_test.go
View file @
68d7ec91
...
@@ -187,7 +187,7 @@ func (s *stubAdminService) BatchSetGroupRateMultipliers(_ context.Context, _ int
...
@@ -187,7 +187,7 @@ func (s *stubAdminService) BatchSetGroupRateMultipliers(_ context.Context, _ int
return
nil
return
nil
}
}
func
(
s
*
stubAdminService
)
ListAccounts
(
ctx
context
.
Context
,
page
,
pageSize
int
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
)
([]
service
.
Account
,
int64
,
error
)
{
func
(
s
*
stubAdminService
)
ListAccounts
(
ctx
context
.
Context
,
page
,
pageSize
int
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
,
privacyMode
string
)
([]
service
.
Account
,
int64
,
error
)
{
return
s
.
accounts
,
int64
(
len
(
s
.
accounts
)),
nil
return
s
.
accounts
,
int64
(
len
(
s
.
accounts
)),
nil
}
}
...
...
backend/internal/handler/sora_client_handler_test.go
View file @
68d7ec91
...
@@ -2072,7 +2072,7 @@ func (r *stubAccountRepoForHandler) Delete(context.Context, int64) error
...
@@ -2072,7 +2072,7 @@ func (r *stubAccountRepoForHandler) Delete(context.Context, int64) error
func
(
r
*
stubAccountRepoForHandler
)
List
(
context
.
Context
,
pagination
.
PaginationParams
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
r
*
stubAccountRepoForHandler
)
List
(
context
.
Context
,
pagination
.
PaginationParams
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
return
nil
,
nil
,
nil
return
nil
,
nil
,
nil
}
}
func
(
r
*
stubAccountRepoForHandler
)
ListWithFilters
(
context
.
Context
,
pagination
.
PaginationParams
,
string
,
string
,
string
,
string
,
int64
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
r
*
stubAccountRepoForHandler
)
ListWithFilters
(
context
.
Context
,
pagination
.
PaginationParams
,
string
,
string
,
string
,
string
,
int64
,
string
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
return
nil
,
nil
,
nil
return
nil
,
nil
,
nil
}
}
func
(
r
*
stubAccountRepoForHandler
)
ListByGroup
(
context
.
Context
,
int64
)
([]
service
.
Account
,
error
)
{
func
(
r
*
stubAccountRepoForHandler
)
ListByGroup
(
context
.
Context
,
int64
)
([]
service
.
Account
,
error
)
{
...
...
backend/internal/handler/sora_gateway_handler_test.go
View file @
68d7ec91
...
@@ -130,7 +130,7 @@ func (r *stubAccountRepo) Delete(ctx context.Context, id int64) error
...
@@ -130,7 +130,7 @@ func (r *stubAccountRepo) Delete(ctx context.Context, id int64) error
func
(
r
*
stubAccountRepo
)
List
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
r
*
stubAccountRepo
)
List
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
return
nil
,
nil
,
nil
return
nil
,
nil
,
nil
}
}
func
(
r
*
stubAccountRepo
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
r
*
stubAccountRepo
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
,
privacyMode
string
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
return
nil
,
nil
,
nil
return
nil
,
nil
,
nil
}
}
func
(
r
*
stubAccountRepo
)
ListByGroup
(
ctx
context
.
Context
,
groupID
int64
)
([]
service
.
Account
,
error
)
{
func
(
r
*
stubAccountRepo
)
ListByGroup
(
ctx
context
.
Context
,
groupID
int64
)
([]
service
.
Account
,
error
)
{
...
...
backend/internal/repository/account_repo.go
View file @
68d7ec91
...
@@ -443,10 +443,10 @@ func (r *accountRepository) Delete(ctx context.Context, id int64) error {
...
@@ -443,10 +443,10 @@ func (r *accountRepository) Delete(ctx context.Context, id int64) error {
}
}
func
(
r
*
accountRepository
)
List
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
r
*
accountRepository
)
List
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
return
r
.
ListWithFilters
(
ctx
,
params
,
""
,
""
,
""
,
""
,
0
)
return
r
.
ListWithFilters
(
ctx
,
params
,
""
,
""
,
""
,
""
,
0
,
""
)
}
}
func
(
r
*
accountRepository
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
r
*
accountRepository
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
,
privacyMode
string
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
q
:=
r
.
client
.
Account
.
Query
()
q
:=
r
.
client
.
Account
.
Query
()
if
platform
!=
""
{
if
platform
!=
""
{
...
@@ -479,6 +479,20 @@ func (r *accountRepository) ListWithFilters(ctx context.Context, params paginati
...
@@ -479,6 +479,20 @@ func (r *accountRepository) ListWithFilters(ctx context.Context, params paginati
}
else
if
groupID
>
0
{
}
else
if
groupID
>
0
{
q
=
q
.
Where
(
dbaccount
.
HasAccountGroupsWith
(
dbaccountgroup
.
GroupIDEQ
(
groupID
)))
q
=
q
.
Where
(
dbaccount
.
HasAccountGroupsWith
(
dbaccountgroup
.
GroupIDEQ
(
groupID
)))
}
}
if
privacyMode
!=
""
{
q
=
q
.
Where
(
dbpredicate
.
Account
(
func
(
s
*
entsql
.
Selector
)
{
path
:=
sqljson
.
Path
(
"privacy_mode"
)
switch
privacyMode
{
case
service
.
AccountPrivacyModeUnsetFilter
:
s
.
Where
(
entsql
.
Or
(
entsql
.
Not
(
sqljson
.
HasKey
(
dbaccount
.
FieldExtra
,
path
)),
sqljson
.
ValueEQ
(
dbaccount
.
FieldExtra
,
""
,
path
),
))
default
:
s
.
Where
(
sqljson
.
ValueEQ
(
dbaccount
.
FieldExtra
,
privacyMode
,
path
))
}
}))
}
total
,
err
:=
q
.
Count
(
ctx
)
total
,
err
:=
q
.
Count
(
ctx
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
backend/internal/repository/account_repo_integration_test.go
View file @
68d7ec91
...
@@ -215,6 +215,7 @@ func (s *AccountRepoSuite) TestListWithFilters() {
...
@@ -215,6 +215,7 @@ func (s *AccountRepoSuite) TestListWithFilters() {
status
string
status
string
search
string
search
string
groupID
int64
groupID
int64
privacyMode
string
wantCount
int
wantCount
int
validate
func
(
accounts
[]
service
.
Account
)
validate
func
(
accounts
[]
service
.
Account
)
}{
}{
...
@@ -281,6 +282,32 @@ func (s *AccountRepoSuite) TestListWithFilters() {
...
@@ -281,6 +282,32 @@ func (s *AccountRepoSuite) TestListWithFilters() {
s
.
Require
()
.
Empty
(
accounts
[
0
]
.
GroupIDs
)
s
.
Require
()
.
Empty
(
accounts
[
0
]
.
GroupIDs
)
},
},
},
},
{
name
:
"filter_by_privacy_mode"
,
setup
:
func
(
client
*
dbent
.
Client
)
{
mustCreateAccount
(
s
.
T
(),
client
,
&
service
.
Account
{
Name
:
"privacy-ok"
,
Extra
:
map
[
string
]
any
{
"privacy_mode"
:
service
.
PrivacyModeTrainingOff
}})
mustCreateAccount
(
s
.
T
(),
client
,
&
service
.
Account
{
Name
:
"privacy-fail"
,
Extra
:
map
[
string
]
any
{
"privacy_mode"
:
service
.
PrivacyModeFailed
}})
},
privacyMode
:
service
.
PrivacyModeTrainingOff
,
wantCount
:
1
,
validate
:
func
(
accounts
[]
service
.
Account
)
{
s
.
Require
()
.
Equal
(
"privacy-ok"
,
accounts
[
0
]
.
Name
)
},
},
{
name
:
"filter_by_privacy_mode_unset"
,
setup
:
func
(
client
*
dbent
.
Client
)
{
mustCreateAccount
(
s
.
T
(),
client
,
&
service
.
Account
{
Name
:
"privacy-unset"
,
Extra
:
nil
})
mustCreateAccount
(
s
.
T
(),
client
,
&
service
.
Account
{
Name
:
"privacy-empty"
,
Extra
:
map
[
string
]
any
{
"privacy_mode"
:
""
}})
mustCreateAccount
(
s
.
T
(),
client
,
&
service
.
Account
{
Name
:
"privacy-set"
,
Extra
:
map
[
string
]
any
{
"privacy_mode"
:
service
.
PrivacyModeTrainingOff
}})
},
privacyMode
:
service
.
AccountPrivacyModeUnsetFilter
,
wantCount
:
2
,
validate
:
func
(
accounts
[]
service
.
Account
)
{
names
:=
[]
string
{
accounts
[
0
]
.
Name
,
accounts
[
1
]
.
Name
}
s
.
ElementsMatch
([]
string
{
"privacy-unset"
,
"privacy-empty"
},
names
)
},
},
}
}
for
_
,
tt
:=
range
tests
{
for
_
,
tt
:=
range
tests
{
...
@@ -293,7 +320,7 @@ func (s *AccountRepoSuite) TestListWithFilters() {
...
@@ -293,7 +320,7 @@ func (s *AccountRepoSuite) TestListWithFilters() {
tt
.
setup
(
client
)
tt
.
setup
(
client
)
accounts
,
_
,
err
:=
repo
.
ListWithFilters
(
ctx
,
pagination
.
PaginationParams
{
Page
:
1
,
PageSize
:
10
},
tt
.
platform
,
tt
.
accType
,
tt
.
status
,
tt
.
search
,
tt
.
groupID
)
accounts
,
_
,
err
:=
repo
.
ListWithFilters
(
ctx
,
pagination
.
PaginationParams
{
Page
:
1
,
PageSize
:
10
},
tt
.
platform
,
tt
.
accType
,
tt
.
status
,
tt
.
search
,
tt
.
groupID
,
tt
.
privacyMode
)
s
.
Require
()
.
NoError
(
err
)
s
.
Require
()
.
NoError
(
err
)
s
.
Require
()
.
Len
(
accounts
,
tt
.
wantCount
)
s
.
Require
()
.
Len
(
accounts
,
tt
.
wantCount
)
if
tt
.
validate
!=
nil
{
if
tt
.
validate
!=
nil
{
...
@@ -360,7 +387,7 @@ func (s *AccountRepoSuite) TestPreload_And_VirtualFields() {
...
@@ -360,7 +387,7 @@ func (s *AccountRepoSuite) TestPreload_And_VirtualFields() {
s
.
Require
()
.
Len
(
got
.
Groups
,
1
,
"expected Groups to be populated"
)
s
.
Require
()
.
Len
(
got
.
Groups
,
1
,
"expected Groups to be populated"
)
s
.
Require
()
.
Equal
(
group
.
ID
,
got
.
Groups
[
0
]
.
ID
)
s
.
Require
()
.
Equal
(
group
.
ID
,
got
.
Groups
[
0
]
.
ID
)
accounts
,
page
,
err
:=
s
.
repo
.
ListWithFilters
(
s
.
ctx
,
pagination
.
PaginationParams
{
Page
:
1
,
PageSize
:
10
},
""
,
""
,
""
,
"acc"
,
0
)
accounts
,
page
,
err
:=
s
.
repo
.
ListWithFilters
(
s
.
ctx
,
pagination
.
PaginationParams
{
Page
:
1
,
PageSize
:
10
},
""
,
""
,
""
,
"acc"
,
0
,
""
)
s
.
Require
()
.
NoError
(
err
,
"ListWithFilters"
)
s
.
Require
()
.
NoError
(
err
,
"ListWithFilters"
)
s
.
Require
()
.
Equal
(
int64
(
1
),
page
.
Total
)
s
.
Require
()
.
Equal
(
int64
(
1
),
page
.
Total
)
s
.
Require
()
.
Len
(
accounts
,
1
)
s
.
Require
()
.
Len
(
accounts
,
1
)
...
...
backend/internal/server/api_contract_test.go
View file @
68d7ec91
...
@@ -990,7 +990,7 @@ func (s *stubAccountRepo) List(ctx context.Context, params pagination.Pagination
...
@@ -990,7 +990,7 @@ func (s *stubAccountRepo) List(ctx context.Context, params pagination.Pagination
return
nil
,
nil
,
errors
.
New
(
"not implemented"
)
return
nil
,
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
s
*
stubAccountRepo
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
s
*
stubAccountRepo
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
,
privacyMode
string
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
return
nil
,
nil
,
errors
.
New
(
"not implemented"
)
return
nil
,
nil
,
errors
.
New
(
"not implemented"
)
}
}
...
...
backend/internal/service/account_service.go
View file @
68d7ec91
...
@@ -15,6 +15,7 @@ var (
...
@@ -15,6 +15,7 @@ var (
)
)
const
AccountListGroupUngrouped
int64
=
-
1
const
AccountListGroupUngrouped
int64
=
-
1
const
AccountPrivacyModeUnsetFilter
=
"__unset__"
type
AccountRepository
interface
{
type
AccountRepository
interface
{
Create
(
ctx
context
.
Context
,
account
*
Account
)
error
Create
(
ctx
context
.
Context
,
account
*
Account
)
error
...
@@ -37,7 +38,7 @@ type AccountRepository interface {
...
@@ -37,7 +38,7 @@ type AccountRepository interface {
Delete
(
ctx
context
.
Context
,
id
int64
)
error
Delete
(
ctx
context
.
Context
,
id
int64
)
error
List
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
List
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
,
privacyMode
string
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
ListByGroup
(
ctx
context
.
Context
,
groupID
int64
)
([]
Account
,
error
)
ListByGroup
(
ctx
context
.
Context
,
groupID
int64
)
([]
Account
,
error
)
ListActive
(
ctx
context
.
Context
)
([]
Account
,
error
)
ListActive
(
ctx
context
.
Context
)
([]
Account
,
error
)
ListByPlatform
(
ctx
context
.
Context
,
platform
string
)
([]
Account
,
error
)
ListByPlatform
(
ctx
context
.
Context
,
platform
string
)
([]
Account
,
error
)
...
...
backend/internal/service/account_service_delete_test.go
View file @
68d7ec91
...
@@ -79,7 +79,7 @@ func (s *accountRepoStub) List(ctx context.Context, params pagination.Pagination
...
@@ -79,7 +79,7 @@ func (s *accountRepoStub) List(ctx context.Context, params pagination.Pagination
panic
(
"unexpected List call"
)
panic
(
"unexpected List call"
)
}
}
func
(
s
*
accountRepoStub
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
s
*
accountRepoStub
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
,
privacyMode
string
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
panic
(
"unexpected ListWithFilters call"
)
panic
(
"unexpected ListWithFilters call"
)
}
}
...
...
backend/internal/service/admin_service.go
View file @
68d7ec91
...
@@ -54,7 +54,7 @@ type AdminService interface {
...
@@ -54,7 +54,7 @@ type AdminService interface {
ReplaceUserGroup
(
ctx
context
.
Context
,
userID
,
oldGroupID
,
newGroupID
int64
)
(
*
ReplaceUserGroupResult
,
error
)
ReplaceUserGroup
(
ctx
context
.
Context
,
userID
,
oldGroupID
,
newGroupID
int64
)
(
*
ReplaceUserGroupResult
,
error
)
// Account management
// Account management
ListAccounts
(
ctx
context
.
Context
,
page
,
pageSize
int
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
)
([]
Account
,
int64
,
error
)
ListAccounts
(
ctx
context
.
Context
,
page
,
pageSize
int
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
,
privacyMode
string
)
([]
Account
,
int64
,
error
)
GetAccount
(
ctx
context
.
Context
,
id
int64
)
(
*
Account
,
error
)
GetAccount
(
ctx
context
.
Context
,
id
int64
)
(
*
Account
,
error
)
GetAccountsByIDs
(
ctx
context
.
Context
,
ids
[]
int64
)
([]
*
Account
,
error
)
GetAccountsByIDs
(
ctx
context
.
Context
,
ids
[]
int64
)
([]
*
Account
,
error
)
CreateAccount
(
ctx
context
.
Context
,
input
*
CreateAccountInput
)
(
*
Account
,
error
)
CreateAccount
(
ctx
context
.
Context
,
input
*
CreateAccountInput
)
(
*
Account
,
error
)
...
@@ -1451,9 +1451,9 @@ func (s *adminServiceImpl) ReplaceUserGroup(ctx context.Context, userID, oldGrou
...
@@ -1451,9 +1451,9 @@ func (s *adminServiceImpl) ReplaceUserGroup(ctx context.Context, userID, oldGrou
}
}
// Account management implementations
// Account management implementations
func
(
s
*
adminServiceImpl
)
ListAccounts
(
ctx
context
.
Context
,
page
,
pageSize
int
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
)
([]
Account
,
int64
,
error
)
{
func
(
s
*
adminServiceImpl
)
ListAccounts
(
ctx
context
.
Context
,
page
,
pageSize
int
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
,
privacyMode
string
)
([]
Account
,
int64
,
error
)
{
params
:=
pagination
.
PaginationParams
{
Page
:
page
,
PageSize
:
pageSize
}
params
:=
pagination
.
PaginationParams
{
Page
:
page
,
PageSize
:
pageSize
}
accounts
,
result
,
err
:=
s
.
accountRepo
.
ListWithFilters
(
ctx
,
params
,
platform
,
accountType
,
status
,
search
,
groupID
)
accounts
,
result
,
err
:=
s
.
accountRepo
.
ListWithFilters
(
ctx
,
params
,
platform
,
accountType
,
status
,
search
,
groupID
,
privacyMode
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
0
,
err
return
nil
,
0
,
err
}
}
...
...
backend/internal/service/admin_service_search_test.go
View file @
68d7ec91
...
@@ -19,18 +19,20 @@ type accountRepoStubForAdminList struct {
...
@@ -19,18 +19,20 @@ type accountRepoStubForAdminList struct {
listWithFiltersType
string
listWithFiltersType
string
listWithFiltersStatus
string
listWithFiltersStatus
string
listWithFiltersSearch
string
listWithFiltersSearch
string
listWithFiltersPrivacy
string
listWithFiltersAccounts
[]
Account
listWithFiltersAccounts
[]
Account
listWithFiltersResult
*
pagination
.
PaginationResult
listWithFiltersResult
*
pagination
.
PaginationResult
listWithFiltersErr
error
listWithFiltersErr
error
}
}
func
(
s
*
accountRepoStubForAdminList
)
ListWithFilters
(
_
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
s
*
accountRepoStubForAdminList
)
ListWithFilters
(
_
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
,
privacyMode
string
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
s
.
listWithFiltersCalls
++
s
.
listWithFiltersCalls
++
s
.
listWithFiltersParams
=
params
s
.
listWithFiltersParams
=
params
s
.
listWithFiltersPlatform
=
platform
s
.
listWithFiltersPlatform
=
platform
s
.
listWithFiltersType
=
accountType
s
.
listWithFiltersType
=
accountType
s
.
listWithFiltersStatus
=
status
s
.
listWithFiltersStatus
=
status
s
.
listWithFiltersSearch
=
search
s
.
listWithFiltersSearch
=
search
s
.
listWithFiltersPrivacy
=
privacyMode
if
s
.
listWithFiltersErr
!=
nil
{
if
s
.
listWithFiltersErr
!=
nil
{
return
nil
,
nil
,
s
.
listWithFiltersErr
return
nil
,
nil
,
s
.
listWithFiltersErr
...
@@ -168,7 +170,7 @@ func TestAdminService_ListAccounts_WithSearch(t *testing.T) {
...
@@ -168,7 +170,7 @@ func TestAdminService_ListAccounts_WithSearch(t *testing.T) {
}
}
svc
:=
&
adminServiceImpl
{
accountRepo
:
repo
}
svc
:=
&
adminServiceImpl
{
accountRepo
:
repo
}
accounts
,
total
,
err
:=
svc
.
ListAccounts
(
context
.
Background
(),
1
,
20
,
PlatformGemini
,
AccountTypeOAuth
,
StatusActive
,
"acc"
,
0
)
accounts
,
total
,
err
:=
svc
.
ListAccounts
(
context
.
Background
(),
1
,
20
,
PlatformGemini
,
AccountTypeOAuth
,
StatusActive
,
"acc"
,
0
,
""
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
int64
(
10
),
total
)
require
.
Equal
(
t
,
int64
(
10
),
total
)
require
.
Equal
(
t
,
[]
Account
{{
ID
:
1
,
Name
:
"acc"
}},
accounts
)
require
.
Equal
(
t
,
[]
Account
{{
ID
:
1
,
Name
:
"acc"
}},
accounts
)
...
@@ -182,6 +184,22 @@ func TestAdminService_ListAccounts_WithSearch(t *testing.T) {
...
@@ -182,6 +184,22 @@ func TestAdminService_ListAccounts_WithSearch(t *testing.T) {
})
})
}
}
func
TestAdminService_ListAccounts_WithPrivacyMode
(
t
*
testing
.
T
)
{
t
.
Run
(
"privacy_mode 参数正常传递到 repository 层"
,
func
(
t
*
testing
.
T
)
{
repo
:=
&
accountRepoStubForAdminList
{
listWithFiltersAccounts
:
[]
Account
{{
ID
:
2
,
Name
:
"acc2"
}},
listWithFiltersResult
:
&
pagination
.
PaginationResult
{
Total
:
1
},
}
svc
:=
&
adminServiceImpl
{
accountRepo
:
repo
}
accounts
,
total
,
err
:=
svc
.
ListAccounts
(
context
.
Background
(),
1
,
20
,
PlatformOpenAI
,
AccountTypeOAuth
,
StatusActive
,
"acc2"
,
0
,
PrivacyModeCFBlocked
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
int64
(
1
),
total
)
require
.
Equal
(
t
,
[]
Account
{{
ID
:
2
,
Name
:
"acc2"
}},
accounts
)
require
.
Equal
(
t
,
PrivacyModeCFBlocked
,
repo
.
listWithFiltersPrivacy
)
})
}
func
TestAdminService_ListProxies_WithSearch
(
t
*
testing
.
T
)
{
func
TestAdminService_ListProxies_WithSearch
(
t
*
testing
.
T
)
{
t
.
Run
(
"search 参数正常传递到 repository 层"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"search 参数正常传递到 repository 层"
,
func
(
t
*
testing
.
T
)
{
repo
:=
&
proxyRepoStubForAdminList
{
repo
:=
&
proxyRepoStubForAdminList
{
...
...
backend/internal/service/gateway_multiplatform_test.go
View file @
68d7ec91
...
@@ -92,7 +92,7 @@ func (m *mockAccountRepoForPlatform) Delete(ctx context.Context, id int64) error
...
@@ -92,7 +92,7 @@ func (m *mockAccountRepoForPlatform) Delete(ctx context.Context, id int64) error
func
(
m
*
mockAccountRepoForPlatform
)
List
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
m
*
mockAccountRepoForPlatform
)
List
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
return
nil
,
nil
,
nil
return
nil
,
nil
,
nil
}
}
func
(
m
*
mockAccountRepoForPlatform
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
m
*
mockAccountRepoForPlatform
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
,
privacyMode
string
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
return
nil
,
nil
,
nil
return
nil
,
nil
,
nil
}
}
func
(
m
*
mockAccountRepoForPlatform
)
ListByGroup
(
ctx
context
.
Context
,
groupID
int64
)
([]
Account
,
error
)
{
func
(
m
*
mockAccountRepoForPlatform
)
ListByGroup
(
ctx
context
.
Context
,
groupID
int64
)
([]
Account
,
error
)
{
...
...
backend/internal/service/gemini_multiplatform_test.go
View file @
68d7ec91
...
@@ -79,7 +79,7 @@ func (m *mockAccountRepoForGemini) Delete(ctx context.Context, id int64) error
...
@@ -79,7 +79,7 @@ func (m *mockAccountRepoForGemini) Delete(ctx context.Context, id int64) error
func
(
m
*
mockAccountRepoForGemini
)
List
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
m
*
mockAccountRepoForGemini
)
List
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
return
nil
,
nil
,
nil
return
nil
,
nil
,
nil
}
}
func
(
m
*
mockAccountRepoForGemini
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
m
*
mockAccountRepoForGemini
)
ListWithFilters
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
,
privacyMode
string
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
return
nil
,
nil
,
nil
return
nil
,
nil
,
nil
}
}
func
(
m
*
mockAccountRepoForGemini
)
ListByGroup
(
ctx
context
.
Context
,
groupID
int64
)
([]
Account
,
error
)
{
func
(
m
*
mockAccountRepoForGemini
)
ListByGroup
(
ctx
context
.
Context
,
groupID
int64
)
([]
Account
,
error
)
{
...
...
backend/internal/service/openai_ws_ratelimit_signal_test.go
View file @
68d7ec91
...
@@ -73,12 +73,13 @@ func (r *openAICodexExtraListRepo) SetRateLimited(_ context.Context, _ int64, re
...
@@ -73,12 +73,13 @@ func (r *openAICodexExtraListRepo) SetRateLimited(_ context.Context, _ int64, re
return
nil
return
nil
}
}
func
(
r
*
openAICodexExtraListRepo
)
ListWithFilters
(
_
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
r
*
openAICodexExtraListRepo
)
ListWithFilters
(
_
context
.
Context
,
params
pagination
.
PaginationParams
,
platform
,
accountType
,
status
,
search
string
,
groupID
int64
,
privacyMode
string
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
_
=
platform
_
=
platform
_
=
accountType
_
=
accountType
_
=
status
_
=
status
_
=
search
_
=
search
_
=
groupID
_
=
groupID
_
=
privacyMode
return
r
.
accounts
,
&
pagination
.
PaginationResult
{
Total
:
int64
(
len
(
r
.
accounts
)),
Page
:
params
.
Page
,
PageSize
:
params
.
PageSize
},
nil
return
r
.
accounts
,
&
pagination
.
PaginationResult
{
Total
:
int64
(
len
(
r
.
accounts
)),
Page
:
params
.
Page
,
PageSize
:
params
.
PageSize
},
nil
}
}
...
@@ -491,7 +492,7 @@ func TestAdminService_ListAccounts_ExhaustedCodexExtraReturnsRateLimitedAccount(
...
@@ -491,7 +492,7 @@ func TestAdminService_ListAccounts_ExhaustedCodexExtraReturnsRateLimitedAccount(
}
}
svc
:=
&
adminServiceImpl
{
accountRepo
:
repo
}
svc
:=
&
adminServiceImpl
{
accountRepo
:
repo
}
accounts
,
total
,
err
:=
svc
.
ListAccounts
(
context
.
Background
(),
1
,
20
,
PlatformOpenAI
,
AccountTypeOAuth
,
""
,
""
,
0
)
accounts
,
total
,
err
:=
svc
.
ListAccounts
(
context
.
Background
(),
1
,
20
,
PlatformOpenAI
,
AccountTypeOAuth
,
""
,
""
,
0
,
""
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
int64
(
1
),
total
)
require
.
Equal
(
t
,
int64
(
1
),
total
)
require
.
Len
(
t
,
accounts
,
1
)
require
.
Len
(
t
,
accounts
,
1
)
...
...
backend/internal/service/ops_concurrency.go
View file @
68d7ec91
...
@@ -24,7 +24,7 @@ func (s *OpsService) listAllAccountsForOps(ctx context.Context, platformFilter s
...
@@ -24,7 +24,7 @@ func (s *OpsService) listAllAccountsForOps(ctx context.Context, platformFilter s
accounts
,
pageInfo
,
err
:=
s
.
accountRepo
.
ListWithFilters
(
ctx
,
pagination
.
PaginationParams
{
accounts
,
pageInfo
,
err
:=
s
.
accountRepo
.
ListWithFilters
(
ctx
,
pagination
.
PaginationParams
{
Page
:
page
,
Page
:
page
,
PageSize
:
opsAccountsPageSize
,
PageSize
:
opsAccountsPageSize
,
},
platformFilter
,
""
,
""
,
""
,
0
)
},
platformFilter
,
""
,
""
,
""
,
0
,
""
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
backend/internal/service/ratelimit_session_window_test.go
View file @
68d7ec91
...
@@ -81,7 +81,7 @@ func (m *sessionWindowMockRepo) Delete(context.Context, int64) error { panic(
...
@@ -81,7 +81,7 @@ func (m *sessionWindowMockRepo) Delete(context.Context, int64) error { panic(
func
(
m
*
sessionWindowMockRepo
)
List
(
context
.
Context
,
pagination
.
PaginationParams
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
m
*
sessionWindowMockRepo
)
List
(
context
.
Context
,
pagination
.
PaginationParams
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
panic
(
"unexpected"
)
panic
(
"unexpected"
)
}
}
func
(
m
*
sessionWindowMockRepo
)
ListWithFilters
(
context
.
Context
,
pagination
.
PaginationParams
,
string
,
string
,
string
,
string
,
int64
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
m
*
sessionWindowMockRepo
)
ListWithFilters
(
context
.
Context
,
pagination
.
PaginationParams
,
string
,
string
,
string
,
string
,
int64
,
string
)
([]
Account
,
*
pagination
.
PaginationResult
,
error
)
{
panic
(
"unexpected"
)
panic
(
"unexpected"
)
}
}
func
(
m
*
sessionWindowMockRepo
)
ListByGroup
(
context
.
Context
,
int64
)
([]
Account
,
error
)
{
func
(
m
*
sessionWindowMockRepo
)
ListByGroup
(
context
.
Context
,
int64
)
([]
Account
,
error
)
{
...
...
frontend/src/api/admin/accounts.ts
View file @
68d7ec91
...
@@ -36,6 +36,7 @@ export async function list(
...
@@ -36,6 +36,7 @@ export async function list(
status
?:
string
status
?:
string
group
?:
string
group
?:
string
search
?:
string
search
?:
string
privacy_mode
?:
string
lite
?:
string
lite
?:
string
},
},
options
?:
{
options
?:
{
...
@@ -68,6 +69,7 @@ export async function listWithEtag(
...
@@ -68,6 +69,7 @@ export async function listWithEtag(
status
?:
string
status
?:
string
group
?:
string
group
?:
string
search
?:
string
search
?:
string
privacy_mode
?:
string
lite
?:
string
lite
?:
string
},
},
options
?:
{
options
?:
{
...
...
frontend/src/components/admin/account/AccountTableFilters.vue
View file @
68d7ec91
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
<Select
:model-value=
"filters.platform"
class=
"w-40"
:options=
"pOpts"
@
update:model-value=
"updatePlatform"
@
change=
"$emit('change')"
/>
<Select
:model-value=
"filters.platform"
class=
"w-40"
:options=
"pOpts"
@
update:model-value=
"updatePlatform"
@
change=
"$emit('change')"
/>
<Select
:model-value=
"filters.type"
class=
"w-40"
:options=
"tOpts"
@
update:model-value=
"updateType"
@
change=
"$emit('change')"
/>
<Select
:model-value=
"filters.type"
class=
"w-40"
:options=
"tOpts"
@
update:model-value=
"updateType"
@
change=
"$emit('change')"
/>
<Select
:model-value=
"filters.status"
class=
"w-40"
:options=
"sOpts"
@
update:model-value=
"updateStatus"
@
change=
"$emit('change')"
/>
<Select
:model-value=
"filters.status"
class=
"w-40"
:options=
"sOpts"
@
update:model-value=
"updateStatus"
@
change=
"$emit('change')"
/>
<Select
:model-value=
"filters.privacy_mode"
class=
"w-40"
:options=
"privacyOpts"
@
update:model-value=
"updatePrivacyMode"
@
change=
"$emit('change')"
/>
<Select
:model-value=
"filters.group"
class=
"w-40"
:options=
"gOpts"
@
update:model-value=
"updateGroup"
@
change=
"$emit('change')"
/>
<Select
:model-value=
"filters.group"
class=
"w-40"
:options=
"gOpts"
@
update:model-value=
"updateGroup"
@
change=
"$emit('change')"
/>
</div>
</div>
</
template
>
</
template
>
...
@@ -22,10 +23,18 @@ const emit = defineEmits(['update:searchQuery', 'update:filters', 'change']); co
...
@@ -22,10 +23,18 @@ const emit = defineEmits(['update:searchQuery', 'update:filters', 'change']); co
const
updatePlatform
=
(
value
:
string
|
number
|
boolean
|
null
)
=>
{
emit
(
'
update:filters
'
,
{
...
props
.
filters
,
platform
:
value
})
}
const
updatePlatform
=
(
value
:
string
|
number
|
boolean
|
null
)
=>
{
emit
(
'
update:filters
'
,
{
...
props
.
filters
,
platform
:
value
})
}
const
updateType
=
(
value
:
string
|
number
|
boolean
|
null
)
=>
{
emit
(
'
update:filters
'
,
{
...
props
.
filters
,
type
:
value
})
}
const
updateType
=
(
value
:
string
|
number
|
boolean
|
null
)
=>
{
emit
(
'
update:filters
'
,
{
...
props
.
filters
,
type
:
value
})
}
const
updateStatus
=
(
value
:
string
|
number
|
boolean
|
null
)
=>
{
emit
(
'
update:filters
'
,
{
...
props
.
filters
,
status
:
value
})
}
const
updateStatus
=
(
value
:
string
|
number
|
boolean
|
null
)
=>
{
emit
(
'
update:filters
'
,
{
...
props
.
filters
,
status
:
value
})
}
const
updatePrivacyMode
=
(
value
:
string
|
number
|
boolean
|
null
)
=>
{
emit
(
'
update:filters
'
,
{
...
props
.
filters
,
privacy_mode
:
value
})
}
const
updateGroup
=
(
value
:
string
|
number
|
boolean
|
null
)
=>
{
emit
(
'
update:filters
'
,
{
...
props
.
filters
,
group
:
value
})
}
const
updateGroup
=
(
value
:
string
|
number
|
boolean
|
null
)
=>
{
emit
(
'
update:filters
'
,
{
...
props
.
filters
,
group
:
value
})
}
const
pOpts
=
computed
(()
=>
[{
value
:
''
,
label
:
t
(
'
admin.accounts.allPlatforms
'
)
},
{
value
:
'
anthropic
'
,
label
:
'
Anthropic
'
},
{
value
:
'
openai
'
,
label
:
'
OpenAI
'
},
{
value
:
'
gemini
'
,
label
:
'
Gemini
'
},
{
value
:
'
antigravity
'
,
label
:
'
Antigravity
'
},
{
value
:
'
sora
'
,
label
:
'
Sora
'
}])
const
pOpts
=
computed
(()
=>
[{
value
:
''
,
label
:
t
(
'
admin.accounts.allPlatforms
'
)
},
{
value
:
'
anthropic
'
,
label
:
'
Anthropic
'
},
{
value
:
'
openai
'
,
label
:
'
OpenAI
'
},
{
value
:
'
gemini
'
,
label
:
'
Gemini
'
},
{
value
:
'
antigravity
'
,
label
:
'
Antigravity
'
},
{
value
:
'
sora
'
,
label
:
'
Sora
'
}])
const
tOpts
=
computed
(()
=>
[{
value
:
''
,
label
:
t
(
'
admin.accounts.allTypes
'
)
},
{
value
:
'
oauth
'
,
label
:
t
(
'
admin.accounts.oauthType
'
)
},
{
value
:
'
setup-token
'
,
label
:
t
(
'
admin.accounts.setupToken
'
)
},
{
value
:
'
apikey
'
,
label
:
t
(
'
admin.accounts.apiKey
'
)
},
{
value
:
'
bedrock
'
,
label
:
'
AWS Bedrock
'
}])
const
tOpts
=
computed
(()
=>
[{
value
:
''
,
label
:
t
(
'
admin.accounts.allTypes
'
)
},
{
value
:
'
oauth
'
,
label
:
t
(
'
admin.accounts.oauthType
'
)
},
{
value
:
'
setup-token
'
,
label
:
t
(
'
admin.accounts.setupToken
'
)
},
{
value
:
'
apikey
'
,
label
:
t
(
'
admin.accounts.apiKey
'
)
},
{
value
:
'
bedrock
'
,
label
:
'
AWS Bedrock
'
}])
const
sOpts
=
computed
(()
=>
[{
value
:
''
,
label
:
t
(
'
admin.accounts.allStatus
'
)
},
{
value
:
'
active
'
,
label
:
t
(
'
admin.accounts.status.active
'
)
},
{
value
:
'
inactive
'
,
label
:
t
(
'
admin.accounts.status.inactive
'
)
},
{
value
:
'
error
'
,
label
:
t
(
'
admin.accounts.status.error
'
)
},
{
value
:
'
rate_limited
'
,
label
:
t
(
'
admin.accounts.status.rateLimited
'
)
},
{
value
:
'
temp_unschedulable
'
,
label
:
t
(
'
admin.accounts.status.tempUnschedulable
'
)
}])
const
sOpts
=
computed
(()
=>
[{
value
:
''
,
label
:
t
(
'
admin.accounts.allStatus
'
)
},
{
value
:
'
active
'
,
label
:
t
(
'
admin.accounts.status.active
'
)
},
{
value
:
'
inactive
'
,
label
:
t
(
'
admin.accounts.status.inactive
'
)
},
{
value
:
'
error
'
,
label
:
t
(
'
admin.accounts.status.error
'
)
},
{
value
:
'
rate_limited
'
,
label
:
t
(
'
admin.accounts.status.rateLimited
'
)
},
{
value
:
'
temp_unschedulable
'
,
label
:
t
(
'
admin.accounts.status.tempUnschedulable
'
)
}])
const
privacyOpts
=
computed
(()
=>
[
{
value
:
''
,
label
:
t
(
'
admin.accounts.allPrivacyModes
'
)
},
{
value
:
'
__unset__
'
,
label
:
t
(
'
admin.accounts.privacyUnset
'
)
},
{
value
:
'
training_off
'
,
label
:
'
Privacy
'
},
{
value
:
'
training_set_cf_blocked
'
,
label
:
'
CF
'
},
{
value
:
'
training_set_failed
'
,
label
:
'
Fail
'
}
])
const
gOpts
=
computed
(()
=>
[
const
gOpts
=
computed
(()
=>
[
{
value
:
''
,
label
:
t
(
'
admin.accounts.allGroups
'
)
},
{
value
:
''
,
label
:
t
(
'
admin.accounts.allGroups
'
)
},
{
value
:
'
ungrouped
'
,
label
:
t
(
'
admin.accounts.ungroupedGroup
'
)
},
{
value
:
'
ungrouped
'
,
label
:
t
(
'
admin.accounts.ungroupedGroup
'
)
},
...
...
frontend/src/components/admin/account/__tests__/AccountTableFilters.spec.ts
0 → 100644
View file @
68d7ec91
import
{
describe
,
expect
,
it
,
vi
}
from
'
vitest
'
import
{
mount
}
from
'
@vue/test-utils
'
import
AccountTableFilters
from
'
../AccountTableFilters.vue
'
vi
.
mock
(
'
vue-i18n
'
,
async
()
=>
{
const
actual
=
await
vi
.
importActual
<
typeof
import
(
'
vue-i18n
'
)
>
(
'
vue-i18n
'
)
return
{
...
actual
,
useI18n
:
()
=>
({
t
:
(
key
:
string
)
=>
key
})
}
})
describe
(
'
AccountTableFilters
'
,
()
=>
{
it
(
'
renders privacy mode options and emits privacy_mode updates
'
,
async
()
=>
{
const
wrapper
=
mount
(
AccountTableFilters
,
{
props
:
{
searchQuery
:
''
,
filters
:
{
platform
:
''
,
type
:
''
,
status
:
''
,
group
:
''
,
privacy_mode
:
''
},
groups
:
[]
},
global
:
{
stubs
:
{
SearchInput
:
{
template
:
'
<div />
'
},
Select
:
{
props
:
[
'
modelValue
'
,
'
options
'
],
emits
:
[
'
update:modelValue
'
,
'
change
'
],
template
:
'
<div class="select-stub" :data-options="JSON.stringify(options)" />
'
}
}
}
})
const
selects
=
wrapper
.
findAll
(
'
.select-stub
'
)
expect
(
selects
).
toHaveLength
(
5
)
const
privacyOptions
=
JSON
.
parse
(
selects
[
3
].
attributes
(
'
data-options
'
))
expect
(
privacyOptions
).
toEqual
([
{
value
:
''
,
label
:
'
admin.accounts.allPrivacyModes
'
},
{
value
:
'
__unset__
'
,
label
:
'
admin.accounts.privacyUnset
'
},
{
value
:
'
training_off
'
,
label
:
'
Privacy
'
},
{
value
:
'
training_set_cf_blocked
'
,
label
:
'
CF
'
},
{
value
:
'
training_set_failed
'
,
label
:
'
Fail
'
}
])
})
})
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