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
2a0bf7f9
authored
Jun 11, 2025
by
creamlike1024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 分组特殊倍率
parent
92de4d0d
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
224 additions
and
55 deletions
+224
-55
controller/channel-test.go
+1
-1
controller/pricing.go
+8
-1
model/option.go
+3
-0
relay/common/relay_info.go
+2
-0
relay/helper/price.go
+8
-1
relay/relay-text.go
+2
-1
service/log_info_generate.go
+8
-7
service/quota.go
+21
-6
setting/group_ratio.go
+31
-0
web/src/components/settings/OperationSetting.js
+2
-0
web/src/components/table/LogsTable.js
+55
-23
web/src/helpers/render.js
+61
-15
web/src/pages/Setting/Operation/GroupRatioSettings.js
+22
-0
No files found.
controller/channel-test.go
View file @
2a0bf7f9
...
@@ -166,7 +166,7 @@ func testChannel(channel *model.Channel, testModel string) (err error, openAIErr
...
@@ -166,7 +166,7 @@ func testChannel(channel *model.Channel, testModel string) (err error, openAIErr
milliseconds
:=
tok
.
Sub
(
tik
)
.
Milliseconds
()
milliseconds
:=
tok
.
Sub
(
tik
)
.
Milliseconds
()
consumedTime
:=
float64
(
milliseconds
)
/
1000.0
consumedTime
:=
float64
(
milliseconds
)
/
1000.0
other
:=
service
.
GenerateTextOtherInfo
(
c
,
info
,
priceData
.
ModelRatio
,
priceData
.
GroupRatio
,
priceData
.
CompletionRatio
,
other
:=
service
.
GenerateTextOtherInfo
(
c
,
info
,
priceData
.
ModelRatio
,
priceData
.
GroupRatio
,
priceData
.
CompletionRatio
,
usage
.
PromptTokensDetails
.
CachedTokens
,
priceData
.
CacheRatio
,
priceData
.
ModelPrice
)
usage
.
PromptTokensDetails
.
CachedTokens
,
priceData
.
CacheRatio
,
priceData
.
ModelPrice
,
priceData
.
UserGroupRatio
)
model
.
RecordConsumeLog
(
c
,
1
,
channel
.
Id
,
usage
.
PromptTokens
,
usage
.
CompletionTokens
,
info
.
OriginModelName
,
"模型测试"
,
model
.
RecordConsumeLog
(
c
,
1
,
channel
.
Id
,
usage
.
PromptTokens
,
usage
.
CompletionTokens
,
info
.
OriginModelName
,
"模型测试"
,
quota
,
"模型测试"
,
0
,
quota
,
int
(
consumedTime
),
false
,
info
.
Group
,
other
)
quota
,
"模型测试"
,
0
,
quota
,
int
(
consumedTime
),
false
,
info
.
Group
,
other
)
common
.
SysLog
(
fmt
.
Sprintf
(
"testing channel #%d, response:
\n
%s"
,
channel
.
Id
,
string
(
respBody
)))
common
.
SysLog
(
fmt
.
Sprintf
(
"testing channel #%d, response:
\n
%s"
,
channel
.
Id
,
string
(
respBody
)))
...
...
controller/pricing.go
View file @
2a0bf7f9
package
controller
package
controller
import
(
import
(
"github.com/gin-gonic/gin"
"one-api/model"
"one-api/model"
"one-api/setting"
"one-api/setting"
"one-api/setting/operation_setting"
"one-api/setting/operation_setting"
"github.com/gin-gonic/gin"
)
)
func
GetPricing
(
c
*
gin
.
Context
)
{
func
GetPricing
(
c
*
gin
.
Context
)
{
...
@@ -20,6 +21,12 @@ func GetPricing(c *gin.Context) {
...
@@ -20,6 +21,12 @@ func GetPricing(c *gin.Context) {
user
,
err
:=
model
.
GetUserCache
(
userId
.
(
int
))
user
,
err
:=
model
.
GetUserCache
(
userId
.
(
int
))
if
err
==
nil
{
if
err
==
nil
{
group
=
user
.
Group
group
=
user
.
Group
for
g
:=
range
groupRatio
{
ratio
,
ok
:=
setting
.
GetGroupGroupRatio
(
group
,
g
)
if
ok
{
groupRatio
[
g
]
=
ratio
}
}
}
}
}
}
...
...
model/option.go
View file @
2a0bf7f9
...
@@ -98,6 +98,7 @@ func InitOptionMap() {
...
@@ -98,6 +98,7 @@ func InitOptionMap() {
common
.
OptionMap
[
"ModelPrice"
]
=
operation_setting
.
ModelPrice2JSONString
()
common
.
OptionMap
[
"ModelPrice"
]
=
operation_setting
.
ModelPrice2JSONString
()
common
.
OptionMap
[
"CacheRatio"
]
=
operation_setting
.
CacheRatio2JSONString
()
common
.
OptionMap
[
"CacheRatio"
]
=
operation_setting
.
CacheRatio2JSONString
()
common
.
OptionMap
[
"GroupRatio"
]
=
setting
.
GroupRatio2JSONString
()
common
.
OptionMap
[
"GroupRatio"
]
=
setting
.
GroupRatio2JSONString
()
common
.
OptionMap
[
"GroupGroupRatio"
]
=
setting
.
GroupGroupRatio2JSONString
()
common
.
OptionMap
[
"UserUsableGroups"
]
=
setting
.
UserUsableGroups2JSONString
()
common
.
OptionMap
[
"UserUsableGroups"
]
=
setting
.
UserUsableGroups2JSONString
()
common
.
OptionMap
[
"CompletionRatio"
]
=
operation_setting
.
CompletionRatio2JSONString
()
common
.
OptionMap
[
"CompletionRatio"
]
=
operation_setting
.
CompletionRatio2JSONString
()
common
.
OptionMap
[
"TopUpLink"
]
=
common
.
TopUpLink
common
.
OptionMap
[
"TopUpLink"
]
=
common
.
TopUpLink
...
@@ -355,6 +356,8 @@ func updateOptionMap(key string, value string) (err error) {
...
@@ -355,6 +356,8 @@ func updateOptionMap(key string, value string) (err error) {
err
=
operation_setting
.
UpdateModelRatioByJSONString
(
value
)
err
=
operation_setting
.
UpdateModelRatioByJSONString
(
value
)
case
"GroupRatio"
:
case
"GroupRatio"
:
err
=
setting
.
UpdateGroupRatioByJSONString
(
value
)
err
=
setting
.
UpdateGroupRatioByJSONString
(
value
)
case
"GroupGroupRatio"
:
err
=
setting
.
UpdateGroupGroupRatioByJSONString
(
value
)
case
"UserUsableGroups"
:
case
"UserUsableGroups"
:
err
=
setting
.
UpdateUserUsableGroupsByJSONString
(
value
)
err
=
setting
.
UpdateUserUsableGroupsByJSONString
(
value
)
case
"CompletionRatio"
:
case
"CompletionRatio"
:
...
...
relay/common/relay_info.go
View file @
2a0bf7f9
...
@@ -61,6 +61,7 @@ type RelayInfo struct {
...
@@ -61,6 +61,7 @@ type RelayInfo struct {
TokenKey
string
TokenKey
string
UserId
int
UserId
int
Group
string
Group
string
UserGroup
string
TokenUnlimited
bool
TokenUnlimited
bool
StartTime
time
.
Time
StartTime
time
.
Time
FirstResponseTime
time
.
Time
FirstResponseTime
time
.
Time
...
@@ -204,6 +205,7 @@ func GenRelayInfo(c *gin.Context) *RelayInfo {
...
@@ -204,6 +205,7 @@ func GenRelayInfo(c *gin.Context) *RelayInfo {
TokenKey
:
tokenKey
,
TokenKey
:
tokenKey
,
UserId
:
userId
,
UserId
:
userId
,
Group
:
group
,
Group
:
group
,
UserGroup
:
c
.
GetString
(
constant
.
ContextKeyUserGroup
),
TokenUnlimited
:
tokenUnlimited
,
TokenUnlimited
:
tokenUnlimited
,
StartTime
:
startTime
,
StartTime
:
startTime
,
FirstResponseTime
:
startTime
.
Add
(
-
time
.
Second
),
FirstResponseTime
:
startTime
.
Add
(
-
time
.
Second
),
...
...
relay/helper/price.go
View file @
2a0bf7f9
...
@@ -2,12 +2,13 @@ package helper
...
@@ -2,12 +2,13 @@ package helper
import
(
import
(
"fmt"
"fmt"
"github.com/gin-gonic/gin"
"one-api/common"
"one-api/common"
constant2
"one-api/constant"
constant2
"one-api/constant"
relaycommon
"one-api/relay/common"
relaycommon
"one-api/relay/common"
"one-api/setting"
"one-api/setting"
"one-api/setting/operation_setting"
"one-api/setting/operation_setting"
"github.com/gin-gonic/gin"
)
)
type
PriceData
struct
{
type
PriceData
struct
{
...
@@ -18,6 +19,7 @@ type PriceData struct {
...
@@ -18,6 +19,7 @@ type PriceData struct {
CacheCreationRatio
float64
CacheCreationRatio
float64
ImageRatio
float64
ImageRatio
float64
GroupRatio
float64
GroupRatio
float64
UserGroupRatio
float64
UsePrice
bool
UsePrice
bool
ShouldPreConsumedQuota
int
ShouldPreConsumedQuota
int
}
}
...
@@ -29,6 +31,10 @@ func (p PriceData) ToSetting() string {
...
@@ -29,6 +31,10 @@ func (p PriceData) ToSetting() string {
func
ModelPriceHelper
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
promptTokens
int
,
maxTokens
int
)
(
PriceData
,
error
)
{
func
ModelPriceHelper
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
promptTokens
int
,
maxTokens
int
)
(
PriceData
,
error
)
{
modelPrice
,
usePrice
:=
operation_setting
.
GetModelPrice
(
info
.
OriginModelName
,
false
)
modelPrice
,
usePrice
:=
operation_setting
.
GetModelPrice
(
info
.
OriginModelName
,
false
)
groupRatio
:=
setting
.
GetGroupRatio
(
info
.
Group
)
groupRatio
:=
setting
.
GetGroupRatio
(
info
.
Group
)
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
info
.
UserGroup
,
info
.
Group
)
if
ok
{
groupRatio
=
userGroupRatio
}
var
preConsumedQuota
int
var
preConsumedQuota
int
var
modelRatio
float64
var
modelRatio
float64
var
completionRatio
float64
var
completionRatio
float64
...
@@ -69,6 +75,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens
...
@@ -69,6 +75,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens
ModelRatio
:
modelRatio
,
ModelRatio
:
modelRatio
,
CompletionRatio
:
completionRatio
,
CompletionRatio
:
completionRatio
,
GroupRatio
:
groupRatio
,
GroupRatio
:
groupRatio
,
UserGroupRatio
:
userGroupRatio
,
UsePrice
:
usePrice
,
UsePrice
:
usePrice
,
CacheRatio
:
cacheRatio
,
CacheRatio
:
cacheRatio
,
ImageRatio
:
imageRatio
,
ImageRatio
:
imageRatio
,
...
...
relay/relay-text.go
View file @
2a0bf7f9
...
@@ -363,6 +363,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
...
@@ -363,6 +363,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
modelRatio
:=
priceData
.
ModelRatio
modelRatio
:=
priceData
.
ModelRatio
groupRatio
:=
priceData
.
GroupRatio
groupRatio
:=
priceData
.
GroupRatio
modelPrice
:=
priceData
.
ModelPrice
modelPrice
:=
priceData
.
ModelPrice
userGroupRatio
:=
priceData
.
UserGroupRatio
// Convert values to decimal for precise calculation
// Convert values to decimal for precise calculation
dPromptTokens
:=
decimal
.
NewFromInt
(
int64
(
promptTokens
))
dPromptTokens
:=
decimal
.
NewFromInt
(
int64
(
promptTokens
))
...
@@ -510,7 +511,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
...
@@ -510,7 +511,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
if
extraContent
!=
""
{
if
extraContent
!=
""
{
logContent
+=
", "
+
extraContent
logContent
+=
", "
+
extraContent
}
}
other
:=
service
.
GenerateTextOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
cacheTokens
,
cacheRatio
,
modelPrice
)
other
:=
service
.
GenerateTextOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
cacheTokens
,
cacheRatio
,
modelPrice
,
userGroupRatio
)
if
imageTokens
!=
0
{
if
imageTokens
!=
0
{
other
[
"image"
]
=
true
other
[
"image"
]
=
true
other
[
"image_ratio"
]
=
imageRatio
other
[
"image_ratio"
]
=
imageRatio
...
...
service/log_info_generate.go
View file @
2a0bf7f9
...
@@ -8,7 +8,7 @@ import (
...
@@ -8,7 +8,7 @@ import (
)
)
func
GenerateTextOtherInfo
(
ctx
*
gin
.
Context
,
relayInfo
*
relaycommon
.
RelayInfo
,
modelRatio
,
groupRatio
,
completionRatio
float64
,
func
GenerateTextOtherInfo
(
ctx
*
gin
.
Context
,
relayInfo
*
relaycommon
.
RelayInfo
,
modelRatio
,
groupRatio
,
completionRatio
float64
,
cacheTokens
int
,
cacheRatio
float64
,
modelPrice
float64
)
map
[
string
]
interface
{}
{
cacheTokens
int
,
cacheRatio
float64
,
modelPrice
float64
,
userGroupRatio
float64
)
map
[
string
]
interface
{}
{
other
:=
make
(
map
[
string
]
interface
{})
other
:=
make
(
map
[
string
]
interface
{})
other
[
"model_ratio"
]
=
modelRatio
other
[
"model_ratio"
]
=
modelRatio
other
[
"group_ratio"
]
=
groupRatio
other
[
"group_ratio"
]
=
groupRatio
...
@@ -16,6 +16,7 @@ func GenerateTextOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, m
...
@@ -16,6 +16,7 @@ func GenerateTextOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, m
other
[
"cache_tokens"
]
=
cacheTokens
other
[
"cache_tokens"
]
=
cacheTokens
other
[
"cache_ratio"
]
=
cacheRatio
other
[
"cache_ratio"
]
=
cacheRatio
other
[
"model_price"
]
=
modelPrice
other
[
"model_price"
]
=
modelPrice
other
[
"user_group_ratio"
]
=
userGroupRatio
other
[
"frt"
]
=
float64
(
relayInfo
.
FirstResponseTime
.
UnixMilli
()
-
relayInfo
.
StartTime
.
UnixMilli
())
other
[
"frt"
]
=
float64
(
relayInfo
.
FirstResponseTime
.
UnixMilli
()
-
relayInfo
.
StartTime
.
UnixMilli
())
if
relayInfo
.
ReasoningEffort
!=
""
{
if
relayInfo
.
ReasoningEffort
!=
""
{
other
[
"reasoning_effort"
]
=
relayInfo
.
ReasoningEffort
other
[
"reasoning_effort"
]
=
relayInfo
.
ReasoningEffort
...
@@ -30,8 +31,8 @@ func GenerateTextOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, m
...
@@ -30,8 +31,8 @@ func GenerateTextOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, m
return
other
return
other
}
}
func
GenerateWssOtherInfo
(
ctx
*
gin
.
Context
,
relayInfo
*
relaycommon
.
RelayInfo
,
usage
*
dto
.
RealtimeUsage
,
modelRatio
,
groupRatio
,
completionRatio
,
audioRatio
,
audioCompletionRatio
,
modelPrice
float64
)
map
[
string
]
interface
{}
{
func
GenerateWssOtherInfo
(
ctx
*
gin
.
Context
,
relayInfo
*
relaycommon
.
RelayInfo
,
usage
*
dto
.
RealtimeUsage
,
modelRatio
,
groupRatio
,
completionRatio
,
audioRatio
,
audioCompletionRatio
,
modelPrice
,
userGroupRatio
float64
)
map
[
string
]
interface
{}
{
info
:=
GenerateTextOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
0
,
0.0
,
modelPrice
)
info
:=
GenerateTextOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
0
,
0.0
,
modelPrice
,
userGroupRatio
)
info
[
"ws"
]
=
true
info
[
"ws"
]
=
true
info
[
"audio_input"
]
=
usage
.
InputTokenDetails
.
AudioTokens
info
[
"audio_input"
]
=
usage
.
InputTokenDetails
.
AudioTokens
info
[
"audio_output"
]
=
usage
.
OutputTokenDetails
.
AudioTokens
info
[
"audio_output"
]
=
usage
.
OutputTokenDetails
.
AudioTokens
...
@@ -42,8 +43,8 @@ func GenerateWssOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, us
...
@@ -42,8 +43,8 @@ func GenerateWssOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, us
return
info
return
info
}
}
func
GenerateAudioOtherInfo
(
ctx
*
gin
.
Context
,
relayInfo
*
relaycommon
.
RelayInfo
,
usage
*
dto
.
Usage
,
modelRatio
,
groupRatio
,
completionRatio
,
audioRatio
,
audioCompletionRatio
,
modelPrice
float64
)
map
[
string
]
interface
{}
{
func
GenerateAudioOtherInfo
(
ctx
*
gin
.
Context
,
relayInfo
*
relaycommon
.
RelayInfo
,
usage
*
dto
.
Usage
,
modelRatio
,
groupRatio
,
completionRatio
,
audioRatio
,
audioCompletionRatio
,
modelPrice
,
userGroupRatio
float64
)
map
[
string
]
interface
{}
{
info
:=
GenerateTextOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
0
,
0.0
,
modelPrice
)
info
:=
GenerateTextOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
0
,
0.0
,
modelPrice
,
userGroupRatio
)
info
[
"audio"
]
=
true
info
[
"audio"
]
=
true
info
[
"audio_input"
]
=
usage
.
PromptTokensDetails
.
AudioTokens
info
[
"audio_input"
]
=
usage
.
PromptTokensDetails
.
AudioTokens
info
[
"audio_output"
]
=
usage
.
CompletionTokenDetails
.
AudioTokens
info
[
"audio_output"
]
=
usage
.
CompletionTokenDetails
.
AudioTokens
...
@@ -55,8 +56,8 @@ func GenerateAudioOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
...
@@ -55,8 +56,8 @@ func GenerateAudioOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
}
}
func
GenerateClaudeOtherInfo
(
ctx
*
gin
.
Context
,
relayInfo
*
relaycommon
.
RelayInfo
,
modelRatio
,
groupRatio
,
completionRatio
float64
,
func
GenerateClaudeOtherInfo
(
ctx
*
gin
.
Context
,
relayInfo
*
relaycommon
.
RelayInfo
,
modelRatio
,
groupRatio
,
completionRatio
float64
,
cacheTokens
int
,
cacheRatio
float64
,
cacheCreationTokens
int
,
cacheCreationRatio
float64
,
modelPrice
float64
)
map
[
string
]
interface
{}
{
cacheTokens
int
,
cacheRatio
float64
,
cacheCreationTokens
int
,
cacheCreationRatio
float64
,
modelPrice
float64
,
userGroupRatio
float64
)
map
[
string
]
interface
{}
{
info
:=
GenerateTextOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
cacheTokens
,
cacheRatio
,
modelPrice
)
info
:=
GenerateTextOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
cacheTokens
,
cacheRatio
,
modelPrice
,
userGroupRatio
)
info
[
"claude"
]
=
true
info
[
"claude"
]
=
true
info
[
"cache_creation_tokens"
]
=
cacheCreationTokens
info
[
"cache_creation_tokens"
]
=
cacheCreationTokens
info
[
"cache_creation_ratio"
]
=
cacheCreationRatio
info
[
"cache_creation_ratio"
]
=
cacheCreationRatio
...
...
service/quota.go
View file @
2a0bf7f9
...
@@ -94,6 +94,10 @@ func PreWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usag
...
@@ -94,6 +94,10 @@ func PreWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usag
audioInputTokens
:=
usage
.
InputTokenDetails
.
AudioTokens
audioInputTokens
:=
usage
.
InputTokenDetails
.
AudioTokens
audioOutTokens
:=
usage
.
OutputTokenDetails
.
AudioTokens
audioOutTokens
:=
usage
.
OutputTokenDetails
.
AudioTokens
groupRatio
:=
setting
.
GetGroupRatio
(
relayInfo
.
Group
)
groupRatio
:=
setting
.
GetGroupRatio
(
relayInfo
.
Group
)
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
relayInfo
.
UserGroup
,
relayInfo
.
Group
)
if
ok
{
groupRatio
=
userGroupRatio
}
modelRatio
,
_
:=
operation_setting
.
GetModelRatio
(
modelName
)
modelRatio
,
_
:=
operation_setting
.
GetModelRatio
(
modelName
)
quotaInfo
:=
QuotaInfo
{
quotaInfo
:=
QuotaInfo
{
...
@@ -145,6 +149,11 @@ func PostWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, mod
...
@@ -145,6 +149,11 @@ func PostWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, mod
audioRatio
:=
decimal
.
NewFromFloat
(
operation_setting
.
GetAudioRatio
(
relayInfo
.
OriginModelName
))
audioRatio
:=
decimal
.
NewFromFloat
(
operation_setting
.
GetAudioRatio
(
relayInfo
.
OriginModelName
))
audioCompletionRatio
:=
decimal
.
NewFromFloat
(
operation_setting
.
GetAudioCompletionRatio
(
modelName
))
audioCompletionRatio
:=
decimal
.
NewFromFloat
(
operation_setting
.
GetAudioCompletionRatio
(
modelName
))
actualGroupRatio
:=
groupRatio
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
relayInfo
.
UserGroup
,
relayInfo
.
Group
)
if
ok
{
actualGroupRatio
=
userGroupRatio
}
quotaInfo
:=
QuotaInfo
{
quotaInfo
:=
QuotaInfo
{
InputDetails
:
TokenDetails
{
InputDetails
:
TokenDetails
{
TextTokens
:
textInputTokens
,
TextTokens
:
textInputTokens
,
...
@@ -157,7 +166,7 @@ func PostWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, mod
...
@@ -157,7 +166,7 @@ func PostWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, mod
ModelName
:
modelName
,
ModelName
:
modelName
,
UsePrice
:
usePrice
,
UsePrice
:
usePrice
,
ModelRatio
:
modelRatio
,
ModelRatio
:
modelRatio
,
GroupRatio
:
g
roupRatio
,
GroupRatio
:
actualG
roupRatio
,
}
}
quota
:=
calculateAudioQuota
(
quotaInfo
)
quota
:=
calculateAudioQuota
(
quotaInfo
)
...
@@ -189,7 +198,7 @@ func PostWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, mod
...
@@ -189,7 +198,7 @@ func PostWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, mod
logContent
+=
", "
+
extraContent
logContent
+=
", "
+
extraContent
}
}
other
:=
GenerateWssOtherInfo
(
ctx
,
relayInfo
,
usage
,
modelRatio
,
groupRatio
,
other
:=
GenerateWssOtherInfo
(
ctx
,
relayInfo
,
usage
,
modelRatio
,
groupRatio
,
completionRatio
.
InexactFloat64
(),
audioRatio
.
InexactFloat64
(),
audioCompletionRatio
.
InexactFloat64
(),
modelPrice
)
completionRatio
.
InexactFloat64
(),
audioRatio
.
InexactFloat64
(),
audioCompletionRatio
.
InexactFloat64
(),
modelPrice
,
userGroupRatio
)
model
.
RecordConsumeLog
(
ctx
,
relayInfo
.
UserId
,
relayInfo
.
ChannelId
,
usage
.
InputTokens
,
usage
.
OutputTokens
,
logModel
,
model
.
RecordConsumeLog
(
ctx
,
relayInfo
.
UserId
,
relayInfo
.
ChannelId
,
usage
.
InputTokens
,
usage
.
OutputTokens
,
logModel
,
tokenName
,
quota
,
logContent
,
relayInfo
.
TokenId
,
userQuota
,
int
(
useTimeSeconds
),
relayInfo
.
IsStream
,
relayInfo
.
Group
,
other
)
tokenName
,
quota
,
logContent
,
relayInfo
.
TokenId
,
userQuota
,
int
(
useTimeSeconds
),
relayInfo
.
IsStream
,
relayInfo
.
Group
,
other
)
}
}
...
@@ -207,7 +216,7 @@ func PostClaudeConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
...
@@ -207,7 +216,7 @@ func PostClaudeConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
modelRatio
:=
priceData
.
ModelRatio
modelRatio
:=
priceData
.
ModelRatio
groupRatio
:=
priceData
.
GroupRatio
groupRatio
:=
priceData
.
GroupRatio
modelPrice
:=
priceData
.
ModelPrice
modelPrice
:=
priceData
.
ModelPrice
userGroupRatio
:=
priceData
.
UserGroupRatio
cacheRatio
:=
priceData
.
CacheRatio
cacheRatio
:=
priceData
.
CacheRatio
cacheTokens
:=
usage
.
PromptTokensDetails
.
CachedTokens
cacheTokens
:=
usage
.
PromptTokensDetails
.
CachedTokens
...
@@ -256,7 +265,7 @@ func PostClaudeConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
...
@@ -256,7 +265,7 @@ func PostClaudeConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
}
}
other
:=
GenerateClaudeOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
other
:=
GenerateClaudeOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
cacheTokens
,
cacheRatio
,
cacheCreationTokens
,
cacheCreationRatio
,
modelPrice
)
cacheTokens
,
cacheRatio
,
cacheCreationTokens
,
cacheCreationRatio
,
modelPrice
,
userGroupRatio
)
model
.
RecordConsumeLog
(
ctx
,
relayInfo
.
UserId
,
relayInfo
.
ChannelId
,
promptTokens
,
completionTokens
,
modelName
,
model
.
RecordConsumeLog
(
ctx
,
relayInfo
.
UserId
,
relayInfo
.
ChannelId
,
promptTokens
,
completionTokens
,
modelName
,
tokenName
,
quota
,
logContent
,
relayInfo
.
TokenId
,
userQuota
,
int
(
useTimeSeconds
),
relayInfo
.
IsStream
,
relayInfo
.
Group
,
other
)
tokenName
,
quota
,
logContent
,
relayInfo
.
TokenId
,
userQuota
,
int
(
useTimeSeconds
),
relayInfo
.
IsStream
,
relayInfo
.
Group
,
other
)
}
}
...
@@ -281,6 +290,12 @@ func PostAudioConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
...
@@ -281,6 +290,12 @@ func PostAudioConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
modelPrice
:=
priceData
.
ModelPrice
modelPrice
:=
priceData
.
ModelPrice
usePrice
:=
priceData
.
UsePrice
usePrice
:=
priceData
.
UsePrice
actualGroupRatio
:=
groupRatio
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
relayInfo
.
UserGroup
,
relayInfo
.
Group
)
if
ok
{
actualGroupRatio
=
userGroupRatio
}
quotaInfo
:=
QuotaInfo
{
quotaInfo
:=
QuotaInfo
{
InputDetails
:
TokenDetails
{
InputDetails
:
TokenDetails
{
TextTokens
:
textInputTokens
,
TextTokens
:
textInputTokens
,
...
@@ -293,7 +308,7 @@ func PostAudioConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
...
@@ -293,7 +308,7 @@ func PostAudioConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
ModelName
:
relayInfo
.
OriginModelName
,
ModelName
:
relayInfo
.
OriginModelName
,
UsePrice
:
usePrice
,
UsePrice
:
usePrice
,
ModelRatio
:
modelRatio
,
ModelRatio
:
modelRatio
,
GroupRatio
:
g
roupRatio
,
GroupRatio
:
actualG
roupRatio
,
}
}
quota
:=
calculateAudioQuota
(
quotaInfo
)
quota
:=
calculateAudioQuota
(
quotaInfo
)
...
@@ -333,7 +348,7 @@ func PostAudioConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
...
@@ -333,7 +348,7 @@ func PostAudioConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
logContent
+=
", "
+
extraContent
logContent
+=
", "
+
extraContent
}
}
other
:=
GenerateAudioOtherInfo
(
ctx
,
relayInfo
,
usage
,
modelRatio
,
groupRatio
,
other
:=
GenerateAudioOtherInfo
(
ctx
,
relayInfo
,
usage
,
modelRatio
,
groupRatio
,
completionRatio
.
InexactFloat64
(),
audioRatio
.
InexactFloat64
(),
audioCompletionRatio
.
InexactFloat64
(),
modelPrice
)
completionRatio
.
InexactFloat64
(),
audioRatio
.
InexactFloat64
(),
audioCompletionRatio
.
InexactFloat64
(),
modelPrice
,
userGroupRatio
)
model
.
RecordConsumeLog
(
ctx
,
relayInfo
.
UserId
,
relayInfo
.
ChannelId
,
usage
.
PromptTokens
,
usage
.
CompletionTokens
,
logModel
,
model
.
RecordConsumeLog
(
ctx
,
relayInfo
.
UserId
,
relayInfo
.
ChannelId
,
usage
.
PromptTokens
,
usage
.
CompletionTokens
,
logModel
,
tokenName
,
quota
,
logContent
,
relayInfo
.
TokenId
,
userQuota
,
int
(
useTimeSeconds
),
relayInfo
.
IsStream
,
relayInfo
.
Group
,
other
)
tokenName
,
quota
,
logContent
,
relayInfo
.
TokenId
,
userQuota
,
int
(
useTimeSeconds
),
relayInfo
.
IsStream
,
relayInfo
.
Group
,
other
)
}
}
...
...
setting/group_ratio.go
View file @
2a0bf7f9
...
@@ -14,6 +14,12 @@ var groupRatio = map[string]float64{
...
@@ -14,6 +14,12 @@ var groupRatio = map[string]float64{
}
}
var
groupRatioMutex
sync
.
RWMutex
var
groupRatioMutex
sync
.
RWMutex
var
GroupGroupRatio
=
map
[
string
]
map
[
string
]
float64
{
"vip"
:
{
"edit_this"
:
0.9
,
},
}
func
GetGroupRatioCopy
()
map
[
string
]
float64
{
func
GetGroupRatioCopy
()
map
[
string
]
float64
{
groupRatioMutex
.
RLock
()
groupRatioMutex
.
RLock
()
defer
groupRatioMutex
.
RUnlock
()
defer
groupRatioMutex
.
RUnlock
()
...
@@ -64,6 +70,31 @@ func GetGroupRatio(name string) float64 {
...
@@ -64,6 +70,31 @@ func GetGroupRatio(name string) float64 {
return
ratio
return
ratio
}
}
func
GetGroupGroupRatio
(
group
,
name
string
)
(
float64
,
bool
)
{
gp
,
ok
:=
GroupGroupRatio
[
group
]
if
!
ok
{
return
-
1
,
false
}
ratio
,
ok
:=
gp
[
name
]
if
!
ok
{
return
-
1
,
false
}
return
ratio
,
true
}
func
GroupGroupRatio2JSONString
()
string
{
jsonBytes
,
err
:=
json
.
Marshal
(
GroupGroupRatio
)
if
err
!=
nil
{
common
.
SysError
(
"error marshalling group-group ratio: "
+
err
.
Error
())
}
return
string
(
jsonBytes
)
}
func
UpdateGroupGroupRatioByJSONString
(
jsonStr
string
)
error
{
GroupGroupRatio
=
make
(
map
[
string
]
map
[
string
]
float64
)
return
json
.
Unmarshal
([]
byte
(
jsonStr
),
&
GroupGroupRatio
)
}
func
CheckGroupRatio
(
jsonStr
string
)
error
{
func
CheckGroupRatio
(
jsonStr
string
)
error
{
checkGroupRatio
:=
make
(
map
[
string
]
float64
)
checkGroupRatio
:=
make
(
map
[
string
]
float64
)
err
:=
json
.
Unmarshal
([]
byte
(
jsonStr
),
&
checkGroupRatio
)
err
:=
json
.
Unmarshal
([]
byte
(
jsonStr
),
&
checkGroupRatio
)
...
...
web/src/components/settings/OperationSetting.js
View file @
2a0bf7f9
...
@@ -30,6 +30,7 @@ const OperationSetting = () => {
...
@@ -30,6 +30,7 @@ const OperationSetting = () => {
CompletionRatio
:
''
,
CompletionRatio
:
''
,
ModelPrice
:
''
,
ModelPrice
:
''
,
GroupRatio
:
''
,
GroupRatio
:
''
,
GroupGroupRatio
:
''
,
UserUsableGroups
:
''
,
UserUsableGroups
:
''
,
TopUpLink
:
''
,
TopUpLink
:
''
,
'general_setting.docs_link'
:
''
,
'general_setting.docs_link'
:
''
,
...
@@ -74,6 +75,7 @@ const OperationSetting = () => {
...
@@ -74,6 +75,7 @@ const OperationSetting = () => {
if
(
if
(
item
.
key
===
'ModelRatio'
||
item
.
key
===
'ModelRatio'
||
item
.
key
===
'GroupRatio'
||
item
.
key
===
'GroupRatio'
||
item
.
key
===
'GroupGroupRatio'
||
item
.
key
===
'UserUsableGroups'
||
item
.
key
===
'UserUsableGroups'
||
item
.
key
===
'CompletionRatio'
||
item
.
key
===
'CompletionRatio'
||
item
.
key
===
'ModelPrice'
||
item
.
key
===
'ModelPrice'
||
...
...
web/src/components/table/LogsTable.js
View file @
2a0bf7f9
...
@@ -20,7 +20,7 @@ import {
...
@@ -20,7 +20,7 @@ import {
renderQuota
,
renderQuota
,
stringToColor
,
stringToColor
,
getLogOther
,
getLogOther
,
renderModelTag
renderModelTag
,
}
from
'../../helpers'
;
}
from
'../../helpers'
;
import
{
import
{
...
@@ -39,11 +39,11 @@ import {
...
@@ -39,11 +39,11 @@ import {
Card
,
Card
,
Typography
,
Typography
,
Divider
,
Divider
,
Form
Form
,
}
from
'@douyinfe/semi-ui'
;
}
from
'@douyinfe/semi-ui'
;
import
{
import
{
IllustrationNoResult
,
IllustrationNoResult
,
IllustrationNoResultDark
IllustrationNoResultDark
,
}
from
'@douyinfe/semi-illustrations'
;
}
from
'@douyinfe/semi-illustrations'
;
import
{
ITEMS_PER_PAGE
}
from
'../../constants'
;
import
{
ITEMS_PER_PAGE
}
from
'../../constants'
;
import
Paragraph
from
'@douyinfe/semi-ui/lib/es/typography/paragraph'
;
import
Paragraph
from
'@douyinfe/semi-ui/lib/es/typography/paragraph'
;
...
@@ -192,7 +192,7 @@ const LogsTable = () => {
...
@@ -192,7 +192,7 @@ const LogsTable = () => {
if
(
!
modelMapped
)
{
if
(
!
modelMapped
)
{
return
renderModelTag
(
record
.
model_name
,
{
return
renderModelTag
(
record
.
model_name
,
{
onClick
:
(
event
)
=>
{
onClick
:
(
event
)
=>
{
copyText
(
event
,
record
.
model_name
).
then
((
r
)
=>
{
});
copyText
(
event
,
record
.
model_name
).
then
((
r
)
=>
{});
},
},
});
});
}
else
{
}
else
{
...
@@ -209,7 +209,7 @@ const LogsTable = () => {
...
@@ -209,7 +209,7 @@ const LogsTable = () => {
<
/Text
>
<
/Text
>
{
renderModelTag
(
record
.
model_name
,
{
{
renderModelTag
(
record
.
model_name
,
{
onClick
:
(
event
)
=>
{
onClick
:
(
event
)
=>
{
copyText
(
event
,
record
.
model_name
).
then
((
r
)
=>
{
});
copyText
(
event
,
record
.
model_name
).
then
((
r
)
=>
{});
},
},
})}
})}
<
/div
>
<
/div
>
...
@@ -220,7 +220,7 @@ const LogsTable = () => {
...
@@ -220,7 +220,7 @@ const LogsTable = () => {
{
renderModelTag
(
other
.
upstream_model_name
,
{
{
renderModelTag
(
other
.
upstream_model_name
,
{
onClick
:
(
event
)
=>
{
onClick
:
(
event
)
=>
{
copyText
(
event
,
other
.
upstream_model_name
).
then
(
copyText
(
event
,
other
.
upstream_model_name
).
then
(
(
r
)
=>
{
},
(
r
)
=>
{},
);
);
},
},
})}
})}
...
@@ -231,7 +231,7 @@ const LogsTable = () => {
...
@@ -231,7 +231,7 @@ const LogsTable = () => {
>
>
{
renderModelTag
(
record
.
model_name
,
{
{
renderModelTag
(
record
.
model_name
,
{
onClick
:
(
event
)
=>
{
onClick
:
(
event
)
=>
{
copyText
(
event
,
record
.
model_name
).
then
((
r
)
=>
{
});
copyText
(
event
,
record
.
model_name
).
then
((
r
)
=>
{});
},
},
suffixIcon
:
(
suffixIcon
:
(
<
Route
<
Route
...
@@ -601,6 +601,7 @@ const LogsTable = () => {
...
@@ -601,6 +601,7 @@ const LogsTable = () => {
other
.
model_ratio
,
other
.
model_ratio
,
other
.
model_price
,
other
.
model_price
,
other
.
group_ratio
,
other
.
group_ratio
,
other
?.
user_group_ratio
,
other
.
cache_tokens
||
0
,
other
.
cache_tokens
||
0
,
other
.
cache_ratio
||
1.0
,
other
.
cache_ratio
||
1.0
,
other
.
cache_creation_tokens
||
0
,
other
.
cache_creation_tokens
||
0
,
...
@@ -610,6 +611,7 @@ const LogsTable = () => {
...
@@ -610,6 +611,7 @@ const LogsTable = () => {
other
.
model_ratio
,
other
.
model_ratio
,
other
.
model_price
,
other
.
model_price
,
other
.
group_ratio
,
other
.
group_ratio
,
other
?.
user_group_ratio
,
other
.
cache_tokens
||
0
,
other
.
cache_tokens
||
0
,
other
.
cache_ratio
||
1.0
,
other
.
cache_ratio
||
1.0
,
);
);
...
@@ -742,7 +744,7 @@ const LogsTable = () => {
...
@@ -742,7 +744,7 @@ const LogsTable = () => {
group
:
''
,
group
:
''
,
dateRange
:
[
dateRange
:
[
timestamp2string
(
getTodayStartTimestamp
()),
timestamp2string
(
getTodayStartTimestamp
()),
timestamp2string
(
now
.
getTime
()
/
1000
+
3600
)
timestamp2string
(
now
.
getTime
()
/
1000
+
3600
)
,
],
],
logType
:
'0'
,
logType
:
'0'
,
};
};
...
@@ -763,7 +765,11 @@ const LogsTable = () => {
...
@@ -763,7 +765,11 @@ const LogsTable = () => {
let
start_timestamp
=
timestamp2string
(
getTodayStartTimestamp
());
let
start_timestamp
=
timestamp2string
(
getTodayStartTimestamp
());
let
end_timestamp
=
timestamp2string
(
now
.
getTime
()
/
1000
+
3600
);
let
end_timestamp
=
timestamp2string
(
now
.
getTime
()
/
1000
+
3600
);
if
(
formValues
.
dateRange
&&
Array
.
isArray
(
formValues
.
dateRange
)
&&
formValues
.
dateRange
.
length
===
2
)
{
if
(
formValues
.
dateRange
&&
Array
.
isArray
(
formValues
.
dateRange
)
&&
formValues
.
dateRange
.
length
===
2
)
{
start_timestamp
=
formValues
.
dateRange
[
0
];
start_timestamp
=
formValues
.
dateRange
[
0
];
end_timestamp
=
formValues
.
dateRange
[
1
];
end_timestamp
=
formValues
.
dateRange
[
1
];
}
}
...
@@ -945,6 +951,7 @@ const LogsTable = () => {
...
@@ -945,6 +951,7 @@ const LogsTable = () => {
other
.
completion_ratio
,
other
.
completion_ratio
,
other
.
model_price
,
other
.
model_price
,
other
.
group_ratio
,
other
.
group_ratio
,
other
?.
user_group_ratio
,
other
.
cache_ratio
||
1.0
,
other
.
cache_ratio
||
1.0
,
other
.
cache_creation_ratio
||
1.0
,
other
.
cache_creation_ratio
||
1.0
,
)
)
...
@@ -992,6 +999,7 @@ const LogsTable = () => {
...
@@ -992,6 +999,7 @@ const LogsTable = () => {
other
?.
audio_ratio
,
other
?.
audio_ratio
,
other
?.
audio_completion_ratio
,
other
?.
audio_completion_ratio
,
other
?.
group_ratio
,
other
?.
group_ratio
,
other
?.
user_group_ratio
,
other
?.
cache_tokens
||
0
,
other
?.
cache_tokens
||
0
,
other
?.
cache_ratio
||
1.0
,
other
?.
cache_ratio
||
1.0
,
);
);
...
@@ -1003,6 +1011,7 @@ const LogsTable = () => {
...
@@ -1003,6 +1011,7 @@ const LogsTable = () => {
other
.
model_price
,
other
.
model_price
,
other
.
completion_ratio
,
other
.
completion_ratio
,
other
.
group_ratio
,
other
.
group_ratio
,
other
?.
user_group_ratio
,
other
.
cache_tokens
||
0
,
other
.
cache_tokens
||
0
,
other
.
cache_ratio
||
1.0
,
other
.
cache_ratio
||
1.0
,
other
.
cache_creation_tokens
||
0
,
other
.
cache_creation_tokens
||
0
,
...
@@ -1016,6 +1025,7 @@ const LogsTable = () => {
...
@@ -1016,6 +1025,7 @@ const LogsTable = () => {
other
?.
model_price
,
other
?.
model_price
,
other
?.
completion_ratio
,
other
?.
completion_ratio
,
other
?.
group_ratio
,
other
?.
group_ratio
,
other
?.
user_group_ratio
,
other
?.
cache_tokens
||
0
,
other
?.
cache_tokens
||
0
,
other
?.
cache_ratio
||
1.0
,
other
?.
cache_ratio
||
1.0
,
other
?.
image
||
false
,
other
?.
image
||
false
,
...
@@ -1066,7 +1076,12 @@ const LogsTable = () => {
...
@@ -1066,7 +1076,12 @@ const LogsTable = () => {
}
=
getFormValues
();
}
=
getFormValues
();
// 使用传入的 logType 或者表单中的 logType 或者状态中的 logType
// 使用传入的 logType 或者表单中的 logType 或者状态中的 logType
const
currentLogType
=
customLogType
!==
null
?
customLogType
:
formLogType
!==
undefined
?
formLogType
:
logType
;
const
currentLogType
=
customLogType
!==
null
?
customLogType
:
formLogType
!==
undefined
?
formLogType
:
logType
;
let
localStartTimestamp
=
Date
.
parse
(
start_timestamp
)
/
1000
;
let
localStartTimestamp
=
Date
.
parse
(
start_timestamp
)
/
1000
;
let
localEndTimestamp
=
Date
.
parse
(
end_timestamp
)
/
1000
;
let
localEndTimestamp
=
Date
.
parse
(
end_timestamp
)
/
1000
;
...
@@ -1093,7 +1108,7 @@ const LogsTable = () => {
...
@@ -1093,7 +1108,7 @@ const LogsTable = () => {
const
handlePageChange
=
(
page
)
=>
{
const
handlePageChange
=
(
page
)
=>
{
setActivePage
(
page
);
setActivePage
(
page
);
loadLogs
(
page
,
pageSize
).
then
((
r
)
=>
{
});
// 不传入logType,让其从表单获取最新值
loadLogs
(
page
,
pageSize
).
then
((
r
)
=>
{});
// 不传入logType,让其从表单获取最新值
};
};
const
handlePageSizeChange
=
async
(
size
)
=>
{
const
handlePageSizeChange
=
async
(
size
)
=>
{
...
@@ -1208,9 +1223,9 @@ const LogsTable = () => {
...
@@ -1208,9 +1223,9 @@ const LogsTable = () => {
getFormApi
=
{(
api
)
=>
setFormApi
(
api
)}
getFormApi
=
{(
api
)
=>
setFormApi
(
api
)}
onSubmit
=
{
refresh
}
onSubmit
=
{
refresh
}
allowEmpty
=
{
true
}
allowEmpty
=
{
true
}
autoComplete
=
"off"
autoComplete
=
'off'
layout
=
"vertical"
layout
=
'vertical'
trigger
=
"change"
trigger
=
'change'
stopValidateWithError
=
{
false
}
stopValidateWithError
=
{
false
}
>
>
<
div
className
=
'flex flex-col gap-4'
>
<
div
className
=
'flex flex-col gap-4'
>
...
@@ -1294,12 +1309,24 @@ const LogsTable = () => {
...
@@ -1294,12 +1309,24 @@ const LogsTable = () => {
},
0
);
},
0
);
}}
}}
>
>
<
Form
.
Select
.
Option
value
=
'0'
>
{
t
(
'全部'
)}
<
/Form.Select.Option
>
<
Form
.
Select
.
Option
value
=
'0'
>
<
Form
.
Select
.
Option
value
=
'1'
>
{
t
(
'充值'
)}
<
/Form.Select.Option
>
{
t
(
'全部'
)}
<
Form
.
Select
.
Option
value
=
'2'
>
{
t
(
'消费'
)}
<
/Form.Select.Option
>
<
/Form.Select.Option
>
<
Form
.
Select
.
Option
value
=
'3'
>
{
t
(
'管理'
)}
<
/Form.Select.Option
>
<
Form
.
Select
.
Option
value
=
'1'
>
<
Form
.
Select
.
Option
value
=
'4'
>
{
t
(
'系统'
)}
<
/Form.Select.Option
>
{
t
(
'充值'
)}
<
Form
.
Select
.
Option
value
=
'5'
>
{
t
(
'错误'
)}
<
/Form.Select.Option
>
<
/Form.Select.Option
>
<
Form
.
Select
.
Option
value
=
'2'
>
{
t
(
'消费'
)}
<
/Form.Select.Option
>
<
Form
.
Select
.
Option
value
=
'3'
>
{
t
(
'管理'
)}
<
/Form.Select.Option
>
<
Form
.
Select
.
Option
value
=
'4'
>
{
t
(
'系统'
)}
<
/Form.Select.Option
>
<
Form
.
Select
.
Option
value
=
'5'
>
{
t
(
'错误'
)}
<
/Form.Select.Option
>
<
/Form.Select
>
<
/Form.Select
>
<
/div
>
<
/div
>
...
@@ -1351,7 +1378,8 @@ const LogsTable = () => {
...
@@ -1351,7 +1378,8 @@ const LogsTable = () => {
{...(
hasExpandableRows
()
&&
{
{...(
hasExpandableRows
()
&&
{
expandedRowRender
:
expandRowRender
,
expandedRowRender
:
expandRowRender
,
expandRowByClick
:
true
,
expandRowByClick
:
true
,
rowExpandable
:
(
record
)
=>
expandData
[
record
.
key
]
&&
expandData
[
record
.
key
].
length
>
0
rowExpandable
:
(
record
)
=>
expandData
[
record
.
key
]
&&
expandData
[
record
.
key
].
length
>
0
,
})}
})}
dataSource
=
{
logs
}
dataSource
=
{
logs
}
rowKey
=
'key'
rowKey
=
'key'
...
@@ -1361,8 +1389,12 @@ const LogsTable = () => {
...
@@ -1361,8 +1389,12 @@ const LogsTable = () => {
size
=
'middle'
size
=
'middle'
empty
=
{
empty
=
{
<
Empty
<
Empty
image
=
{
<
IllustrationNoResult
style
=
{{
width
:
150
,
height
:
150
}}
/>
}
image
=
{
darkModeImage
=
{
<
IllustrationNoResultDark
style
=
{{
width
:
150
,
height
:
150
}}
/>
}
<
IllustrationNoResult
style
=
{{
width
:
150
,
height
:
150
}}
/
>
}
darkModeImage
=
{
<
IllustrationNoResultDark
style
=
{{
width
:
150
,
height
:
150
}}
/
>
}
description
=
{
t
(
'搜索无结果'
)}
description
=
{
t
(
'搜索无结果'
)}
style
=
{{
padding
:
30
}}
style
=
{{
padding
:
30
}}
/
>
/
>
...
...
web/src/helpers/render.js
View file @
2a0bf7f9
...
@@ -30,7 +30,7 @@ import {
...
@@ -30,7 +30,7 @@ import {
Dify
,
Dify
,
Coze
,
Coze
,
SiliconCloud
,
SiliconCloud
,
FastGPT
FastGPT
,
}
from
'@lobehub/icons'
;
}
from
'@lobehub/icons'
;
import
{
import
{
...
@@ -46,7 +46,7 @@ import {
...
@@ -46,7 +46,7 @@ import {
Gift
,
Gift
,
User
,
User
,
Settings
,
Settings
,
CircleUser
CircleUser
,
}
from
'lucide-react'
;
}
from
'lucide-react'
;
// 侧边栏图标颜色映射
// 侧边栏图标颜色映射
...
@@ -315,7 +315,6 @@ export const getModelCategories = (() => {
...
@@ -315,7 +315,6 @@ export const getModelCategories = (() => {
};
};
})();
})();
/**
/**
* 根据渠道类型返回对应的厂商图标
* 根据渠道类型返回对应的厂商图标
* @param {number} channelType - 渠道类型值
* @param {number} channelType - 渠道类型值
...
@@ -868,6 +867,10 @@ export function renderQuota(quota, digits = 2) {
...
@@ -868,6 +867,10 @@ export function renderQuota(quota, digits = 2) {
return
renderNumber
(
quota
);
return
renderNumber
(
quota
);
}
}
function
isValidGroupRatio
(
ratio
)
{
return
ratio
!==
undefined
&&
ratio
!==
null
&&
ratio
!==
-
1
;
}
export
function
renderModelPrice
(
export
function
renderModelPrice
(
inputTokens
,
inputTokens
,
completionTokens
,
completionTokens
,
...
@@ -875,6 +878,7 @@ export function renderModelPrice(
...
@@ -875,6 +878,7 @@ export function renderModelPrice(
modelPrice
=
-
1
,
modelPrice
=
-
1
,
completionRatio
,
completionRatio
,
groupRatio
,
groupRatio
,
user_group_ratio
,
cacheTokens
=
0
,
cacheTokens
=
0
,
cacheRatio
=
1.0
,
cacheRatio
=
1.0
,
image
=
false
,
image
=
false
,
...
@@ -890,13 +894,19 @@ export function renderModelPrice(
...
@@ -890,13 +894,19 @@ export function renderModelPrice(
audioInputTokens
=
0
,
audioInputTokens
=
0
,
audioInputPrice
=
0
,
audioInputPrice
=
0
,
)
{
)
{
const
useUserGroupRatio
=
isValidGroupRatio
(
user_group_ratio
);
const
ratioLabel
=
useUserGroupRatio
?
i18next
.
t
(
'专属倍率'
)
:
i18next
.
t
(
'分组倍率'
);
groupRatio
=
useUserGroupRatio
?
user_group_ratio
:
groupRatio
;
if
(
modelPrice
!==
-
1
)
{
if
(
modelPrice
!==
-
1
)
{
return
i18next
.
t
(
return
i18next
.
t
(
'模型价格:${{price}} *
分组倍率
:{{ratio}} = ${{total}}'
,
'模型价格:${{price}} *
{{ratioType}}
:{{ratio}} = ${{total}}'
,
{
{
price
:
modelPrice
,
price
:
modelPrice
,
ratio
:
groupRatio
,
ratio
:
groupRatio
,
total
:
modelPrice
*
groupRatio
,
total
:
modelPrice
*
groupRatio
,
ratioType
:
ratioLabel
,
},
},
);
);
}
else
{
}
else
{
...
@@ -1033,11 +1043,12 @@ export function renderModelPrice(
...
@@ -1033,11 +1043,12 @@ export function renderModelPrice(
// 构建输出部分描述
// 构建输出部分描述
const
outputDesc
=
i18next
.
t
(
const
outputDesc
=
i18next
.
t
(
'输出 {{completion}} tokens / 1M tokens * ${{compPrice}}) *
分组倍率
{{ratio}}'
,
'输出 {{completion}} tokens / 1M tokens * ${{compPrice}}) *
{{ratioType}}
{{ratio}}'
,
{
{
completion
:
completionTokens
,
completion
:
completionTokens
,
compPrice
:
completionRatioPrice
,
compPrice
:
completionRatioPrice
,
ratio
:
groupRatio
,
ratio
:
groupRatio
,
ratioType
:
ratioLabel
,
},
},
);
);
...
@@ -1045,21 +1056,23 @@ export function renderModelPrice(
...
@@ -1045,21 +1056,23 @@ export function renderModelPrice(
const
extraServices
=
[
const
extraServices
=
[
webSearch
&&
webSearchCallCount
>
0
webSearch
&&
webSearchCallCount
>
0
?
i18next
.
t
(
?
i18next
.
t
(
' + Web搜索 {{count}}次 / 1K 次 * ${{price}} * 分组倍率
{{ratio}}'
,
' + Web搜索 {{count}}次 / 1K 次 * ${{price}} * {{ratioType}}
{{ratio}}'
,
{
{
count
:
webSearchCallCount
,
count
:
webSearchCallCount
,
price
:
webSearchPrice
,
price
:
webSearchPrice
,
ratio
:
groupRatio
,
ratio
:
groupRatio
,
ratioType
:
ratioLabel
,
},
},
)
)
:
''
,
:
''
,
fileSearch
&&
fileSearchCallCount
>
0
fileSearch
&&
fileSearchCallCount
>
0
?
i18next
.
t
(
?
i18next
.
t
(
' + 文件搜索 {{count}}次 / 1K 次 * ${{price}} * 分组倍率
{{ratio}}'
,
' + 文件搜索 {{count}}次 / 1K 次 * ${{price}} * {{ratioType}}
{{ratio}}'
,
{
{
count
:
fileSearchCallCount
,
count
:
fileSearchCallCount
,
price
:
fileSearchPrice
,
price
:
fileSearchPrice
,
ratio
:
groupRatio
,
ratio
:
groupRatio
,
ratioType
:
ratioLabel
,
},
},
)
)
:
''
,
:
''
,
...
@@ -1097,6 +1110,7 @@ export function renderLogContent(
...
@@ -1097,6 +1110,7 @@ export function renderLogContent(
fileSearch
=
false
,
fileSearch
=
false
,
fileSearchCallCount
=
0
,
fileSearchCallCount
=
0
,
)
{
)
{
useUserGroupRatio
=
isValidGroupRatio
(
user_group_ratio
);
const
ratioLabel
=
useUserGroupRatio
const
ratioLabel
=
useUserGroupRatio
?
i18next
.
t
(
'专属倍率'
)
?
i18next
.
t
(
'专属倍率'
)
:
i18next
.
t
(
'分组倍率'
);
:
i18next
.
t
(
'分组倍率'
);
...
@@ -1149,14 +1163,21 @@ export function renderModelPriceSimple(
...
@@ -1149,14 +1163,21 @@ export function renderModelPriceSimple(
modelRatio
,
modelRatio
,
modelPrice
=
-
1
,
modelPrice
=
-
1
,
groupRatio
,
groupRatio
,
user_group_ratio
,
cacheTokens
=
0
,
cacheTokens
=
0
,
cacheRatio
=
1.0
,
cacheRatio
=
1.0
,
image
=
false
,
image
=
false
,
imageRatio
=
1.0
,
imageRatio
=
1.0
,
)
{
)
{
const
useUserGroupRatio
=
isValidGroupRatio
(
user_group_ratio
);
const
ratioLabel
=
useUserGroupRatio
?
i18next
.
t
(
'专属倍率'
)
:
i18next
.
t
(
'分组倍率'
);
groupRatio
=
useUserGroupRatio
?
user_group_ratio
:
groupRatio
;
if
(
modelPrice
!==
-
1
)
{
if
(
modelPrice
!==
-
1
)
{
return
i18next
.
t
(
'价格:${{price}} *
分组
:{{ratio}}'
,
{
return
i18next
.
t
(
'价格:${{price}} *
{{ratioType}}
:{{ratio}}'
,
{
price
:
modelPrice
,
price
:
modelPrice
,
ratioType
:
ratioLabel
,
ratio
:
groupRatio
,
ratio
:
groupRatio
,
});
});
}
else
{
}
else
{
...
@@ -1191,8 +1212,9 @@ export function renderModelPriceSimple(
...
@@ -1191,8 +1212,9 @@ export function renderModelPriceSimple(
},
},
);
);
}
else
{
}
else
{
return
i18next
.
t
(
'模型: {{ratio}} *
分组:
{{groupRatio}}'
,
{
return
i18next
.
t
(
'模型: {{ratio}} *
{{ratioType}}:
{{groupRatio}}'
,
{
ratio
:
modelRatio
,
ratio
:
modelRatio
,
ratioType
:
ratioLabel
,
groupRatio
:
groupRatio
,
groupRatio
:
groupRatio
,
});
});
}
}
...
@@ -1210,17 +1232,24 @@ export function renderAudioModelPrice(
...
@@ -1210,17 +1232,24 @@ export function renderAudioModelPrice(
audioRatio
,
audioRatio
,
audioCompletionRatio
,
audioCompletionRatio
,
groupRatio
,
groupRatio
,
user_group_ratio
,
cacheTokens
=
0
,
cacheTokens
=
0
,
cacheRatio
=
1.0
,
cacheRatio
=
1.0
,
)
{
)
{
const
useUserGroupRatio
=
isValidGroupRatio
(
user_group_ratio
);
const
ratioLabel
=
useUserGroupRatio
?
i18next
.
t
(
'专属倍率'
)
:
i18next
.
t
(
'分组倍率'
);
groupRatio
=
useUserGroupRatio
?
user_group_ratio
:
groupRatio
;
// 1 ratio = $0.002 / 1K tokens
// 1 ratio = $0.002 / 1K tokens
if
(
modelPrice
!==
-
1
)
{
if
(
modelPrice
!==
-
1
)
{
return
i18next
.
t
(
return
i18next
.
t
(
'模型价格:${{price}} *
分组倍率
:{{ratio}} = ${{total}}'
,
'模型价格:${{price}} *
{{ratioType}}
:{{ratio}} = ${{total}}'
,
{
{
price
:
modelPrice
,
price
:
modelPrice
,
ratio
:
groupRatio
,
ratio
:
groupRatio
,
total
:
modelPrice
*
groupRatio
,
total
:
modelPrice
*
groupRatio
,
ratioType
:
ratioLabel
,
},
},
);
);
}
else
{
}
else
{
...
@@ -1374,12 +1403,17 @@ export function renderClaudeModelPrice(
...
@@ -1374,12 +1403,17 @@ export function renderClaudeModelPrice(
modelPrice
=
-
1
,
modelPrice
=
-
1
,
completionRatio
,
completionRatio
,
groupRatio
,
groupRatio
,
user_group_ratio
,
cacheTokens
=
0
,
cacheTokens
=
0
,
cacheRatio
=
1.0
,
cacheRatio
=
1.0
,
cacheCreationTokens
=
0
,
cacheCreationTokens
=
0
,
cacheCreationRatio
=
1.0
,
cacheCreationRatio
=
1.0
,
)
{
)
{
const
ratioLabel
=
false
?
i18next
.
t
(
'专属倍率'
)
:
i18next
.
t
(
'分组倍率'
);
const
useUserGroupRatio
=
isValidGroupRatio
(
user_group_ratio
);
const
ratioLabel
=
useUserGroupRatio
?
i18next
.
t
(
'专属倍率'
)
:
i18next
.
t
(
'分组倍率'
);
groupRatio
=
useUserGroupRatio
?
user_group_ratio
:
groupRatio
;
if
(
modelPrice
!==
-
1
)
{
if
(
modelPrice
!==
-
1
)
{
return
i18next
.
t
(
return
i18next
.
t
(
...
@@ -1461,7 +1495,7 @@ export function renderClaudeModelPrice(
...
@@ -1461,7 +1495,7 @@ export function renderClaudeModelPrice(
<
p
>
<
p
>
{
cacheTokens
>
0
||
cacheCreationTokens
>
0
{
cacheTokens
>
0
||
cacheCreationTokens
>
0
?
i18next
.
t
(
?
i18next
.
t
(
'提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * ${{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组
{{ratio}} = ${{total}}'
,
'提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * ${{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * {{ratioType}}
{{ratio}} = ${{total}}'
,
{
{
nonCacheInput
:
nonCachedTokens
,
nonCacheInput
:
nonCachedTokens
,
cacheInput
:
cacheTokens
,
cacheInput
:
cacheTokens
,
...
@@ -1474,17 +1508,19 @@ export function renderClaudeModelPrice(
...
@@ -1474,17 +1508,19 @@ export function renderClaudeModelPrice(
completion
:
completionTokens
,
completion
:
completionTokens
,
compPrice
:
completionRatioPrice
,
compPrice
:
completionRatioPrice
,
ratio
:
groupRatio
,
ratio
:
groupRatio
,
ratioType
:
ratioLabel
,
total
:
price
.
toFixed
(
6
),
total
:
price
.
toFixed
(
6
),
},
},
)
)
:
i18next
.
t
(
:
i18next
.
t
(
'提示 {{input}} tokens / 1M tokens * ${{price}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组
{{ratio}} = ${{total}}'
,
'提示 {{input}} tokens / 1M tokens * ${{price}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * {{ratioType}}
{{ratio}} = ${{total}}'
,
{
{
input
:
inputTokens
,
input
:
inputTokens
,
price
:
inputRatioPrice
,
price
:
inputRatioPrice
,
completion
:
completionTokens
,
completion
:
completionTokens
,
compPrice
:
completionRatioPrice
,
compPrice
:
completionRatioPrice
,
ratio
:
groupRatio
,
ratio
:
groupRatio
,
ratioType
:
ratioLabel
,
total
:
price
.
toFixed
(
6
),
total
:
price
.
toFixed
(
6
),
},
},
)}
)}
...
@@ -1501,10 +1537,15 @@ export function renderClaudeLogContent(
...
@@ -1501,10 +1537,15 @@ export function renderClaudeLogContent(
completionRatio
,
completionRatio
,
modelPrice
=
-
1
,
modelPrice
=
-
1
,
groupRatio
,
groupRatio
,
user_group_ratio
,
cacheRatio
=
1.0
,
cacheRatio
=
1.0
,
cacheCreationRatio
=
1.0
,
cacheCreationRatio
=
1.0
,
)
{
)
{
const
ratioLabel
=
false
?
i18next
.
t
(
'专属倍率'
)
:
i18next
.
t
(
'分组倍率'
);
const
useUserGroupRatio
=
isValidGroupRatio
(
user_group_ratio
);
const
ratioLabel
=
useUserGroupRatio
?
i18next
.
t
(
'专属倍率'
)
:
i18next
.
t
(
'分组倍率'
);
groupRatio
=
useUserGroupRatio
?
user_group_ratio
:
groupRatio
;
if
(
modelPrice
!==
-
1
)
{
if
(
modelPrice
!==
-
1
)
{
return
i18next
.
t
(
'模型价格 ${{price}},{{ratioType}} {{ratio}}'
,
{
return
i18next
.
t
(
'模型价格 ${{price}},{{ratioType}} {{ratio}}'
,
{
...
@@ -1531,12 +1572,17 @@ export function renderClaudeModelPriceSimple(
...
@@ -1531,12 +1572,17 @@ export function renderClaudeModelPriceSimple(
modelRatio
,
modelRatio
,
modelPrice
=
-
1
,
modelPrice
=
-
1
,
groupRatio
,
groupRatio
,
user_group_ratio
,
cacheTokens
=
0
,
cacheTokens
=
0
,
cacheRatio
=
1.0
,
cacheRatio
=
1.0
,
cacheCreationTokens
=
0
,
cacheCreationTokens
=
0
,
cacheCreationRatio
=
1.0
,
cacheCreationRatio
=
1.0
,
)
{
)
{
const
ratioLabel
=
false
?
i18next
.
t
(
'专属倍率'
)
:
i18next
.
t
(
'分组'
);
const
useUserGroupRatio
=
isValidGroupRatio
(
user_group_ratio
);
const
ratioLabel
=
useUserGroupRatio
?
i18next
.
t
(
'专属倍率'
)
:
i18next
.
t
(
'分组倍率'
);
groupRatio
=
useUserGroupRatio
?
user_group_ratio
:
groupRatio
;
if
(
modelPrice
!==
-
1
)
{
if
(
modelPrice
!==
-
1
)
{
return
i18next
.
t
(
'价格:${{price}} * {{ratioType}}:{{ratio}}'
,
{
return
i18next
.
t
(
'价格:${{price}} * {{ratioType}}:{{ratio}}'
,
{
...
...
web/src/pages/Setting/Operation/GroupRatioSettings.js
View file @
2a0bf7f9
...
@@ -16,6 +16,7 @@ export default function GroupRatioSettings(props) {
...
@@ -16,6 +16,7 @@ export default function GroupRatioSettings(props) {
const
[
inputs
,
setInputs
]
=
useState
({
const
[
inputs
,
setInputs
]
=
useState
({
GroupRatio
:
''
,
GroupRatio
:
''
,
UserUsableGroups
:
''
,
UserUsableGroups
:
''
,
GroupGroupRatio
:
''
,
});
});
const
refForm
=
useRef
();
const
refForm
=
useRef
();
const
[
inputsRow
,
setInputsRow
]
=
useState
(
inputs
);
const
[
inputsRow
,
setInputsRow
]
=
useState
(
inputs
);
...
@@ -136,6 +137,27 @@ export default function GroupRatioSettings(props) {
...
@@ -136,6 +137,27 @@ export default function GroupRatioSettings(props) {
/
>
/
>
<
/Col
>
<
/Col
>
<
/Row
>
<
/Row
>
<
Row
gutter
=
{
16
}
>
<
Col
xs
=
{
24
}
sm
=
{
16
}
>
<
Form
.
TextArea
label
=
{
t
(
'分组特殊倍率'
)}
placeholder
=
{
t
(
'为一个 JSON 文本'
)}
field
=
{
'GroupGroupRatio'
}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
trigger
=
'blur'
stopValidateWithError
rules
=
{[
{
validator
:
(
rule
,
value
)
=>
verifyJSON
(
value
),
message
:
t
(
'不是合法的 JSON 字符串'
),
},
]}
onChange
=
{(
value
)
=>
setInputs
({
...
inputs
,
GroupGroupRatio
:
value
})
}
/
>
<
/Col
>
<
/Row
>
<
/Form.Section
>
<
/Form.Section
>
<
/Form
>
<
/Form
>
<
Button
onClick
=
{
onSubmit
}
>
{
t
(
'保存分组倍率设置'
)}
<
/Button
>
<
Button
onClick
=
{
onSubmit
}
>
{
t
(
'保存分组倍率设置'
)}
<
/Button
>
...
...
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