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
8fd29082
Unverified
Commit
8fd29082
authored
Apr 15, 2026
by
Wesley Liddick
Committed by
GitHub
Apr 15, 2026
Browse files
Merge pull request #1663 from touwaeriol/fix/test-dialog-close-during-stream
fix(ui): allow closing test dialog during active SSE stream
parents
9bf079b7
38c00872
Changes
2
Show whitespace changes
Inline
Side-by-side
frontend/src/components/account/AccountTestModal.vue
View file @
8fd29082
...
@@ -165,7 +165,6 @@
...
@@ -165,7 +165,6 @@
<button
<button
@
click=
"handleClose"
@
click=
"handleClose"
class=
"rounded-lg bg-gray-100 px-4 py-2 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-200 dark:bg-dark-600 dark:text-gray-300 dark:hover:bg-dark-500"
class=
"rounded-lg bg-gray-100 px-4 py-2 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-200 dark:bg-dark-600 dark:text-gray-300 dark:hover:bg-dark-500"
:disabled=
"status === 'connecting'"
>
>
{{
t
(
'
common.close
'
)
}}
{{
t
(
'
common.close
'
)
}}
</button>
</button>
...
@@ -249,7 +248,7 @@ const availableModels = ref<ClaudeModel[]>([])
...
@@ -249,7 +248,7 @@ const availableModels = ref<ClaudeModel[]>([])
const
selectedModelId
=
ref
(
''
)
const
selectedModelId
=
ref
(
''
)
const
testPrompt
=
ref
(
''
)
const
testPrompt
=
ref
(
''
)
const
loadingModels
=
ref
(
false
)
const
loadingModels
=
ref
(
false
)
let
eventSource
:
EventSource
|
null
=
null
let
abortController
:
AbortController
|
null
=
null
const
generatedImages
=
ref
<
PreviewImage
[]
>
([])
const
generatedImages
=
ref
<
PreviewImage
[]
>
([])
const
prioritizedGeminiModels
=
[
'
gemini-3.1-flash-image
'
,
'
gemini-2.5-flash-image
'
,
'
gemini-2.5-flash
'
,
'
gemini-2.5-pro
'
,
'
gemini-3-flash-preview
'
,
'
gemini-3-pro-preview
'
,
'
gemini-2.0-flash
'
]
const
prioritizedGeminiModels
=
[
'
gemini-3.1-flash-image
'
,
'
gemini-2.5-flash-image
'
,
'
gemini-2.5-flash
'
,
'
gemini-2.5-pro
'
,
'
gemini-3-flash-preview
'
,
'
gemini-3-pro-preview
'
,
'
gemini-2.0-flash
'
]
const
supportsGeminiImageTest
=
computed
(()
=>
{
const
supportsGeminiImageTest
=
computed
(()
=>
{
...
@@ -279,7 +278,7 @@ watch(
...
@@ -279,7 +278,7 @@ watch(
resetState
()
resetState
()
await
loadAvailableModels
()
await
loadAvailableModels
()
}
else
{
}
else
{
closeEventSource
()
abortStream
()
}
}
}
}
)
)
...
@@ -329,18 +328,14 @@ const resetState = () => {
...
@@ -329,18 +328,14 @@ const resetState = () => {
}
}
const
handleClose
=
()
=>
{
const
handleClose
=
()
=>
{
// 防止在连接测试进行中关闭对话框
abortStream
()
if
(
status
.
value
===
'
connecting
'
)
{
return
}
closeEventSource
()
emit
(
'
close
'
)
emit
(
'
close
'
)
}
}
const
closeEventSource
=
()
=>
{
const
abortStream
=
()
=>
{
if
(
eventSource
)
{
if
(
abortController
)
{
eventSource
.
close
()
abortController
.
abort
()
eventSource
=
null
abortController
=
null
}
}
}
}
...
@@ -365,7 +360,9 @@ const startTest = async () => {
...
@@ -365,7 +360,9 @@ const startTest = async () => {
addLine
(
t
(
'
admin.accounts.testAccountTypeLabel
'
,
{
type
:
props
.
account
.
type
}),
'
text-gray-400
'
)
addLine
(
t
(
'
admin.accounts.testAccountTypeLabel
'
,
{
type
:
props
.
account
.
type
}),
'
text-gray-400
'
)
addLine
(
''
,
'
text-gray-300
'
)
addLine
(
''
,
'
text-gray-300
'
)
closeEventSource
()
abortStream
()
abortController
=
new
AbortController
()
try
{
try
{
// Create EventSource for SSE
// Create EventSource for SSE
...
@@ -381,7 +378,8 @@ const startTest = async () => {
...
@@ -381,7 +378,8 @@ const startTest = async () => {
body
:
JSON
.
stringify
({
body
:
JSON
.
stringify
({
model_id
:
selectedModelId
.
value
,
model_id
:
selectedModelId
.
value
,
prompt
:
supportsGeminiImageTest
.
value
?
testPrompt
.
value
.
trim
()
:
''
prompt
:
supportsGeminiImageTest
.
value
?
testPrompt
.
value
.
trim
()
:
''
})
}),
signal
:
abortController
.
signal
})
})
if
(
!
response
.
ok
)
{
if
(
!
response
.
ok
)
{
...
@@ -418,10 +416,15 @@ const startTest = async () => {
...
@@ -418,10 +416,15 @@ const startTest = async () => {
}
}
}
}
}
}
}
catch
(
error
:
any
)
{
}
catch
(
error
:
unknown
)
{
if
(
error
instanceof
DOMException
&&
error
.
name
===
'
AbortError
'
)
{
status
.
value
=
'
idle
'
return
}
status
.
value
=
'
error
'
status
.
value
=
'
error
'
errorMessage
.
value
=
error
.
message
||
'
Unknown error
'
const
msg
=
error
instanceof
Error
?
error
.
message
:
'
Unknown error
'
addLine
(
`Error:
${
errorMessage
.
value
}
`
,
'
text-red-400
'
)
errorMessage
.
value
=
msg
addLine
(
`Error:
${
msg
}
`
,
'
text-red-400
'
)
}
}
}
}
...
...
frontend/src/components/admin/account/AccountTestModal.vue
View file @
8fd29082
...
@@ -165,7 +165,6 @@
...
@@ -165,7 +165,6 @@
<button
<button
@
click=
"handleClose"
@
click=
"handleClose"
class=
"rounded-lg bg-gray-100 px-4 py-2 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-200 dark:bg-dark-600 dark:text-gray-300 dark:hover:bg-dark-500"
class=
"rounded-lg bg-gray-100 px-4 py-2 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-200 dark:bg-dark-600 dark:text-gray-300 dark:hover:bg-dark-500"
:disabled=
"status === 'connecting'"
>
>
{{
t
(
'
common.close
'
)
}}
{{
t
(
'
common.close
'
)
}}
</button>
</button>
...
@@ -249,7 +248,7 @@ const availableModels = ref<ClaudeModel[]>([])
...
@@ -249,7 +248,7 @@ const availableModels = ref<ClaudeModel[]>([])
const
selectedModelId
=
ref
(
''
)
const
selectedModelId
=
ref
(
''
)
const
testPrompt
=
ref
(
''
)
const
testPrompt
=
ref
(
''
)
const
loadingModels
=
ref
(
false
)
const
loadingModels
=
ref
(
false
)
let
eventSource
:
EventSource
|
null
=
null
let
abortController
:
AbortController
|
null
=
null
const
generatedImages
=
ref
<
PreviewImage
[]
>
([])
const
generatedImages
=
ref
<
PreviewImage
[]
>
([])
const
prioritizedGeminiModels
=
[
'
gemini-3.1-flash-image
'
,
'
gemini-2.5-flash-image
'
,
'
gemini-2.5-flash
'
,
'
gemini-2.5-pro
'
,
'
gemini-3-flash-preview
'
,
'
gemini-3-pro-preview
'
,
'
gemini-2.0-flash
'
]
const
prioritizedGeminiModels
=
[
'
gemini-3.1-flash-image
'
,
'
gemini-2.5-flash-image
'
,
'
gemini-2.5-flash
'
,
'
gemini-2.5-pro
'
,
'
gemini-3-flash-preview
'
,
'
gemini-3-pro-preview
'
,
'
gemini-2.0-flash
'
]
const
supportsGeminiImageTest
=
computed
(()
=>
{
const
supportsGeminiImageTest
=
computed
(()
=>
{
...
@@ -279,7 +278,7 @@ watch(
...
@@ -279,7 +278,7 @@ watch(
resetState
()
resetState
()
await
loadAvailableModels
()
await
loadAvailableModels
()
}
else
{
}
else
{
closeEventSource
()
abortStream
()
}
}
}
}
)
)
...
@@ -329,18 +328,14 @@ const resetState = () => {
...
@@ -329,18 +328,14 @@ const resetState = () => {
}
}
const
handleClose
=
()
=>
{
const
handleClose
=
()
=>
{
// 防止在连接测试进行中关闭对话框
abortStream
()
if
(
status
.
value
===
'
connecting
'
)
{
return
}
closeEventSource
()
emit
(
'
close
'
)
emit
(
'
close
'
)
}
}
const
closeEventSource
=
()
=>
{
const
abortStream
=
()
=>
{
if
(
eventSource
)
{
if
(
abortController
)
{
eventSource
.
close
()
abortController
.
abort
()
eventSource
=
null
abortController
=
null
}
}
}
}
...
@@ -365,7 +360,9 @@ const startTest = async () => {
...
@@ -365,7 +360,9 @@ const startTest = async () => {
addLine
(
t
(
'
admin.accounts.testAccountTypeLabel
'
,
{
type
:
props
.
account
.
type
}),
'
text-gray-400
'
)
addLine
(
t
(
'
admin.accounts.testAccountTypeLabel
'
,
{
type
:
props
.
account
.
type
}),
'
text-gray-400
'
)
addLine
(
''
,
'
text-gray-300
'
)
addLine
(
''
,
'
text-gray-300
'
)
closeEventSource
()
abortStream
()
abortController
=
new
AbortController
()
try
{
try
{
// Create EventSource for SSE
// Create EventSource for SSE
...
@@ -381,7 +378,8 @@ const startTest = async () => {
...
@@ -381,7 +378,8 @@ const startTest = async () => {
body
:
JSON
.
stringify
({
body
:
JSON
.
stringify
({
model_id
:
selectedModelId
.
value
,
model_id
:
selectedModelId
.
value
,
prompt
:
supportsGeminiImageTest
.
value
?
testPrompt
.
value
.
trim
()
:
''
prompt
:
supportsGeminiImageTest
.
value
?
testPrompt
.
value
.
trim
()
:
''
})
}),
signal
:
abortController
.
signal
})
})
if
(
!
response
.
ok
)
{
if
(
!
response
.
ok
)
{
...
@@ -418,10 +416,15 @@ const startTest = async () => {
...
@@ -418,10 +416,15 @@ const startTest = async () => {
}
}
}
}
}
}
}
catch
(
error
:
any
)
{
}
catch
(
error
:
unknown
)
{
if
(
error
instanceof
DOMException
&&
error
.
name
===
'
AbortError
'
)
{
status
.
value
=
'
idle
'
return
}
status
.
value
=
'
error
'
status
.
value
=
'
error
'
errorMessage
.
value
=
error
.
message
||
'
Unknown error
'
const
msg
=
error
instanceof
Error
?
error
.
message
:
'
Unknown error
'
addLine
(
`Error:
${
errorMessage
.
value
}
`
,
'
text-red-400
'
)
errorMessage
.
value
=
msg
addLine
(
`Error:
${
msg
}
`
,
'
text-red-400
'
)
}
}
}
}
...
...
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