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
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
98 additions
and
7 deletions
+98
-7
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
+0
-0
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) {
"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) {
ModelLimitsEnabled
:
token
.
ModelLimitsEnabled
,
ModelLimits
:
token
.
ModelLimits
,
AllowIps
:
token
.
AllowIps
,
Group
:
token
.
Group
,
}
err
=
cleanToken
.
Insert
()
if
err
!=
nil
{
...
...
@@ -223,6 +224,7 @@ func UpdateToken(c *gin.Context) {
cleanToken
.
ModelLimitsEnabled
=
token
.
ModelLimitsEnabled
cleanToken
.
ModelLimits
=
token
.
ModelLimits
cleanToken
.
AllowIps
=
token
.
AllowIps
cleanToken
.
Group
=
token
.
Group
}
err
=
cleanToken
.
Update
()
if
err
!=
nil
{
...
...
middleware/auth.go
View file @
4a02eb1b
...
...
@@ -176,6 +176,7 @@ func TokenAuth() func(c *gin.Context) {
c
.
Set
(
"token_model_limit_enabled"
,
false
)
}
c
.
Set
(
"allow_ips"
,
token
.
GetIpLimitsMap
())
c
.
Set
(
"token_group"
,
token
.
Group
)
if
len
(
parts
)
>
1
{
if
model
.
IsAdmin
(
token
.
UserId
)
{
c
.
Set
(
"specific_channel_id"
,
parts
[
1
])
...
...
middleware/distributor.go
View file @
4a02eb1b
...
...
@@ -39,6 +39,15 @@ func Distribute() func(c *gin.Context) {
return
}
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
)
if
ok
{
id
,
err
:=
strconv
.
Atoi
(
channelId
.
(
string
))
...
...
model/option.go
View file @
4a02eb1b
...
...
@@ -86,6 +86,7 @@ func InitOptionMap() {
common
.
OptionMap
[
"ModelRatio"
]
=
common
.
ModelRatio2JSONString
()
common
.
OptionMap
[
"ModelPrice"
]
=
common
.
ModelPrice2JSONString
()
common
.
OptionMap
[
"GroupRatio"
]
=
common
.
GroupRatio2JSONString
()
common
.
OptionMap
[
"UserUsableGroups"
]
=
common
.
UserUsableGroups2JSONString
()
common
.
OptionMap
[
"CompletionRatio"
]
=
common
.
CompletionRatio2JSONString
()
common
.
OptionMap
[
"TopUpLink"
]
=
common
.
TopUpLink
common
.
OptionMap
[
"ChatLink"
]
=
common
.
ChatLink
...
...
@@ -303,6 +304,8 @@ func updateOptionMap(key string, value string) (err error) {
err
=
common
.
UpdateModelRatioByJSONString
(
value
)
case
"GroupRatio"
:
err
=
common
.
UpdateGroupRatioByJSONString
(
value
)
case
"UserUsableGroups"
:
err
=
common
.
UpdateUserUsableGroupsByJSONString
(
value
)
case
"CompletionRatio"
:
err
=
common
.
UpdateCompletionRatioByJSONString
(
value
)
case
"ModelPrice"
:
...
...
model/token.go
View file @
4a02eb1b
...
...
@@ -25,6 +25,7 @@ type Token struct {
ModelLimits
string
`json:"model_limits" gorm:"type:varchar(1024);default:''"`
AllowIps
*
string
`json:"allow_ips" gorm:"default:''"`
UsedQuota
int
`json:"used_quota" gorm:"default:0"`
// used quota
Group
string
`json:"group" gorm:"default:''"`
DeletedAt
gorm
.
DeletedAt
`gorm:"index"`
}
...
...
@@ -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
func
(
token
*
Token
)
Update
()
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
}
...
...
router/api-router.go
View file @
4a02eb1b
...
...
@@ -39,6 +39,7 @@ func SetApiRouter(router *gin.Engine) {
//userRoute.POST("/tokenlog", middleware.CriticalRateLimit(), controller.TokenLog)
userRoute
.
GET
(
"/logout"
,
controller
.
Logout
)
userRoute
.
GET
(
"/epay/notify"
,
controller
.
EpayNotify
)
userRoute
.
GET
(
"/groups"
,
controller
.
GetUserGroups
)
selfRoute
:=
userRoute
.
Group
(
"/"
)
selfRoute
.
Use
(
middleware
.
UserAuth
())
...
...
web/src/components/OperationSetting.js
View file @
4a02eb1b
...
...
@@ -23,6 +23,7 @@ const OperationSetting = () => {
CompletionRatio
:
''
,
ModelPrice
:
''
,
GroupRatio
:
''
,
UserUsableGroups
:
''
,
TopUpLink
:
''
,
ChatLink
:
''
,
ChatLink2
:
''
,
// 添加的新状态变量
...
...
@@ -62,6 +63,7 @@ const OperationSetting = () => {
if
(
item
.
key
===
'ModelRatio'
||
item
.
key
===
'GroupRatio'
||
item
.
key
===
'UserUsableGroups'
||
item
.
key
===
'CompletionRatio'
||
item
.
key
===
'ModelPrice'
)
{
...
...
web/src/components/TokensTable.js
View file @
4a02eb1b
...
...
@@ -8,14 +8,14 @@ import {
}
from
'../helpers'
;
import
{
ITEMS_PER_PAGE
}
from
'../constants'
;
import
{
renderQuota
}
from
'../helpers/render'
;
import
{
renderGroup
,
renderQuota
}
from
'../helpers/render'
;
import
{
Button
,
Dropdown
,
Form
,
Modal
,
Popconfirm
,
Popover
,
Popover
,
Space
,
SplitButtonGroup
,
Table
,
Tag
,
...
...
@@ -119,7 +119,12 @@ const TokensTable = () => {
dataIndex
:
'status'
,
key
:
'status'
,
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) {
export
function
renderGroup
(
group
)
{
if
(
group
===
''
)
{
return
(
<
Tag
size
=
'large'
key
=
'default'
>
unknown
<
Tag
size
=
'large'
key
=
'default'
color
=
{
stringToColor
(
'default'
)}
>
default
<
/Tag
>
);
}
...
...
web/src/pages/Setting/Operation/SettingsMagnification.js
View file @
4a02eb1b
...
...
@@ -16,7 +16,8 @@ export default function SettingsMagnification(props) {
ModelPrice
:
''
,
ModelRatio
:
''
,
CompletionRatio
:
''
,
GroupRatio
:
''
GroupRatio
:
''
,
UserUsableGroups
:
''
});
const
refForm
=
useRef
();
const
[
inputsRow
,
setInputsRow
]
=
useState
(
inputs
);
...
...
@@ -213,6 +214,33 @@ export default function SettingsMagnification(props) {
/
>
<
/Col
>
<
/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
>
<
Space
>
...
...
web/src/pages/Token/EditToken.js
View file @
4a02eb1b
This diff is collapsed.
Click to expand it.
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