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
4a02eb1b
authored
Sep 18, 2024
by
CalciumIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 令牌分组
parent
120b5476
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
160 additions
and
32 deletions
+160
-32
common/user_groups.go
+23
-0
controller/group.go
+15
-0
controller/token.go
+2
-0
middleware/auth.go
+1
-0
middleware/distributor.go
+9
-0
model/option.go
+3
-0
model/token.go
+3
-1
router/api-router.go
+1
-0
web/src/components/OperationSetting.js
+2
-0
web/src/components/TokensTable.js
+8
-3
web/src/helpers/render.js
+2
-2
web/src/pages/Setting/Operation/SettingsMagnification.js
+29
-1
web/src/pages/Token/EditToken.js
+62
-25
No files found.
common/user_groups.go
0 → 100644
View file @
4a02eb1b
package
common
import
(
"encoding/json"
)
var
UserUsableGroups
=
map
[
string
]
string
{
"default"
:
"默认分组"
,
"vip"
:
"vip分组"
,
}
func
UserUsableGroups2JSONString
()
string
{
jsonBytes
,
err
:=
json
.
Marshal
(
UserUsableGroups
)
if
err
!=
nil
{
SysError
(
"error marshalling user groups: "
+
err
.
Error
())
}
return
string
(
jsonBytes
)
}
func
UpdateUserUsableGroupsByJSONString
(
jsonStr
string
)
error
{
UserUsableGroups
=
make
(
map
[
string
]
string
)
return
json
.
Unmarshal
([]
byte
(
jsonStr
),
&
UserUsableGroups
)
}
controller/group.go
View file @
4a02eb1b
...
@@ -17,3 +17,18 @@ func GetGroups(c *gin.Context) {
...
@@ -17,3 +17,18 @@ func GetGroups(c *gin.Context) {
"data"
:
groupNames
,
"data"
:
groupNames
,
})
})
}
}
func
GetUserGroups
(
c
*
gin
.
Context
)
{
usableGroups
:=
make
(
map
[
string
]
string
)
for
groupName
,
_
:=
range
common
.
GroupRatio
{
// UserUsableGroups contains the groups that the user can use
if
_
,
ok
:=
common
.
UserUsableGroups
[
groupName
];
ok
{
usableGroups
[
groupName
]
=
common
.
UserUsableGroups
[
groupName
]
}
}
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
true
,
"message"
:
""
,
"data"
:
usableGroups
,
})
}
controller/token.go
View file @
4a02eb1b
...
@@ -135,6 +135,7 @@ func AddToken(c *gin.Context) {
...
@@ -135,6 +135,7 @@ func AddToken(c *gin.Context) {
ModelLimitsEnabled
:
token
.
ModelLimitsEnabled
,
ModelLimitsEnabled
:
token
.
ModelLimitsEnabled
,
ModelLimits
:
token
.
ModelLimits
,
ModelLimits
:
token
.
ModelLimits
,
AllowIps
:
token
.
AllowIps
,
AllowIps
:
token
.
AllowIps
,
Group
:
token
.
Group
,
}
}
err
=
cleanToken
.
Insert
()
err
=
cleanToken
.
Insert
()
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -223,6 +224,7 @@ func UpdateToken(c *gin.Context) {
...
@@ -223,6 +224,7 @@ func UpdateToken(c *gin.Context) {
cleanToken
.
ModelLimitsEnabled
=
token
.
ModelLimitsEnabled
cleanToken
.
ModelLimitsEnabled
=
token
.
ModelLimitsEnabled
cleanToken
.
ModelLimits
=
token
.
ModelLimits
cleanToken
.
ModelLimits
=
token
.
ModelLimits
cleanToken
.
AllowIps
=
token
.
AllowIps
cleanToken
.
AllowIps
=
token
.
AllowIps
cleanToken
.
Group
=
token
.
Group
}
}
err
=
cleanToken
.
Update
()
err
=
cleanToken
.
Update
()
if
err
!=
nil
{
if
err
!=
nil
{
...
...
middleware/auth.go
View file @
4a02eb1b
...
@@ -176,6 +176,7 @@ func TokenAuth() func(c *gin.Context) {
...
@@ -176,6 +176,7 @@ func TokenAuth() func(c *gin.Context) {
c
.
Set
(
"token_model_limit_enabled"
,
false
)
c
.
Set
(
"token_model_limit_enabled"
,
false
)
}
}
c
.
Set
(
"allow_ips"
,
token
.
GetIpLimitsMap
())
c
.
Set
(
"allow_ips"
,
token
.
GetIpLimitsMap
())
c
.
Set
(
"token_group"
,
token
.
Group
)
if
len
(
parts
)
>
1
{
if
len
(
parts
)
>
1
{
if
model
.
IsAdmin
(
token
.
UserId
)
{
if
model
.
IsAdmin
(
token
.
UserId
)
{
c
.
Set
(
"specific_channel_id"
,
parts
[
1
])
c
.
Set
(
"specific_channel_id"
,
parts
[
1
])
...
...
middleware/distributor.go
View file @
4a02eb1b
...
@@ -39,6 +39,15 @@ func Distribute() func(c *gin.Context) {
...
@@ -39,6 +39,15 @@ func Distribute() func(c *gin.Context) {
return
return
}
}
userGroup
,
_
:=
model
.
CacheGetUserGroup
(
userId
)
userGroup
,
_
:=
model
.
CacheGetUserGroup
(
userId
)
tokenGroup
:=
c
.
GetString
(
"token_group"
)
if
tokenGroup
!=
""
{
// check group in common.GroupRatio
if
_
,
ok
:=
common
.
GroupRatio
[
tokenGroup
];
!
ok
{
abortWithOpenAiMessage
(
c
,
http
.
StatusForbidden
,
fmt
.
Sprintf
(
"分组 %s 已被禁用"
,
tokenGroup
))
return
}
userGroup
=
tokenGroup
}
c
.
Set
(
"group"
,
userGroup
)
c
.
Set
(
"group"
,
userGroup
)
if
ok
{
if
ok
{
id
,
err
:=
strconv
.
Atoi
(
channelId
.
(
string
))
id
,
err
:=
strconv
.
Atoi
(
channelId
.
(
string
))
...
...
model/option.go
View file @
4a02eb1b
...
@@ -86,6 +86,7 @@ func InitOptionMap() {
...
@@ -86,6 +86,7 @@ func InitOptionMap() {
common
.
OptionMap
[
"ModelRatio"
]
=
common
.
ModelRatio2JSONString
()
common
.
OptionMap
[
"ModelRatio"
]
=
common
.
ModelRatio2JSONString
()
common
.
OptionMap
[
"ModelPrice"
]
=
common
.
ModelPrice2JSONString
()
common
.
OptionMap
[
"ModelPrice"
]
=
common
.
ModelPrice2JSONString
()
common
.
OptionMap
[
"GroupRatio"
]
=
common
.
GroupRatio2JSONString
()
common
.
OptionMap
[
"GroupRatio"
]
=
common
.
GroupRatio2JSONString
()
common
.
OptionMap
[
"UserUsableGroups"
]
=
common
.
UserUsableGroups2JSONString
()
common
.
OptionMap
[
"CompletionRatio"
]
=
common
.
CompletionRatio2JSONString
()
common
.
OptionMap
[
"CompletionRatio"
]
=
common
.
CompletionRatio2JSONString
()
common
.
OptionMap
[
"TopUpLink"
]
=
common
.
TopUpLink
common
.
OptionMap
[
"TopUpLink"
]
=
common
.
TopUpLink
common
.
OptionMap
[
"ChatLink"
]
=
common
.
ChatLink
common
.
OptionMap
[
"ChatLink"
]
=
common
.
ChatLink
...
@@ -303,6 +304,8 @@ func updateOptionMap(key string, value string) (err error) {
...
@@ -303,6 +304,8 @@ func updateOptionMap(key string, value string) (err error) {
err
=
common
.
UpdateModelRatioByJSONString
(
value
)
err
=
common
.
UpdateModelRatioByJSONString
(
value
)
case
"GroupRatio"
:
case
"GroupRatio"
:
err
=
common
.
UpdateGroupRatioByJSONString
(
value
)
err
=
common
.
UpdateGroupRatioByJSONString
(
value
)
case
"UserUsableGroups"
:
err
=
common
.
UpdateUserUsableGroupsByJSONString
(
value
)
case
"CompletionRatio"
:
case
"CompletionRatio"
:
err
=
common
.
UpdateCompletionRatioByJSONString
(
value
)
err
=
common
.
UpdateCompletionRatioByJSONString
(
value
)
case
"ModelPrice"
:
case
"ModelPrice"
:
...
...
model/token.go
View file @
4a02eb1b
...
@@ -25,6 +25,7 @@ type Token struct {
...
@@ -25,6 +25,7 @@ type Token struct {
ModelLimits
string
`json:"model_limits" gorm:"type:varchar(1024);default:''"`
ModelLimits
string
`json:"model_limits" gorm:"type:varchar(1024);default:''"`
AllowIps
*
string
`json:"allow_ips" gorm:"default:''"`
AllowIps
*
string
`json:"allow_ips" gorm:"default:''"`
UsedQuota
int
`json:"used_quota" gorm:"default:0"`
// used quota
UsedQuota
int
`json:"used_quota" gorm:"default:0"`
// used quota
Group
string
`json:"group" gorm:"default:''"`
DeletedAt
gorm
.
DeletedAt
`gorm:"index"`
DeletedAt
gorm
.
DeletedAt
`gorm:"index"`
}
}
...
@@ -153,7 +154,8 @@ func (token *Token) Insert() error {
...
@@ -153,7 +154,8 @@ func (token *Token) Insert() error {
// Update Make sure your token's fields is completed, because this will update non-zero values
// Update Make sure your token's fields is completed, because this will update non-zero values
func
(
token
*
Token
)
Update
()
error
{
func
(
token
*
Token
)
Update
()
error
{
var
err
error
var
err
error
err
=
DB
.
Model
(
token
)
.
Select
(
"name"
,
"status"
,
"expired_time"
,
"remain_quota"
,
"unlimited_quota"
,
"model_limits_enabled"
,
"model_limits"
,
"allow_ips"
)
.
Updates
(
token
)
.
Error
err
=
DB
.
Model
(
token
)
.
Select
(
"name"
,
"status"
,
"expired_time"
,
"remain_quota"
,
"unlimited_quota"
,
"model_limits_enabled"
,
"model_limits"
,
"allow_ips"
,
"group"
)
.
Updates
(
token
)
.
Error
return
err
return
err
}
}
...
...
router/api-router.go
View file @
4a02eb1b
...
@@ -39,6 +39,7 @@ func SetApiRouter(router *gin.Engine) {
...
@@ -39,6 +39,7 @@ func SetApiRouter(router *gin.Engine) {
//userRoute.POST("/tokenlog", middleware.CriticalRateLimit(), controller.TokenLog)
//userRoute.POST("/tokenlog", middleware.CriticalRateLimit(), controller.TokenLog)
userRoute
.
GET
(
"/logout"
,
controller
.
Logout
)
userRoute
.
GET
(
"/logout"
,
controller
.
Logout
)
userRoute
.
GET
(
"/epay/notify"
,
controller
.
EpayNotify
)
userRoute
.
GET
(
"/epay/notify"
,
controller
.
EpayNotify
)
userRoute
.
GET
(
"/groups"
,
controller
.
GetUserGroups
)
selfRoute
:=
userRoute
.
Group
(
"/"
)
selfRoute
:=
userRoute
.
Group
(
"/"
)
selfRoute
.
Use
(
middleware
.
UserAuth
())
selfRoute
.
Use
(
middleware
.
UserAuth
())
...
...
web/src/components/OperationSetting.js
View file @
4a02eb1b
...
@@ -23,6 +23,7 @@ const OperationSetting = () => {
...
@@ -23,6 +23,7 @@ const OperationSetting = () => {
CompletionRatio
:
''
,
CompletionRatio
:
''
,
ModelPrice
:
''
,
ModelPrice
:
''
,
GroupRatio
:
''
,
GroupRatio
:
''
,
UserUsableGroups
:
''
,
TopUpLink
:
''
,
TopUpLink
:
''
,
ChatLink
:
''
,
ChatLink
:
''
,
ChatLink2
:
''
,
// 添加的新状态变量
ChatLink2
:
''
,
// 添加的新状态变量
...
@@ -62,6 +63,7 @@ const OperationSetting = () => {
...
@@ -62,6 +63,7 @@ const OperationSetting = () => {
if
(
if
(
item
.
key
===
'ModelRatio'
||
item
.
key
===
'ModelRatio'
||
item
.
key
===
'GroupRatio'
||
item
.
key
===
'GroupRatio'
||
item
.
key
===
'UserUsableGroups'
||
item
.
key
===
'CompletionRatio'
||
item
.
key
===
'CompletionRatio'
||
item
.
key
===
'ModelPrice'
item
.
key
===
'ModelPrice'
)
{
)
{
...
...
web/src/components/TokensTable.js
View file @
4a02eb1b
...
@@ -8,14 +8,14 @@ import {
...
@@ -8,14 +8,14 @@ import {
}
from
'../helpers'
;
}
from
'../helpers'
;
import
{
ITEMS_PER_PAGE
}
from
'../constants'
;
import
{
ITEMS_PER_PAGE
}
from
'../constants'
;
import
{
renderQuota
}
from
'../helpers/render'
;
import
{
renderGroup
,
renderQuota
}
from
'../helpers/render'
;
import
{
import
{
Button
,
Button
,
Dropdown
,
Dropdown
,
Form
,
Form
,
Modal
,
Modal
,
Popconfirm
,
Popconfirm
,
Popover
,
Popover
,
Space
,
SplitButtonGroup
,
SplitButtonGroup
,
Table
,
Table
,
Tag
,
Tag
,
...
@@ -119,7 +119,12 @@ const TokensTable = () => {
...
@@ -119,7 +119,12 @@ const TokensTable = () => {
dataIndex
:
'status'
,
dataIndex
:
'status'
,
key
:
'status'
,
key
:
'status'
,
render
:
(
text
,
record
,
index
)
=>
{
render
:
(
text
,
record
,
index
)
=>
{
return
<
div
>
{
renderStatus
(
text
,
record
.
model_limits_enabled
)}
<
/div>
;
return
<
div
>
<
Space
>
{
renderStatus
(
text
,
record
.
model_limits_enabled
)}
{
renderGroup
(
record
.
group
)}
<
/Space
>
<
/div>
;
},
},
},
},
{
{
...
...
web/src/helpers/render.js
View file @
4a02eb1b
...
@@ -15,8 +15,8 @@ export function renderText(text, limit) {
...
@@ -15,8 +15,8 @@ export function renderText(text, limit) {
export
function
renderGroup
(
group
)
{
export
function
renderGroup
(
group
)
{
if
(
group
===
''
)
{
if
(
group
===
''
)
{
return
(
return
(
<
Tag
size
=
'large'
key
=
'default'
>
<
Tag
size
=
'large'
key
=
'default'
color
=
{
stringToColor
(
'default'
)}
>
unknown
default
<
/Tag
>
<
/Tag
>
);
);
}
}
...
...
web/src/pages/Setting/Operation/SettingsMagnification.js
View file @
4a02eb1b
...
@@ -16,7 +16,8 @@ export default function SettingsMagnification(props) {
...
@@ -16,7 +16,8 @@ export default function SettingsMagnification(props) {
ModelPrice
:
''
,
ModelPrice
:
''
,
ModelRatio
:
''
,
ModelRatio
:
''
,
CompletionRatio
:
''
,
CompletionRatio
:
''
,
GroupRatio
:
''
GroupRatio
:
''
,
UserUsableGroups
:
''
});
});
const
refForm
=
useRef
();
const
refForm
=
useRef
();
const
[
inputsRow
,
setInputsRow
]
=
useState
(
inputs
);
const
[
inputsRow
,
setInputsRow
]
=
useState
(
inputs
);
...
@@ -213,6 +214,33 @@ export default function SettingsMagnification(props) {
...
@@ -213,6 +214,33 @@ export default function SettingsMagnification(props) {
/
>
/
>
<
/Col
>
<
/Col
>
<
/Row
>
<
/Row
>
<
Row
gutter
=
{
16
}
>
<
Col
span
=
{
16
}
>
<
Form
.
TextArea
label
=
{
'用户可选分组'
}
extraText
=
{
''
}
placeholder
=
{
'为一个 JSON 文本,键为分组名称,值为倍率'
}
field
=
{
'UserUsableGroups'
}
autosize
=
{{
minRows
:
6
,
maxRows
:
12
}}
trigger
=
'blur'
stopValidateWithError
rules
=
{[
{
validator
:
(
rule
,
value
)
=>
{
return
verifyJSON
(
value
);
},
message
:
'不是合法的 JSON 字符串'
}
]}
onChange
=
{(
value
)
=>
setInputs
({
...
inputs
,
UserUsableGroups
:
value
})
}
/
>
<
/Col
>
<
/Row
>
<
/Form.Section
>
<
/Form.Section
>
<
/Form
>
<
/Form
>
<
Space
>
<
Space
>
...
...
web/src/pages/Token/EditToken.js
View file @
4a02eb1b
...
@@ -35,6 +35,7 @@ const EditToken = (props) => {
...
@@ -35,6 +35,7 @@ const EditToken = (props) => {
model_limits_enabled
:
false
,
model_limits_enabled
:
false
,
model_limits
:
[],
model_limits
:
[],
allow_ips
:
''
,
allow_ips
:
''
,
group
:
''
,
};
};
const
[
inputs
,
setInputs
]
=
useState
(
originInputs
);
const
[
inputs
,
setInputs
]
=
useState
(
originInputs
);
const
{
const
{
...
@@ -44,10 +45,12 @@ const EditToken = (props) => {
...
@@ -44,10 +45,12 @@ const EditToken = (props) => {
unlimited_quota
,
unlimited_quota
,
model_limits_enabled
,
model_limits_enabled
,
model_limits
,
model_limits
,
allow_ips
allow_ips
,
group
}
=
inputs
;
}
=
inputs
;
// const [visible, setVisible] = useState(false);
// const [visible, setVisible] = useState(false);
const
[
models
,
setModels
]
=
useState
({});
const
[
models
,
setModels
]
=
useState
({});
const
[
groups
,
setGroups
]
=
useState
([]);
const
navigate
=
useNavigate
();
const
navigate
=
useNavigate
();
const
handleInputChange
=
(
name
,
value
)
=>
{
const
handleInputChange
=
(
name
,
value
)
=>
{
setInputs
((
inputs
)
=>
({
...
inputs
,
[
name
]:
value
}));
setInputs
((
inputs
)
=>
({
...
inputs
,
[
name
]:
value
}));
...
@@ -88,6 +91,22 @@ const EditToken = (props) => {
...
@@ -88,6 +91,22 @@ const EditToken = (props) => {
}
}
};
};
const
loadGroups
=
async
()
=>
{
let
res
=
await
API
.
get
(
`/api/user/groups`
);
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
// return data is a map, key is group name, value is group description
// label is group description, value is group name
let
localGroupOptions
=
Object
.
keys
(
data
).
map
((
group
)
=>
({
label
:
data
[
group
],
value
:
group
,
}));
setGroups
(
localGroupOptions
);
}
else
{
showError
(
message
);
}
};
const
loadToken
=
async
()
=>
{
const
loadToken
=
async
()
=>
{
setLoading
(
true
);
setLoading
(
true
);
let
res
=
await
API
.
get
(
`/api/token/
${
props
.
editingToken
.
id
}
`
);
let
res
=
await
API
.
get
(
`/api/token/
${
props
.
editingToken
.
id
}
`
);
...
@@ -120,6 +139,7 @@ const EditToken = (props) => {
...
@@ -120,6 +139,7 @@ const EditToken = (props) => {
});
});
}
}
loadModels
();
loadModels
();
loadGroups
();
},
[
isEdit
]);
},
[
isEdit
]);
// 新增 state 变量 tokenCount 来记录用户想要创建的令牌数量,默认为 1
// 新增 state 变量 tokenCount 来记录用户想要创建的令牌数量,默认为 1
...
@@ -253,7 +273,7 @@ const EditToken = (props) => {
...
@@ -253,7 +273,7 @@ const EditToken = (props) => {
>
>
<
Spin
spinning
=
{
loading
}
>
<
Spin
spinning
=
{
loading
}
>
<
Input
<
Input
style
=
{{
marginTop
:
20
}}
style
=
{{
marginTop
:
20
}}
label
=
'名称'
label
=
'名称'
name
=
'name'
name
=
'name'
placeholder
=
{
'请输入名称'
}
placeholder
=
{
'请输入名称'
}
...
@@ -262,7 +282,7 @@ const EditToken = (props) => {
...
@@ -262,7 +282,7 @@ const EditToken = (props) => {
autoComplete
=
'new-password'
autoComplete
=
'new-password'
required
=
{
!
isEdit
}
required
=
{
!
isEdit
}
/
>
/
>
<
Divider
/>
<
Divider
/>
<
DatePicker
<
DatePicker
label
=
'过期时间'
label
=
'过期时间'
name
=
'expired_time'
name
=
'expired_time'
...
@@ -272,7 +292,7 @@ const EditToken = (props) => {
...
@@ -272,7 +292,7 @@ const EditToken = (props) => {
autoComplete
=
'new-password'
autoComplete
=
'new-password'
type
=
'dateTime'
type
=
'dateTime'
/>
/>
<
div
style
=
{{
marginTop
:
20
}}
>
<
div
style
=
{{
marginTop
:
20
}}
>
<
Space
>
<
Space
>
<
Button
<
Button
type
=
{
'tertiary'
}
type
=
{
'tertiary'
}
...
@@ -309,18 +329,18 @@ const EditToken = (props) => {
...
@@ -309,18 +329,18 @@ const EditToken = (props) => {
<
/Space
>
<
/Space
>
<
/div
>
<
/div
>
<
Divider
/>
<
Divider
/>
<
Banner
<
Banner
type
=
{
'warning'
}
type
=
{
'warning'
}
description
=
{
description
=
{
'注意,令牌的额度仅用于限制令牌本身的最大额度使用量,实际的使用受到账户的剩余额度限制。'
'注意,令牌的额度仅用于限制令牌本身的最大额度使用量,实际的使用受到账户的剩余额度限制。'
}
}
><
/Banner
>
><
/Banner
>
<
div
style
=
{{
marginTop
:
20
}}
>
<
div
style
=
{{
marginTop
:
20
}}
>
<
Typography
.
Text
>
{
`额度
${
renderQuotaWithPrompt
(
remain_quota
)}
`
}
<
/Typography.Text
>
<
Typography
.
Text
>
{
`额度
${
renderQuotaWithPrompt
(
remain_quota
)}
`
}
<
/Typography.Text
>
<
/div
>
<
/div
>
<
AutoComplete
<
AutoComplete
style
=
{{
marginTop
:
8
}}
style
=
{{
marginTop
:
8
}}
name
=
'remain_quota'
name
=
'remain_quota'
placeholder
=
{
'请输入额度'
}
placeholder
=
{
'请输入额度'
}
onChange
=
{(
value
)
=>
handleInputChange
(
'remain_quota'
,
value
)}
onChange
=
{(
value
)
=>
handleInputChange
(
'remain_quota'
,
value
)}
...
@@ -329,23 +349,23 @@ const EditToken = (props) => {
...
@@ -329,23 +349,23 @@ const EditToken = (props) => {
type
=
'number'
type
=
'number'
// position={'top'}
// position={'top'}
data
=
{[
data
=
{[
{
value
:
500000
,
label
:
'1$'
},
{
value
:
500000
,
label
:
'1$'
},
{
value
:
5000000
,
label
:
'10$'
},
{
value
:
5000000
,
label
:
'10$'
},
{
value
:
25000000
,
label
:
'50$'
},
{
value
:
25000000
,
label
:
'50$'
},
{
value
:
50000000
,
label
:
'100$'
},
{
value
:
50000000
,
label
:
'100$'
},
{
value
:
250000000
,
label
:
'500$'
},
{
value
:
250000000
,
label
:
'500$'
},
{
value
:
500000000
,
label
:
'1000$'
},
{
value
:
500000000
,
label
:
'1000$'
},
]}
]}
disabled
=
{
unlimited_quota
}
disabled
=
{
unlimited_quota
}
/
>
/
>
{
!
isEdit
&&
(
{
!
isEdit
&&
(
<>
<>
<
div
style
=
{{
marginTop
:
20
}}
>
<
div
style
=
{{
marginTop
:
20
}}
>
<
Typography
.
Text
>
新建数量
<
/Typography.Text
>
<
Typography
.
Text
>
新建数量
<
/Typography.Text
>
<
/div
>
<
/div
>
<
AutoComplete
<
AutoComplete
style
=
{{
marginTop
:
8
}}
style
=
{{
marginTop
:
8
}}
label
=
'数量'
label
=
'数量'
placeholder
=
{
'请选择或输入创建令牌的数量'
}
placeholder
=
{
'请选择或输入创建令牌的数量'
}
onChange
=
{(
value
)
=>
handleTokenCountChange
(
value
)}
onChange
=
{(
value
)
=>
handleTokenCountChange
(
value
)}
...
@@ -354,10 +374,10 @@ const EditToken = (props) => {
...
@@ -354,10 +374,10 @@ const EditToken = (props) => {
autoComplete
=
'off'
autoComplete
=
'off'
type
=
'number'
type
=
'number'
data
=
{[
data
=
{[
{
value
:
10
,
label
:
'10个'
},
{
value
:
10
,
label
:
'10个'
},
{
value
:
20
,
label
:
'20个'
},
{
value
:
20
,
label
:
'20个'
},
{
value
:
30
,
label
:
'30个'
},
{
value
:
30
,
label
:
'30个'
},
{
value
:
100
,
label
:
'100个'
},
{
value
:
100
,
label
:
'100个'
},
]}
]}
disabled
=
{
unlimited_quota
}
disabled
=
{
unlimited_quota
}
/
>
/
>
...
@@ -366,7 +386,7 @@ const EditToken = (props) => {
...
@@ -366,7 +386,7 @@ const EditToken = (props) => {
<
div
>
<
div
>
<
Button
<
Button
style
=
{{
marginTop
:
8
}}
style
=
{{
marginTop
:
8
}}
type
=
{
'warning'
}
type
=
{
'warning'
}
onClick
=
{()
=>
{
onClick
=
{()
=>
{
setUnlimitedQuota
();
setUnlimitedQuota
();
...
@@ -375,8 +395,8 @@ const EditToken = (props) => {
...
@@ -375,8 +395,8 @@ const EditToken = (props) => {
{
unlimited_quota
?
'取消无限额度'
:
'设为无限额度'
}
{
unlimited_quota
?
'取消无限额度'
:
'设为无限额度'
}
<
/Button
>
<
/Button
>
<
/div
>
<
/div
>
<
Divider
/>
<
Divider
/>
<
div
style
=
{{
marginTop
:
10
}}
>
<
div
style
=
{{
marginTop
:
10
}}
>
<
Typography
.
Text
>
IP
白名单(请勿过度信任此功能)
<
/Typography.Text
>
<
Typography
.
Text
>
IP
白名单(请勿过度信任此功能)
<
/Typography.Text
>
<
/div
>
<
/div
>
<
TextArea
<
TextArea
...
@@ -387,9 +407,9 @@ const EditToken = (props) => {
...
@@ -387,9 +407,9 @@ const EditToken = (props) => {
handleInputChange
(
'allow_ips'
,
value
);
handleInputChange
(
'allow_ips'
,
value
);
}}
}}
value
=
{
inputs
.
allow_ips
}
value
=
{
inputs
.
allow_ips
}
style
=
{{
fontFamily
:
'JetBrains Mono, Consolas'
}}
style
=
{{
fontFamily
:
'JetBrains Mono, Consolas'
}}
/
>
/
>
<
div
style
=
{{
marginTop
:
10
,
display
:
'flex'
}}
>
<
div
style
=
{{
marginTop
:
10
,
display
:
'flex'
}}
>
<
Space
>
<
Space
>
<
Checkbox
<
Checkbox
name
=
'model_limits_enabled'
name
=
'model_limits_enabled'
...
@@ -405,7 +425,7 @@ const EditToken = (props) => {
...
@@ -405,7 +425,7 @@ const EditToken = (props) => {
<
/div
>
<
/div
>
<
Select
<
Select
style
=
{{
marginTop
:
8
}}
style
=
{{
marginTop
:
8
}}
placeholder
=
{
'请选择该渠道所支持的模型'
}
placeholder
=
{
'请选择该渠道所支持的模型'
}
name
=
'models'
name
=
'models'
required
required
...
@@ -419,6 +439,23 @@ const EditToken = (props) => {
...
@@ -419,6 +439,23 @@ const EditToken = (props) => {
optionList
=
{
models
}
optionList
=
{
models
}
disabled
=
{
!
model_limits_enabled
}
disabled
=
{
!
model_limits_enabled
}
/
>
/
>
<
div
style
=
{{
marginTop
:
10
}}
>
<
Typography
.
Text
>
令牌分组,不选为默认分组
<
/Typography.Text
>
<
/div
>
<
Select
style
=
{{
marginTop
:
8
}}
placeholder
=
{
'令牌分组,不选为默认分组'
}
name
=
'gruop'
required
selection
onChange
=
{(
value
)
=>
{
handleInputChange
(
'group'
,
value
);
}}
value
=
{
inputs
.
group
}
autoComplete
=
'new-password'
optionList
=
{
groups
}
/
>
<
/Spin
>
<
/Spin
>
<
/SideSheet
>
<
/SideSheet
>
<
/
>
<
/
>
...
...
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