Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
beb6ea96
authored
Jul 08, 2025
by
CaIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
✨
feat(ability): enhance FixAbility function
parent
4e974daa
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
39 additions
and
64 deletions
+39
-64
controller/channel.go
+5
-2
main.go
+2
-2
model/ability.go
+30
-58
web/src/components/table/ChannelsTable.js
+1
-1
web/src/pages/Channel/EditChannel.js
+1
-1
No files found.
controller/channel.go
View file @
beb6ea96
...
@@ -228,7 +228,7 @@ func FetchUpstreamModels(c *gin.Context) {
...
@@ -228,7 +228,7 @@ func FetchUpstreamModels(c *gin.Context) {
}
}
func
FixChannelsAbilities
(
c
*
gin
.
Context
)
{
func
FixChannelsAbilities
(
c
*
gin
.
Context
)
{
count
,
err
:=
model
.
FixAbility
()
success
,
fails
,
err
:=
model
.
FixAbility
()
if
err
!=
nil
{
if
err
!=
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"success"
:
false
,
...
@@ -239,7 +239,10 @@ func FixChannelsAbilities(c *gin.Context) {
...
@@ -239,7 +239,10 @@ func FixChannelsAbilities(c *gin.Context) {
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
true
,
"success"
:
true
,
"message"
:
""
,
"message"
:
""
,
"data"
:
count
,
"data"
:
gin
.
H
{
"success"
:
success
,
"fails"
:
fails
,
},
})
})
}
}
...
...
main.go
View file @
beb6ea96
...
@@ -68,9 +68,9 @@ func main() {
...
@@ -68,9 +68,9 @@ func main() {
if
r
:=
recover
();
r
!=
nil
{
if
r
:=
recover
();
r
!=
nil
{
common
.
SysError
(
fmt
.
Sprintf
(
"InitChannelCache panic: %v, retrying once"
,
r
))
common
.
SysError
(
fmt
.
Sprintf
(
"InitChannelCache panic: %v, retrying once"
,
r
))
// Retry once
// Retry once
_
,
fixErr
:=
model
.
FixAbility
()
_
,
_
,
fixErr
:=
model
.
FixAbility
()
if
fixErr
!=
nil
{
if
fixErr
!=
nil
{
common
.
SysError
(
fmt
.
Sprintf
(
"InitChannelCache failed: %s"
,
fixErr
.
Error
()))
common
.
FatalLog
(
fmt
.
Sprintf
(
"InitChannelCache failed: %s"
,
fixErr
.
Error
()))
}
}
}
}
}()
}()
...
...
model/ability.go
View file @
beb6ea96
...
@@ -5,6 +5,7 @@ import (
...
@@ -5,6 +5,7 @@ import (
"fmt"
"fmt"
"one-api/common"
"one-api/common"
"strings"
"strings"
"sync"
"github.com/samber/lo"
"github.com/samber/lo"
"gorm.io/gorm"
"gorm.io/gorm"
...
@@ -272,74 +273,45 @@ func UpdateAbilityByTag(tag string, newTag *string, priority *int64, weight *uin
...
@@ -272,74 +273,45 @@ func UpdateAbilityByTag(tag string, newTag *string, priority *int64, weight *uin
return
DB
.
Model
(
&
Ability
{})
.
Where
(
"tag = ?"
,
tag
)
.
Updates
(
ability
)
.
Error
return
DB
.
Model
(
&
Ability
{})
.
Where
(
"tag = ?"
,
tag
)
.
Updates
(
ability
)
.
Error
}
}
func
FixAbility
()
(
int
,
error
)
{
var
fixLock
=
sync
.
Mutex
{}
var
channelIds
[]
int
count
:=
0
// Find all channel ids from channel table
err
:=
DB
.
Model
(
&
Channel
{})
.
Pluck
(
"id"
,
&
channelIds
)
.
Error
if
err
!=
nil
{
common
.
SysError
(
fmt
.
Sprintf
(
"Get channel ids from channel table failed: %s"
,
err
.
Error
()))
return
0
,
err
}
// Delete abilities of channels that are not in channel table - in batches to avoid too many placeholders
func
FixAbility
()
(
int
,
int
,
error
)
{
if
len
(
channelIds
)
>
0
{
lock
:=
fixLock
.
TryLock
()
// Process deletion in chunks to avoid "too many placeholders" error
if
!
lock
{
for
_
,
chunk
:=
range
lo
.
Chunk
(
channelIds
,
100
)
{
return
0
,
0
,
errors
.
New
(
"已经有一个修复任务在运行中,请稍后再试"
)
err
=
DB
.
Where
(
"channel_id NOT IN (?)"
,
chunk
)
.
Delete
(
&
Ability
{})
.
Error
if
err
!=
nil
{
common
.
SysError
(
fmt
.
Sprintf
(
"Delete abilities of channels (batch) that are not in channel table failed: %s"
,
err
.
Error
()))
return
0
,
err
}
}
}
defer
fixLock
.
Unlock
()
}
else
{
var
channels
[]
*
Channel
// If no channels exist, delete all abilitie
s
// Find all channel
s
err
=
DB
.
Delete
(
&
Ability
{}
)
.
Error
err
:=
DB
.
Model
(
&
Channel
{})
.
Find
(
&
channels
)
.
Error
if
err
!=
nil
{
if
err
!=
nil
{
common
.
SysError
(
fmt
.
Sprintf
(
"Delete all abilities failed: %s"
,
err
.
Error
()))
return
0
,
0
,
err
return
0
,
err
}
}
common
.
SysLog
(
"Delete all abilities successfully"
)
if
len
(
channels
)
==
0
{
return
0
,
nil
return
0
,
0
,
nil
}
common
.
SysLog
(
fmt
.
Sprintf
(
"Delete abilities of channels that are not in channel table successfully, ids: %v"
,
channelIds
))
count
+=
len
(
channelIds
)
// Use channelIds to find channel not in abilities table
var
abilityChannelIds
[]
int
err
=
DB
.
Table
(
"abilities"
)
.
Distinct
(
"channel_id"
)
.
Pluck
(
"channel_id"
,
&
abilityChannelIds
)
.
Error
if
err
!=
nil
{
common
.
SysError
(
fmt
.
Sprintf
(
"Get channel ids from abilities table failed: %s"
,
err
.
Error
()))
return
count
,
err
}
}
successCount
:=
0
var
channels
[]
Channel
failCount
:=
0
if
len
(
abilityChannelIds
)
==
0
{
for
_
,
chunk
:=
range
lo
.
Chunk
(
channels
,
50
)
{
err
=
DB
.
Find
(
&
channels
)
.
Error
ids
:=
lo
.
Map
(
chunk
,
func
(
c
*
Channel
,
_
int
)
int
{
return
c
.
Id
})
}
else
{
// Delete all abilities of this channel
// Process query in chunks to avoid "too many placeholders" error
err
=
DB
.
Where
(
"channel_id IN ?"
,
ids
)
.
Delete
(
&
Ability
{})
.
Error
err
=
nil
for
_
,
chunk
:=
range
lo
.
Chunk
(
abilityChannelIds
,
100
)
{
var
channelsChunk
[]
Channel
err
=
DB
.
Where
(
"id NOT IN (?)"
,
chunk
)
.
Find
(
&
channelsChunk
)
.
Error
if
err
!=
nil
{
if
err
!=
nil
{
common
.
SysError
(
fmt
.
Sprintf
(
"Find channels not in abilities table failed: %s"
,
err
.
Error
()))
common
.
SysError
(
fmt
.
Sprintf
(
"Delete abilities failed: %s"
,
err
.
Error
()))
return
count
,
err
failCount
+=
len
(
chunk
)
}
continue
channels
=
append
(
channels
,
channelsChunk
...
)
}
}
}
// Then add new abilities
for
_
,
channel
:=
range
channels
{
for
_
,
channel
:=
range
chunk
{
err
:=
channel
.
UpdateAbilities
(
nil
)
err
=
channel
.
AddAbilities
(
)
if
err
!=
nil
{
if
err
!=
nil
{
common
.
SysError
(
fmt
.
Sprintf
(
"Update abilities of channel %d failed: %s"
,
channel
.
Id
,
err
.
Error
()))
common
.
SysError
(
fmt
.
Sprintf
(
"Add abilities for channel %d failed: %s"
,
channel
.
Id
,
err
.
Error
()))
failCount
++
}
else
{
}
else
{
common
.
SysLog
(
fmt
.
Sprintf
(
"Update abilities of channel %d successfully"
,
channel
.
Id
))
successCount
++
count
++
}
}
}
}
}
InitChannelCache
()
InitChannelCache
()
return
c
ount
,
nil
return
successCount
,
failC
ount
,
nil
}
}
web/src/components/table/ChannelsTable.js
View file @
beb6ea96
...
@@ -1463,7 +1463,7 @@ const ChannelsTable = () => {
...
@@ -1463,7 +1463,7 @@ const ChannelsTable = () => {
const
res
=
await
API
.
post
(
`/api/channel/fix`
);
const
res
=
await
API
.
post
(
`/api/channel/fix`
);
const
{
success
,
message
,
data
}
=
res
.
data
;
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
showSuccess
(
t
(
'已修复 ${
data} 个通道!'
).
replace
(
'${data}'
,
data
));
showSuccess
(
t
(
'已修复 ${
success} 个通道,失败 ${fails} 个通道。'
).
replace
(
'${success}'
,
data
.
success
).
replace
(
'${fails}'
,
data
.
fails
));
await
refresh
();
await
refresh
();
}
else
{
}
else
{
showError
(
message
);
showError
(
message
);
...
...
web/src/pages/Channel/EditChannel.js
View file @
beb6ea96
...
@@ -240,7 +240,7 @@ const EditChannel = (props) => {
...
@@ -240,7 +240,7 @@ const EditChannel = (props) => {
if
(
isEdit
)
{
if
(
isEdit
)
{
// 如果是编辑模式,使用已有的channel id获取模型列表
// 如果是编辑模式,使用已有的channel id获取模型列表
const
res
=
await
API
.
get
(
'/api/channel/fetch_models/'
+
channelId
);
const
res
=
await
API
.
get
(
'/api/channel/fetch_models/'
+
channelId
);
if
(
res
.
data
&&
res
.
data
?
.
success
)
{
if
(
res
.
data
&&
res
.
data
.
success
)
{
models
.
push
(...
res
.
data
.
data
);
models
.
push
(...
res
.
data
.
data
);
}
else
{
}
else
{
err
=
true
;
err
=
true
;
...
...
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