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
158d621f
authored
Jun 13, 2025
by
Calcium-Ion
Committed by
GitHub
Jun 13, 2025
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1207 from QuantumNous/user_group_ratio
feat: 分组特殊倍率
parents
b1176d02
0e974418
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
346 additions
and
159 deletions
+346
-159
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
+48
-5
web/src/components/settings/OperationSetting.js
+2
-0
web/src/components/table/LogsTable.js
+88
-57
web/src/helpers/render.js
+124
-80
web/src/pages/Setting/Operation/GroupRatioSettings.js
+31
-0
No files found.
controller/channel-test.go
View file @
158d621f
...
@@ -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 @
158d621f
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 @
158d621f
...
@@ -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
...
@@ -357,6 +358,8 @@ func updateOptionMap(key string, value string) (err error) {
...
@@ -357,6 +358,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 @
158d621f
...
@@ -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 @
158d621f
...
@@ -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 @
158d621f
...
@@ -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 @
158d621f
...
@@ -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 @
158d621f
...
@@ -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 @
158d621f
...
@@ -14,10 +14,19 @@ var groupRatio = map[string]float64{
...
@@ -14,10 +14,19 @@ 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
,
},
}
groupGroupRatioMutex
sync
.
RWMutex
)
func
GetGroupRatioCopy
()
map
[
string
]
float64
{
func
GetGroupRatioCopy
()
map
[
string
]
float64
{
groupRatioMutex
.
RLock
()
groupRatioMutex
.
RLock
()
defer
groupRatioMutex
.
RUnlock
()
defer
groupRatioMutex
.
RUnlock
()
groupRatioCopy
:=
make
(
map
[
string
]
float64
)
groupRatioCopy
:=
make
(
map
[
string
]
float64
)
for
k
,
v
:=
range
groupRatio
{
for
k
,
v
:=
range
groupRatio
{
groupRatioCopy
[
k
]
=
v
groupRatioCopy
[
k
]
=
v
...
@@ -28,7 +37,7 @@ func GetGroupRatioCopy() map[string]float64 {
...
@@ -28,7 +37,7 @@ func GetGroupRatioCopy() map[string]float64 {
func
ContainsGroupRatio
(
name
string
)
bool
{
func
ContainsGroupRatio
(
name
string
)
bool
{
groupRatioMutex
.
RLock
()
groupRatioMutex
.
RLock
()
defer
groupRatioMutex
.
RUnlock
()
defer
groupRatioMutex
.
RUnlock
()
_
,
ok
:=
groupRatio
[
name
]
_
,
ok
:=
groupRatio
[
name
]
return
ok
return
ok
}
}
...
@@ -36,7 +45,7 @@ func ContainsGroupRatio(name string) bool {
...
@@ -36,7 +45,7 @@ func ContainsGroupRatio(name string) bool {
func
GroupRatio2JSONString
()
string
{
func
GroupRatio2JSONString
()
string
{
groupRatioMutex
.
RLock
()
groupRatioMutex
.
RLock
()
defer
groupRatioMutex
.
RUnlock
()
defer
groupRatioMutex
.
RUnlock
()
jsonBytes
,
err
:=
json
.
Marshal
(
groupRatio
)
jsonBytes
,
err
:=
json
.
Marshal
(
groupRatio
)
if
err
!=
nil
{
if
err
!=
nil
{
common
.
SysError
(
"error marshalling model ratio: "
+
err
.
Error
())
common
.
SysError
(
"error marshalling model ratio: "
+
err
.
Error
())
...
@@ -47,7 +56,7 @@ func GroupRatio2JSONString() string {
...
@@ -47,7 +56,7 @@ func GroupRatio2JSONString() string {
func
UpdateGroupRatioByJSONString
(
jsonStr
string
)
error
{
func
UpdateGroupRatioByJSONString
(
jsonStr
string
)
error
{
groupRatioMutex
.
Lock
()
groupRatioMutex
.
Lock
()
defer
groupRatioMutex
.
Unlock
()
defer
groupRatioMutex
.
Unlock
()
groupRatio
=
make
(
map
[
string
]
float64
)
groupRatio
=
make
(
map
[
string
]
float64
)
return
json
.
Unmarshal
([]
byte
(
jsonStr
),
&
groupRatio
)
return
json
.
Unmarshal
([]
byte
(
jsonStr
),
&
groupRatio
)
}
}
...
@@ -55,7 +64,7 @@ func UpdateGroupRatioByJSONString(jsonStr string) error {
...
@@ -55,7 +64,7 @@ func UpdateGroupRatioByJSONString(jsonStr string) error {
func
GetGroupRatio
(
name
string
)
float64
{
func
GetGroupRatio
(
name
string
)
float64
{
groupRatioMutex
.
RLock
()
groupRatioMutex
.
RLock
()
defer
groupRatioMutex
.
RUnlock
()
defer
groupRatioMutex
.
RUnlock
()
ratio
,
ok
:=
groupRatio
[
name
]
ratio
,
ok
:=
groupRatio
[
name
]
if
!
ok
{
if
!
ok
{
common
.
SysError
(
"group ratio not found: "
+
name
)
common
.
SysError
(
"group ratio not found: "
+
name
)
...
@@ -64,6 +73,40 @@ func GetGroupRatio(name string) float64 {
...
@@ -64,6 +73,40 @@ func GetGroupRatio(name string) float64 {
return
ratio
return
ratio
}
}
func
GetGroupGroupRatio
(
group
,
name
string
)
(
float64
,
bool
)
{
groupGroupRatioMutex
.
RLock
()
defer
groupGroupRatioMutex
.
RUnlock
()
gp
,
ok
:=
GroupGroupRatio
[
group
]
if
!
ok
{
return
-
1
,
false
}
ratio
,
ok
:=
gp
[
name
]
if
!
ok
{
return
-
1
,
false
}
return
ratio
,
true
}
func
GroupGroupRatio2JSONString
()
string
{
groupGroupRatioMutex
.
RLock
()
defer
groupGroupRatioMutex
.
RUnlock
()
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
{
groupGroupRatioMutex
.
Lock
()
defer
groupGroupRatioMutex
.
Unlock
()
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 @
158d621f
...
@@ -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 @
158d621f
...
@@ -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
...
@@ -598,21 +598,23 @@ const LogsTable = () => {
...
@@ -598,21 +598,23 @@ const LogsTable = () => {
}
}
let
content
=
other
?.
claude
let
content
=
other
?.
claude
?
renderClaudeModelPriceSimple
(
?
renderClaudeModelPriceSimple
(
other
.
model_ratio
,
other
.
model_ratio
,
other
.
model_price
,
other
.
model_price
,
other
.
group_ratio
,
other
.
group_ratio
,
other
.
cache_tokens
||
0
,
other
?.
user_group_ratio
,
other
.
cache_ratio
||
1.0
,
other
.
cache_tokens
||
0
,
other
.
cache_creation_tokens
||
0
,
other
.
cache_ratio
||
1.0
,
other
.
cache_creation_ratio
||
1.0
,
other
.
cache_creation_tokens
||
0
,
)
other
.
cache_creation_ratio
||
1.0
,
)
:
renderModelPriceSimple
(
:
renderModelPriceSimple
(
other
.
model_ratio
,
other
.
model_ratio
,
other
.
model_price
,
other
.
model_price
,
other
.
group_ratio
,
other
.
group_ratio
,
other
.
cache_tokens
||
0
,
other
?.
user_group_ratio
,
other
.
cache_ratio
||
1.0
,
other
.
cache_tokens
||
0
,
);
other
.
cache_ratio
||
1.0
,
);
return
(
return
(
<
Paragraph
<
Paragraph
ellipsis
=
{{
ellipsis
=
{{
...
@@ -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
];
}
}
...
@@ -941,27 +947,27 @@ const LogsTable = () => {
...
@@ -941,27 +947,27 @@ const LogsTable = () => {
key
:
t
(
'日志详情'
),
key
:
t
(
'日志详情'
),
value
:
other
?.
claude
value
:
other
?.
claude
?
renderClaudeLogContent
(
?
renderClaudeLogContent
(
other
?.
model_ratio
,
other
?.
model_ratio
,
other
.
completion_ratio
,
other
.
completion_ratio
,
other
.
model_price
,
other
.
model_price
,
other
.
group_ratio
,
other
.
group_ratio
,
other
.
cache_ratio
||
1.0
,
other
?.
user_group_ratio
,
other
.
cache_creation_ratio
||
1.0
,
other
.
cache_ratio
||
1.0
,
)
other
.
cache_creation_ratio
||
1.0
,
)
:
renderLogContent
(
:
renderLogContent
(
other
?.
model_ratio
,
other
?.
model_ratio
,
other
.
completion_ratio
,
other
.
completion_ratio
,
other
.
model_price
,
other
.
model_price
,
other
.
group_ratio
,
other
.
group_ratio
,
other
?.
user_group_ratio
,
other
?.
user_group_ratio
,
false
,
false
,
1.0
,
1.0
,
undefined
,
other
.
web_search
||
false
,
other
.
web_search
||
false
,
other
.
web_search_call_count
||
0
,
other
.
web_search_call_count
||
0
,
other
.
file_search
||
false
,
other
.
file_search
||
false
,
other
.
file_search_call_count
||
0
,
other
.
file_search_call_count
||
0
,
),
),
});
});
}
}
if
(
logs
[
i
].
type
===
2
)
{
if
(
logs
[
i
].
type
===
2
)
{
...
@@ -992,6 +998,7 @@ const LogsTable = () => {
...
@@ -992,6 +998,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 +1010,7 @@ const LogsTable = () => {
...
@@ -1003,6 +1010,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 +1024,7 @@ const LogsTable = () => {
...
@@ -1016,6 +1024,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 +1075,12 @@ const LogsTable = () => {
...
@@ -1066,7 +1075,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 +1107,7 @@ const LogsTable = () => {
...
@@ -1093,7 +1107,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 +1222,9 @@ const LogsTable = () => {
...
@@ -1208,9 +1222,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 +1308,24 @@ const LogsTable = () => {
...
@@ -1294,12 +1308,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 +1377,8 @@ const LogsTable = () => {
...
@@ -1351,7 +1377,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 +1388,12 @@ const LogsTable = () => {
...
@@ -1361,8 +1388,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 @
158d621f
...
@@ -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,30 @@ export function renderQuota(quota, digits = 2) {
...
@@ -868,6 +867,30 @@ export function renderQuota(quota, digits = 2) {
return
renderNumber
(
quota
);
return
renderNumber
(
quota
);
}
}
function
isValidGroupRatio
(
ratio
)
{
return
Number
.
isFinite
(
ratio
)
&&
ratio
!==
-
1
;
}
/**
* Helper function to get effective ratio and label
* @param {number} groupRatio - The default group ratio
* @param {number} user_group_ratio - The user-specific group ratio
* @returns {Object} - Object containing { ratio, label, useUserGroupRatio }
*/
function
getEffectiveRatio
(
groupRatio
,
user_group_ratio
)
{
const
useUserGroupRatio
=
isValidGroupRatio
(
user_group_ratio
);
const
ratioLabel
=
useUserGroupRatio
?
i18next
.
t
(
'专属倍率'
)
:
i18next
.
t
(
'分组倍率'
);
const
effectiveRatio
=
useUserGroupRatio
?
user_group_ratio
:
groupRatio
;
return
{
ratio
:
effectiveRatio
,
label
:
ratioLabel
,
useUserGroupRatio
:
useUserGroupRatio
};
}
export
function
renderModelPrice
(
export
function
renderModelPrice
(
inputTokens
,
inputTokens
,
completionTokens
,
completionTokens
,
...
@@ -875,6 +898,7 @@ export function renderModelPrice(
...
@@ -875,6 +898,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 +914,17 @@ export function renderModelPrice(
...
@@ -890,13 +914,17 @@ export function renderModelPrice(
audioInputTokens
=
0
,
audioInputTokens
=
0
,
audioInputPrice
=
0
,
audioInputPrice
=
0
,
)
{
)
{
const
{
ratio
:
effectiveGroupRatio
,
label
:
ratioLabel
}
=
getEffectiveRatio
(
groupRatio
,
user_group_ratio
);
groupRatio
=
effectiveGroupRatio
;
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 +1061,12 @@ export function renderModelPrice(
...
@@ -1033,11 +1061,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,23 +1074,25 @@ export function renderModelPrice(
...
@@ -1045,23 +1074,25 @@ 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
,
)
},
)
:
''
,
:
''
,
].
join
(
''
);
].
join
(
''
);
...
@@ -1091,16 +1122,12 @@ export function renderLogContent(
...
@@ -1091,16 +1122,12 @@ export function renderLogContent(
user_group_ratio
,
user_group_ratio
,
image
=
false
,
image
=
false
,
imageRatio
=
1.0
,
imageRatio
=
1.0
,
useUserGroupRatio
=
undefined
,
webSearch
=
false
,
webSearch
=
false
,
webSearchCallCount
=
0
,
webSearchCallCount
=
0
,
fileSearch
=
false
,
fileSearch
=
false
,
fileSearchCallCount
=
0
,
fileSearchCallCount
=
0
,
)
{
)
{
const
ratioLabel
=
useUserGroupRatio
const
{
ratio
,
label
:
ratioLabel
,
useUserGroupRatio
:
useUserGroupRatio
}
=
getEffectiveRatio
(
groupRatio
,
user_group_ratio
);
?
i18next
.
t
(
'专属倍率'
)
:
i18next
.
t
(
'分组倍率'
);
const
ratio
=
useUserGroupRatio
?
user_group_ratio
:
groupRatio
;
if
(
modelPrice
!==
-
1
)
{
if
(
modelPrice
!==
-
1
)
{
return
i18next
.
t
(
'模型价格 ${{price}},{{ratioType}} {{ratio}}'
,
{
return
i18next
.
t
(
'模型价格 ${{price}},{{ratioType}} {{ratio}}'
,
{
...
@@ -1149,14 +1176,18 @@ export function renderModelPriceSimple(
...
@@ -1149,14 +1176,18 @@ 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
{
ratio
:
effectiveGroupRatio
,
label
:
ratioLabel
}
=
getEffectiveRatio
(
groupRatio
,
user_group_ratio
);
groupRatio
=
effectiveGroupRatio
;
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 +1222,9 @@ export function renderModelPriceSimple(
...
@@ -1191,8 +1222,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 +1242,21 @@ export function renderAudioModelPrice(
...
@@ -1210,17 +1242,21 @@ export function renderAudioModelPrice(
audioRatio
,
audioRatio
,
audioCompletionRatio
,
audioCompletionRatio
,
groupRatio
,
groupRatio
,
user_group_ratio
,
cacheTokens
=
0
,
cacheTokens
=
0
,
cacheRatio
=
1.0
,
cacheRatio
=
1.0
,
)
{
)
{
const
{
ratio
:
effectiveGroupRatio
,
label
:
ratioLabel
}
=
getEffectiveRatio
(
groupRatio
,
user_group_ratio
);
groupRatio
=
effectiveGroupRatio
;
// 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
{
...
@@ -1245,10 +1281,10 @@ export function renderAudioModelPrice(
...
@@ -1245,10 +1281,10 @@ export function renderAudioModelPrice(
let
audioPrice
=
let
audioPrice
=
(
audioInputTokens
/
1000000
)
*
inputRatioPrice
*
audioRatio
*
groupRatio
+
(
audioInputTokens
/
1000000
)
*
inputRatioPrice
*
audioRatio
*
groupRatio
+
(
audioCompletionTokens
/
1000000
)
*
(
audioCompletionTokens
/
1000000
)
*
inputRatioPrice
*
inputRatioPrice
*
audioRatio
*
audioRatio
*
audioCompletionRatio
*
audioCompletionRatio
*
groupRatio
;
groupRatio
;
let
price
=
textPrice
+
audioPrice
;
let
price
=
textPrice
+
audioPrice
;
return
(
return
(
<>
<>
...
@@ -1304,27 +1340,27 @@ export function renderAudioModelPrice(
...
@@ -1304,27 +1340,27 @@ export function renderAudioModelPrice(
<
p
>
<
p
>
{
cacheTokens
>
0
{
cacheTokens
>
0
?
i18next
.
t
(
?
i18next
.
t
(
'文字提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}'
,
'文字提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}'
,
{
{
nonCacheInput
:
inputTokens
-
cacheTokens
,
nonCacheInput
:
inputTokens
-
cacheTokens
,
cacheInput
:
cacheTokens
,
cacheInput
:
cacheTokens
,
cachePrice
:
inputRatioPrice
*
cacheRatio
,
cachePrice
:
inputRatioPrice
*
cacheRatio
,
price
:
inputRatioPrice
,
price
:
inputRatioPrice
,
completion
:
completionTokens
,
completion
:
completionTokens
,
compPrice
:
completionRatioPrice
,
compPrice
:
completionRatioPrice
,
total
:
textPrice
.
toFixed
(
6
),
total
:
textPrice
.
toFixed
(
6
),
},
},
)
)
:
i18next
.
t
(
:
i18next
.
t
(
'文字提示 {{input}} tokens / 1M tokens * ${{price}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}'
,
'文字提示 {{input}} tokens / 1M tokens * ${{price}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}'
,
{
{
input
:
inputTokens
,
input
:
inputTokens
,
price
:
inputRatioPrice
,
price
:
inputRatioPrice
,
completion
:
completionTokens
,
completion
:
completionTokens
,
compPrice
:
completionRatioPrice
,
compPrice
:
completionRatioPrice
,
total
:
textPrice
.
toFixed
(
6
),
total
:
textPrice
.
toFixed
(
6
),
},
},
)}
)}
<
/p
>
<
/p
>
<
p
>
<
p
>
{
i18next
.
t
(
{
i18next
.
t
(
...
@@ -1374,12 +1410,14 @@ export function renderClaudeModelPrice(
...
@@ -1374,12 +1410,14 @@ 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
{
ratio
:
effectiveGroupRatio
,
label
:
ratioLabel
}
=
getEffectiveRatio
(
groupRatio
,
user_group_ratio
);
groupRatio
=
effectiveGroupRatio
;
if
(
modelPrice
!==
-
1
)
{
if
(
modelPrice
!==
-
1
)
{
return
i18next
.
t
(
return
i18next
.
t
(
...
@@ -1461,33 +1499,35 @@ export function renderClaudeModelPrice(
...
@@ -1461,33 +1499,35 @@ 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
,
cacheRatio
:
cacheRatio
,
cacheRatio
:
cacheRatio
,
cacheCreationInput
:
cacheCreationTokens
,
cacheCreationInput
:
cacheCreationTokens
,
cacheCreationRatio
:
cacheCreationRatio
,
cacheCreationRatio
:
cacheCreationRatio
,
cachePrice
:
cacheRatioPrice
,
cachePrice
:
cacheRatioPrice
,
cacheCreationPrice
:
cacheCreationRatioPrice
,
cacheCreationPrice
:
cacheCreationRatioPrice
,
price
:
inputRatioPrice
,
price
:
inputRatioPrice
,
completion
:
completionTokens
,
completion
:
completionTokens
,
compPrice
:
completionRatioPrice
,
compPrice
:
completionRatioPrice
,
ratio
:
groupRatio
,
ratio
:
groupRatio
,
total
:
price
.
toFixed
(
6
),
ratioType
:
ratioLabel
,
},
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
,
total
:
price
.
toFixed
(
6
),
ratioType
:
ratioLabel
,
},
total
:
price
.
toFixed
(
6
),
)}
},
)}
<
/p
>
<
/p
>
<
p
>
{
i18next
.
t
(
'仅供参考,以实际扣费为准'
)}
<
/p
>
<
p
>
{
i18next
.
t
(
'仅供参考,以实际扣费为准'
)}
<
/p
>
<
/article
>
<
/article
>
...
@@ -1501,10 +1541,12 @@ export function renderClaudeLogContent(
...
@@ -1501,10 +1541,12 @@ 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
{
ratio
:
effectiveGroupRatio
,
label
:
ratioLabel
}
=
getEffectiveRatio
(
groupRatio
,
user_group_ratio
);
groupRatio
=
effectiveGroupRatio
;
if
(
modelPrice
!==
-
1
)
{
if
(
modelPrice
!==
-
1
)
{
return
i18next
.
t
(
'模型价格 ${{price}},{{ratioType}} {{ratio}}'
,
{
return
i18next
.
t
(
'模型价格 ${{price}},{{ratioType}} {{ratio}}'
,
{
...
@@ -1531,12 +1573,14 @@ export function renderClaudeModelPriceSimple(
...
@@ -1531,12 +1573,14 @@ 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
{
ratio
:
effectiveGroupRatio
,
label
:
ratioLabel
}
=
getEffectiveRatio
(
groupRatio
,
user_group_ratio
);
groupRatio
=
effectiveGroupRatio
;
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 @
158d621f
...
@@ -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
);
...
@@ -99,6 +100,9 @@ export default function GroupRatioSettings(props) {
...
@@ -99,6 +100,9 @@ export default function GroupRatioSettings(props) {
<
Form
.
TextArea
<
Form
.
TextArea
label
=
{
t
(
'分组倍率'
)}
label
=
{
t
(
'分组倍率'
)}
placeholder
=
{
t
(
'为一个 JSON 文本,键为分组名称,值为倍率'
)}
placeholder
=
{
t
(
'为一个 JSON 文本,键为分组名称,值为倍率'
)}
extraText
=
{
t
(
'分组倍率设置,可以在此处新增分组或修改现有分组的倍率,格式为 JSON 字符串,例如:{"vip": 0.5, "test": 1},表示 vip 分组的倍率为 0.5,test 分组的倍率为 1'
,
)}
field
=
{
'GroupRatio'
}
field
=
{
'GroupRatio'
}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
trigger
=
'blur'
trigger
=
'blur'
...
@@ -120,6 +124,9 @@ export default function GroupRatioSettings(props) {
...
@@ -120,6 +124,9 @@ export default function GroupRatioSettings(props) {
<
Form
.
TextArea
<
Form
.
TextArea
label
=
{
t
(
'用户可选分组'
)}
label
=
{
t
(
'用户可选分组'
)}
placeholder
=
{
t
(
'为一个 JSON 文本,键为分组名称,值为分组描述'
)}
placeholder
=
{
t
(
'为一个 JSON 文本,键为分组名称,值为分组描述'
)}
extraText
=
{
t
(
'用户新建令牌时可选的分组,格式为 JSON 字符串,例如:{"vip": "VIP 用户", "test": "测试"},表示用户可以选择 vip 分组和 test 分组'
,
)}
field
=
{
'UserUsableGroups'
}
field
=
{
'UserUsableGroups'
}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
trigger
=
'blur'
trigger
=
'blur'
...
@@ -136,6 +143,30 @@ export default function GroupRatioSettings(props) {
...
@@ -136,6 +143,30 @@ export default function GroupRatioSettings(props) {
/
>
/
>
<
/Col
>
<
/Col
>
<
/Row
>
<
/Row
>
<
Row
gutter
=
{
16
}
>
<
Col
xs
=
{
24
}
sm
=
{
16
}
>
<
Form
.
TextArea
label
=
{
t
(
'分组特殊倍率'
)}
placeholder
=
{
t
(
'为一个 JSON 文本'
)}
extraText
=
{
t
(
'键为分组名称,值为另一个 JSON 对象,键为分组名称,值为该分组的用户的特殊分组倍率,例如:{"vip": {"default": 0.5, "test": 1}},表示 vip 分组的用户在使用default分组的令牌时倍率为0.5,使用test分组时倍率为1'
,
)}
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