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
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
222 additions
and
79 deletions
+222
-79
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
+0
-0
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
milliseconds
:=
tok
.
Sub
(
tik
)
.
Milliseconds
()
consumedTime
:=
float64
(
milliseconds
)
/
1000.0
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
,
"模型测试"
,
quota
,
"模型测试"
,
0
,
quota
,
int
(
consumedTime
),
false
,
info
.
Group
,
other
)
common
.
SysLog
(
fmt
.
Sprintf
(
"testing channel #%d, response:
\n
%s"
,
channel
.
Id
,
string
(
respBody
)))
...
...
controller/pricing.go
View file @
158d621f
package
controller
import
(
"github.com/gin-gonic/gin"
"one-api/model"
"one-api/setting"
"one-api/setting/operation_setting"
"github.com/gin-gonic/gin"
)
func
GetPricing
(
c
*
gin
.
Context
)
{
...
...
@@ -20,6 +21,12 @@ func GetPricing(c *gin.Context) {
user
,
err
:=
model
.
GetUserCache
(
userId
.
(
int
))
if
err
==
nil
{
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() {
common
.
OptionMap
[
"ModelPrice"
]
=
operation_setting
.
ModelPrice2JSONString
()
common
.
OptionMap
[
"CacheRatio"
]
=
operation_setting
.
CacheRatio2JSONString
()
common
.
OptionMap
[
"GroupRatio"
]
=
setting
.
GroupRatio2JSONString
()
common
.
OptionMap
[
"GroupGroupRatio"
]
=
setting
.
GroupGroupRatio2JSONString
()
common
.
OptionMap
[
"UserUsableGroups"
]
=
setting
.
UserUsableGroups2JSONString
()
common
.
OptionMap
[
"CompletionRatio"
]
=
operation_setting
.
CompletionRatio2JSONString
()
common
.
OptionMap
[
"TopUpLink"
]
=
common
.
TopUpLink
...
...
@@ -357,6 +358,8 @@ func updateOptionMap(key string, value string) (err error) {
err
=
operation_setting
.
UpdateModelRatioByJSONString
(
value
)
case
"GroupRatio"
:
err
=
setting
.
UpdateGroupRatioByJSONString
(
value
)
case
"GroupGroupRatio"
:
err
=
setting
.
UpdateGroupGroupRatioByJSONString
(
value
)
case
"UserUsableGroups"
:
err
=
setting
.
UpdateUserUsableGroupsByJSONString
(
value
)
case
"CompletionRatio"
:
...
...
relay/common/relay_info.go
View file @
158d621f
...
...
@@ -61,6 +61,7 @@ type RelayInfo struct {
TokenKey
string
UserId
int
Group
string
UserGroup
string
TokenUnlimited
bool
StartTime
time
.
Time
FirstResponseTime
time
.
Time
...
...
@@ -204,6 +205,7 @@ func GenRelayInfo(c *gin.Context) *RelayInfo {
TokenKey
:
tokenKey
,
UserId
:
userId
,
Group
:
group
,
UserGroup
:
c
.
GetString
(
constant
.
ContextKeyUserGroup
),
TokenUnlimited
:
tokenUnlimited
,
StartTime
:
startTime
,
FirstResponseTime
:
startTime
.
Add
(
-
time
.
Second
),
...
...
relay/helper/price.go
View file @
158d621f
...
...
@@ -2,12 +2,13 @@ package helper
import
(
"fmt"
"github.com/gin-gonic/gin"
"one-api/common"
constant2
"one-api/constant"
relaycommon
"one-api/relay/common"
"one-api/setting"
"one-api/setting/operation_setting"
"github.com/gin-gonic/gin"
)
type
PriceData
struct
{
...
...
@@ -18,6 +19,7 @@ type PriceData struct {
CacheCreationRatio
float64
ImageRatio
float64
GroupRatio
float64
UserGroupRatio
float64
UsePrice
bool
ShouldPreConsumedQuota
int
}
...
...
@@ -29,6 +31,10 @@ func (p PriceData) ToSetting() string {
func
ModelPriceHelper
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
promptTokens
int
,
maxTokens
int
)
(
PriceData
,
error
)
{
modelPrice
,
usePrice
:=
operation_setting
.
GetModelPrice
(
info
.
OriginModelName
,
false
)
groupRatio
:=
setting
.
GetGroupRatio
(
info
.
Group
)
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
info
.
UserGroup
,
info
.
Group
)
if
ok
{
groupRatio
=
userGroupRatio
}
var
preConsumedQuota
int
var
modelRatio
float64
var
completionRatio
float64
...
...
@@ -69,6 +75,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens
ModelRatio
:
modelRatio
,
CompletionRatio
:
completionRatio
,
GroupRatio
:
groupRatio
,
UserGroupRatio
:
userGroupRatio
,
UsePrice
:
usePrice
,
CacheRatio
:
cacheRatio
,
ImageRatio
:
imageRatio
,
...
...
relay/relay-text.go
View file @
158d621f
...
...
@@ -363,6 +363,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
modelRatio
:=
priceData
.
ModelRatio
groupRatio
:=
priceData
.
GroupRatio
modelPrice
:=
priceData
.
ModelPrice
userGroupRatio
:=
priceData
.
UserGroupRatio
// Convert values to decimal for precise calculation
dPromptTokens
:=
decimal
.
NewFromInt
(
int64
(
promptTokens
))
...
...
@@ -510,7 +511,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
if
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
{
other
[
"image"
]
=
true
other
[
"image_ratio"
]
=
imageRatio
...
...
service/log_info_generate.go
View file @
158d621f
...
...
@@ -8,7 +8,7 @@ import (
)
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
[
"model_ratio"
]
=
modelRatio
other
[
"group_ratio"
]
=
groupRatio
...
...
@@ -16,6 +16,7 @@ func GenerateTextOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, m
other
[
"cache_tokens"
]
=
cacheTokens
other
[
"cache_ratio"
]
=
cacheRatio
other
[
"model_price"
]
=
modelPrice
other
[
"user_group_ratio"
]
=
userGroupRatio
other
[
"frt"
]
=
float64
(
relayInfo
.
FirstResponseTime
.
UnixMilli
()
-
relayInfo
.
StartTime
.
UnixMilli
())
if
relayInfo
.
ReasoningEffort
!=
""
{
other
[
"reasoning_effort"
]
=
relayInfo
.
ReasoningEffort
...
...
@@ -30,8 +31,8 @@ func GenerateTextOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, m
return
other
}
func
GenerateWssOtherInfo
(
ctx
*
gin
.
Context
,
relayInfo
*
relaycommon
.
RelayInfo
,
usage
*
dto
.
RealtimeUsage
,
modelRatio
,
groupRatio
,
completionRatio
,
audioRatio
,
audioCompletionRatio
,
modelPrice
float64
)
map
[
string
]
interface
{}
{
info
:=
GenerateTextOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
0
,
0.0
,
modelPrice
)
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
,
userGroupRatio
)
info
[
"ws"
]
=
true
info
[
"audio_input"
]
=
usage
.
InputTokenDetails
.
AudioTokens
info
[
"audio_output"
]
=
usage
.
OutputTokenDetails
.
AudioTokens
...
...
@@ -42,8 +43,8 @@ func GenerateWssOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, us
return
info
}
func
GenerateAudioOtherInfo
(
ctx
*
gin
.
Context
,
relayInfo
*
relaycommon
.
RelayInfo
,
usage
*
dto
.
Usage
,
modelRatio
,
groupRatio
,
completionRatio
,
audioRatio
,
audioCompletionRatio
,
modelPrice
float64
)
map
[
string
]
interface
{}
{
info
:=
GenerateTextOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
0
,
0.0
,
modelPrice
)
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
,
userGroupRatio
)
info
[
"audio"
]
=
true
info
[
"audio_input"
]
=
usage
.
PromptTokensDetails
.
AudioTokens
info
[
"audio_output"
]
=
usage
.
CompletionTokenDetails
.
AudioTokens
...
...
@@ -55,8 +56,8 @@ func GenerateAudioOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
}
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
{}
{
info
:=
GenerateTextOtherInfo
(
ctx
,
relayInfo
,
modelRatio
,
groupRatio
,
completionRatio
,
cacheTokens
,
cacheRatio
,
modelPrice
)
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
,
userGroupRatio
)
info
[
"claude"
]
=
true
info
[
"cache_creation_tokens"
]
=
cacheCreationTokens
info
[
"cache_creation_ratio"
]
=
cacheCreationRatio
...
...
service/quota.go
View file @
158d621f
...
...
@@ -94,6 +94,10 @@ func PreWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usag
audioInputTokens
:=
usage
.
InputTokenDetails
.
AudioTokens
audioOutTokens
:=
usage
.
OutputTokenDetails
.
AudioTokens
groupRatio
:=
setting
.
GetGroupRatio
(
relayInfo
.
Group
)
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
relayInfo
.
UserGroup
,
relayInfo
.
Group
)
if
ok
{
groupRatio
=
userGroupRatio
}
modelRatio
,
_
:=
operation_setting
.
GetModelRatio
(
modelName
)
quotaInfo
:=
QuotaInfo
{
...
...
@@ -145,6 +149,11 @@ func PostWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, mod
audioRatio
:=
decimal
.
NewFromFloat
(
operation_setting
.
GetAudioRatio
(
relayInfo
.
OriginModelName
))
audioCompletionRatio
:=
decimal
.
NewFromFloat
(
operation_setting
.
GetAudioCompletionRatio
(
modelName
))
actualGroupRatio
:=
groupRatio
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
relayInfo
.
UserGroup
,
relayInfo
.
Group
)
if
ok
{
actualGroupRatio
=
userGroupRatio
}
quotaInfo
:=
QuotaInfo
{
InputDetails
:
TokenDetails
{
TextTokens
:
textInputTokens
,
...
...
@@ -157,7 +166,7 @@ func PostWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, mod
ModelName
:
modelName
,
UsePrice
:
usePrice
,
ModelRatio
:
modelRatio
,
GroupRatio
:
g
roupRatio
,
GroupRatio
:
actualG
roupRatio
,
}
quota
:=
calculateAudioQuota
(
quotaInfo
)
...
...
@@ -189,7 +198,7 @@ func PostWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, mod
logContent
+=
", "
+
extraContent
}
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
,
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,
modelRatio
:=
priceData
.
ModelRatio
groupRatio
:=
priceData
.
GroupRatio
modelPrice
:=
priceData
.
ModelPrice
userGroupRatio
:=
priceData
.
UserGroupRatio
cacheRatio
:=
priceData
.
CacheRatio
cacheTokens
:=
usage
.
PromptTokensDetails
.
CachedTokens
...
...
@@ -256,7 +265,7 @@ func PostClaudeConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
}
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
,
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,
modelPrice
:=
priceData
.
ModelPrice
usePrice
:=
priceData
.
UsePrice
actualGroupRatio
:=
groupRatio
userGroupRatio
,
ok
:=
setting
.
GetGroupGroupRatio
(
relayInfo
.
UserGroup
,
relayInfo
.
Group
)
if
ok
{
actualGroupRatio
=
userGroupRatio
}
quotaInfo
:=
QuotaInfo
{
InputDetails
:
TokenDetails
{
TextTokens
:
textInputTokens
,
...
...
@@ -293,7 +308,7 @@ func PostAudioConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
ModelName
:
relayInfo
.
OriginModelName
,
UsePrice
:
usePrice
,
ModelRatio
:
modelRatio
,
GroupRatio
:
g
roupRatio
,
GroupRatio
:
actualG
roupRatio
,
}
quota
:=
calculateAudioQuota
(
quotaInfo
)
...
...
@@ -333,7 +348,7 @@ func PostAudioConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
logContent
+=
", "
+
extraContent
}
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
,
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{
}
var
groupRatioMutex
sync
.
RWMutex
var
(
GroupGroupRatio
=
map
[
string
]
map
[
string
]
float64
{
"vip"
:
{
"edit_this"
:
0.9
,
},
}
groupGroupRatioMutex
sync
.
RWMutex
)
func
GetGroupRatioCopy
()
map
[
string
]
float64
{
groupRatioMutex
.
RLock
()
defer
groupRatioMutex
.
RUnlock
()
groupRatioCopy
:=
make
(
map
[
string
]
float64
)
for
k
,
v
:=
range
groupRatio
{
groupRatioCopy
[
k
]
=
v
...
...
@@ -28,7 +37,7 @@ func GetGroupRatioCopy() map[string]float64 {
func
ContainsGroupRatio
(
name
string
)
bool
{
groupRatioMutex
.
RLock
()
defer
groupRatioMutex
.
RUnlock
()
_
,
ok
:=
groupRatio
[
name
]
return
ok
}
...
...
@@ -36,7 +45,7 @@ func ContainsGroupRatio(name string) bool {
func
GroupRatio2JSONString
()
string
{
groupRatioMutex
.
RLock
()
defer
groupRatioMutex
.
RUnlock
()
jsonBytes
,
err
:=
json
.
Marshal
(
groupRatio
)
if
err
!=
nil
{
common
.
SysError
(
"error marshalling model ratio: "
+
err
.
Error
())
...
...
@@ -47,7 +56,7 @@ func GroupRatio2JSONString() string {
func
UpdateGroupRatioByJSONString
(
jsonStr
string
)
error
{
groupRatioMutex
.
Lock
()
defer
groupRatioMutex
.
Unlock
()
groupRatio
=
make
(
map
[
string
]
float64
)
return
json
.
Unmarshal
([]
byte
(
jsonStr
),
&
groupRatio
)
}
...
...
@@ -55,7 +64,7 @@ func UpdateGroupRatioByJSONString(jsonStr string) error {
func
GetGroupRatio
(
name
string
)
float64
{
groupRatioMutex
.
RLock
()
defer
groupRatioMutex
.
RUnlock
()
ratio
,
ok
:=
groupRatio
[
name
]
if
!
ok
{
common
.
SysError
(
"group ratio not found: "
+
name
)
...
...
@@ -64,6 +73,40 @@ func GetGroupRatio(name string) float64 {
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
{
checkGroupRatio
:=
make
(
map
[
string
]
float64
)
err
:=
json
.
Unmarshal
([]
byte
(
jsonStr
),
&
checkGroupRatio
)
...
...
web/src/components/settings/OperationSetting.js
View file @
158d621f
...
...
@@ -30,6 +30,7 @@ const OperationSetting = () => {
CompletionRatio
:
''
,
ModelPrice
:
''
,
GroupRatio
:
''
,
GroupGroupRatio
:
''
,
UserUsableGroups
:
''
,
TopUpLink
:
''
,
'general_setting.docs_link'
:
''
,
...
...
@@ -74,6 +75,7 @@ const OperationSetting = () => {
if
(
item
.
key
===
'ModelRatio'
||
item
.
key
===
'GroupRatio'
||
item
.
key
===
'GroupGroupRatio'
||
item
.
key
===
'UserUsableGroups'
||
item
.
key
===
'CompletionRatio'
||
item
.
key
===
'ModelPrice'
||
...
...
web/src/components/table/LogsTable.js
View file @
158d621f
This diff is collapsed.
Click to expand it.
web/src/helpers/render.js
View file @
158d621f
This diff is collapsed.
Click to expand it.
web/src/pages/Setting/Operation/GroupRatioSettings.js
View file @
158d621f
...
...
@@ -16,6 +16,7 @@ export default function GroupRatioSettings(props) {
const
[
inputs
,
setInputs
]
=
useState
({
GroupRatio
:
''
,
UserUsableGroups
:
''
,
GroupGroupRatio
:
''
,
});
const
refForm
=
useRef
();
const
[
inputsRow
,
setInputsRow
]
=
useState
(
inputs
);
...
...
@@ -99,6 +100,9 @@ export default function GroupRatioSettings(props) {
<
Form
.
TextArea
label
=
{
t
(
'分组倍率'
)}
placeholder
=
{
t
(
'为一个 JSON 文本,键为分组名称,值为倍率'
)}
extraText
=
{
t
(
'分组倍率设置,可以在此处新增分组或修改现有分组的倍率,格式为 JSON 字符串,例如:{"vip": 0.5, "test": 1},表示 vip 分组的倍率为 0.5,test 分组的倍率为 1'
,
)}
field
=
{
'GroupRatio'
}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
trigger
=
'blur'
...
...
@@ -120,6 +124,9 @@ export default function GroupRatioSettings(props) {
<
Form
.
TextArea
label
=
{
t
(
'用户可选分组'
)}
placeholder
=
{
t
(
'为一个 JSON 文本,键为分组名称,值为分组描述'
)}
extraText
=
{
t
(
'用户新建令牌时可选的分组,格式为 JSON 字符串,例如:{"vip": "VIP 用户", "test": "测试"},表示用户可以选择 vip 分组和 test 分组'
,
)}
field
=
{
'UserUsableGroups'
}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
trigger
=
'blur'
...
...
@@ -136,6 +143,30 @@ export default function GroupRatioSettings(props) {
/
>
<
/Col
>
<
/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
>
<
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