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
28e8e89e
authored
Apr 23, 2023
by
JustSong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Able to manage channels now
parent
9ca6adf4
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
189 additions
and
209 deletions
+189
-209
common/constants.go
+8
-3
controller/channel.go
+3
-0
model/channel.go
+1
-1
web/src/components/ChannelsTable.js
+112
-105
web/src/components/TokensTable.js
+1
-1
web/src/constants/channel.constants.js
+9
-0
web/src/constants/index.js
+3
-2
web/src/pages/Channel/AddChannel.js
+27
-27
web/src/pages/Channel/EditChannel.js
+25
-70
No files found.
common/constants.go
View file @
28e8e89e
...
...
@@ -91,7 +91,12 @@ const (
)
const
(
ChannelTypeUnknown
=
0
ChannelTypeOpenAI
=
1
ChannelTypeAPI2D
=
2
ChannelTypeUnknown
=
0
ChannelTypeOpenAI
=
1
ChannelTypeAPI2D
=
2
ChannelTypeAzure
=
3
ChannelTypeCloseAI
=
4
ChannelTypeOpenAISB
=
5
ChannelTypeOpenAIMax
=
6
ChannelTypeOhMyGPT
=
7
)
controller/channel.go
View file @
28e8e89e
...
...
@@ -82,6 +82,8 @@ func AddChannel(c *gin.Context) {
})
return
}
channel
.
CreatedTime
=
common
.
GetTimestamp
()
channel
.
AccessedTime
=
common
.
GetTimestamp
()
err
=
channel
.
Insert
()
if
err
!=
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
...
...
@@ -136,6 +138,7 @@ func UpdateChannel(c *gin.Context) {
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
true
,
"message"
:
""
,
"data"
:
channel
,
})
return
}
model/channel.go
View file @
28e8e89e
...
...
@@ -9,7 +9,7 @@ type Channel struct {
Type
int
`json:"type" gorm:"default:0"`
Key
string
`json:"key"`
Status
int
`json:"status" gorm:"default:1"`
Name
string
`json:"name" gorm:"
unique;
index"`
Name
string
`json:"name" gorm:"index"`
Weight
int
`json:"weight"`
CreatedTime
int64
`json:"created_time" gorm:"bigint"`
AccessedTime
int64
`json:"accessed_time" gorm:"bigint"`
...
...
web/src/components/ChannelsTable.js
View file @
28e8e89e
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
Button
,
Form
,
Label
,
Pagination
,
Table
}
from
'semantic-ui-react'
;
import
{
Link
}
from
'react-router-dom'
;
import
{
API
,
showError
,
showSuccess
}
from
'../helpers'
;
import
{
API
,
copy
,
showError
,
showSuccess
,
timestamp2string
}
from
'../helpers'
;
import
{
ITEMS_PER_PAGE
}
from
'../constants'
;
import
{
CHANNEL_OPTIONS
,
ITEMS_PER_PAGE
}
from
'../constants'
;
function
renderRole
(
role
)
{
switch
(
role
)
{
case
1
:
return
<
Label
>
普通用户
<
/Label>
;
case
10
:
return
<
Label
color
=
'yellow'
>
管理员
<
/Label>
;
case
100
:
return
<
Label
color
=
'orange'
>
超级管理员
<
/Label>
;
default
:
return
<
Label
color
=
'red'
>
未知身份
<
/Label>
;
function
renderTimestamp
(
timestamp
)
{
return
(
<>
{
timestamp2string
(
timestamp
)}
<
/
>
);
}
let
type2label
=
undefined
;
function
renderType
(
type
)
{
if
(
!
type2label
)
{
type2label
=
new
Map
;
for
(
let
i
=
0
;
i
<
CHANNEL_OPTIONS
.
length
;
i
++
)
{
type2label
[
CHANNEL_OPTIONS
[
i
].
value
]
=
CHANNEL_OPTIONS
[
i
];
}
type2label
[
0
]
=
{
value
:
0
,
text
:
'未知类型'
,
color
:
'grey'
};
}
return
<
Label
basic
color
=
{
type2label
[
type
].
color
}
>
{
type2label
[
type
].
text
}
<
/Label>
;
}
const
ChannelsTable
=
()
=>
{
const
[
users
,
setUser
s
]
=
useState
([]);
const
[
channels
,
setChannel
s
]
=
useState
([]);
const
[
loading
,
setLoading
]
=
useState
(
true
);
const
[
activePage
,
setActivePage
]
=
useState
(
1
);
const
[
searchKeyword
,
setSearchKeyword
]
=
useState
(
''
);
const
[
searching
,
setSearching
]
=
useState
(
false
);
const
load
User
s
=
async
(
startIdx
)
=>
{
const
res
=
await
API
.
get
(
`/api/
user
/?p=
${
startIdx
}
`
);
const
load
Channel
s
=
async
(
startIdx
)
=>
{
const
res
=
await
API
.
get
(
`/api/
channel
/?p=
${
startIdx
}
`
);
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
if
(
startIdx
===
0
)
{
set
User
s
(
data
);
set
Channel
s
(
data
);
}
else
{
let
new
Users
=
user
s
;
new
User
s
.
push
(...
data
);
set
Users
(
newUser
s
);
let
new
Channels
=
channel
s
;
new
Channel
s
.
push
(...
data
);
set
Channels
(
newChannel
s
);
}
}
else
{
showError
(
message
);
...
...
@@ -44,55 +52,63 @@ const ChannelsTable = () => {
const
onPaginationChange
=
(
e
,
{
activePage
})
=>
{
(
async
()
=>
{
if
(
activePage
===
Math
.
ceil
(
user
s
.
length
/
ITEMS_PER_PAGE
)
+
1
)
{
if
(
activePage
===
Math
.
ceil
(
channel
s
.
length
/
ITEMS_PER_PAGE
)
+
1
)
{
// In this case we have to load more data and then append them.
await
load
User
s
(
activePage
-
1
);
await
load
Channel
s
(
activePage
-
1
);
}
setActivePage
(
activePage
);
})();
};
useEffect
(()
=>
{
load
User
s
(
0
)
load
Channel
s
(
0
)
.
then
()
.
catch
((
reason
)
=>
{
showError
(
reason
);
});
},
[]);
const
manageUser
=
(
username
,
action
,
idx
)
=>
{
(
async
()
=>
{
const
res
=
await
API
.
post
(
'/api/user/manage'
,
{
username
,
action
,
});
const
{
success
,
message
}
=
res
.
data
;
if
(
success
)
{
showSuccess
(
'操作成功完成!'
);
let
user
=
res
.
data
.
data
;
let
newUsers
=
[...
users
];
let
realIdx
=
(
activePage
-
1
)
*
ITEMS_PER_PAGE
+
idx
;
if
(
action
===
'delete'
)
{
newUsers
[
realIdx
].
deleted
=
true
;
}
else
{
newUsers
[
realIdx
].
status
=
user
.
status
;
newUsers
[
realIdx
].
role
=
user
.
role
;
}
setUsers
(
newUsers
);
const
manageChannel
=
async
(
id
,
action
,
idx
)
=>
{
let
data
=
{
id
};
let
res
;
switch
(
action
)
{
case
'delete'
:
res
=
await
API
.
delete
(
`/api/channel/
${
id
}
/`
);
break
;
case
'enable'
:
data
.
status
=
1
;
res
=
await
API
.
put
(
'/api/channel/'
,
data
);
break
;
case
'disable'
:
data
.
status
=
2
;
res
=
await
API
.
put
(
'/api/channel/'
,
data
);
break
;
}
const
{
success
,
message
}
=
res
.
data
;
if
(
success
)
{
showSuccess
(
'操作成功完成!'
);
let
channel
=
res
.
data
.
data
;
let
newChannels
=
[...
channels
];
let
realIdx
=
(
activePage
-
1
)
*
ITEMS_PER_PAGE
+
idx
;
if
(
action
===
'delete'
)
{
newChannels
[
realIdx
].
deleted
=
true
;
}
else
{
showError
(
message
)
;
newChannels
[
realIdx
].
status
=
channel
.
status
;
}
})();
setChannels
(
newChannels
);
}
else
{
showError
(
message
);
}
};
const
renderStatus
=
(
status
)
=>
{
switch
(
status
)
{
case
1
:
return
<
Label
basic
>
已激活
<
/Label>
;
return
<
Label
basic
color
=
'green'
>
已启用
<
/Label>
;
case
2
:
return
(
<
Label
basic
color
=
'red'
>
已
封禁
已
禁用
<
/Label
>
);
default
:
...
...
@@ -104,18 +120,18 @@ const ChannelsTable = () => {
}
};
const
search
User
s
=
async
()
=>
{
const
search
Channel
s
=
async
()
=>
{
if
(
searchKeyword
===
''
)
{
// if keyword is blank, load files instead.
await
load
User
s
(
0
);
await
load
Channel
s
(
0
);
setActivePage
(
1
);
return
;
}
setSearching
(
true
);
const
res
=
await
API
.
get
(
`/api/
user
/search?keyword=
${
searchKeyword
}
`
);
const
res
=
await
API
.
get
(
`/api/
channel
/search?keyword=
${
searchKeyword
}
`
);
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
set
User
s
(
data
);
set
Channel
s
(
data
);
setActivePage
(
1
);
}
else
{
showError
(
message
);
...
...
@@ -127,28 +143,28 @@ const ChannelsTable = () => {
setSearchKeyword
(
value
.
trim
());
};
const
sort
User
=
(
key
)
=>
{
if
(
user
s
.
length
===
0
)
return
;
const
sort
Channel
=
(
key
)
=>
{
if
(
channel
s
.
length
===
0
)
return
;
setLoading
(
true
);
let
sorted
Users
=
[...
user
s
];
sorted
User
s
.
sort
((
a
,
b
)
=>
{
let
sorted
Channels
=
[...
channel
s
];
sorted
Channel
s
.
sort
((
a
,
b
)
=>
{
return
(
''
+
a
[
key
]).
localeCompare
(
b
[
key
]);
});
if
(
sorted
Users
[
0
].
id
===
user
s
[
0
].
id
)
{
sorted
User
s
.
reverse
();
if
(
sorted
Channels
[
0
].
id
===
channel
s
[
0
].
id
)
{
sorted
Channel
s
.
reverse
();
}
set
Users
(
sortedUser
s
);
set
Channels
(
sortedChannel
s
);
setLoading
(
false
);
};
return
(
<>
<
Form
onSubmit
=
{
search
User
s
}
>
<
Form
onSubmit
=
{
search
Channel
s
}
>
<
Form
.
Input
icon
=
'search'
fluid
iconPosition
=
'left'
placeholder
=
'搜索
用户的 ID,用户名,显示名称,以及邮箱地址
...'
placeholder
=
'搜索
渠道的 ID 和名称
...'
value
=
{
searchKeyword
}
loading
=
{
searching
}
onChange
=
{
handleKeywordChange
}
...
...
@@ -161,87 +177,78 @@ const ChannelsTable = () => {
<
Table
.
HeaderCell
style
=
{{
cursor
:
'pointer'
}}
onClick
=
{()
=>
{
sort
User
(
'username
'
);
sort
Channel
(
'id
'
);
}}
>
用户名
ID
<
/Table.HeaderCell
>
<
Table
.
HeaderCell
style
=
{{
cursor
:
'pointer'
}}
onClick
=
{()
=>
{
sort
User
(
'display_
name'
);
sort
Channel
(
'
name'
);
}}
>
显示
名称
名称
<
/Table.HeaderCell
>
<
Table
.
HeaderCell
style
=
{{
cursor
:
'pointer'
}}
onClick
=
{()
=>
{
sort
User
(
'email
'
);
sort
Channel
(
'type
'
);
}}
>
邮箱地址
类型
<
/Table.HeaderCell
>
<
Table
.
HeaderCell
style
=
{{
cursor
:
'pointer'
}}
onClick
=
{()
=>
{
sort
User
(
'role
'
);
sort
Channel
(
'status
'
);
}}
>
用户角色
状态
<
/Table.HeaderCell
>
<
Table
.
HeaderCell
style
=
{{
cursor
:
'pointer'
}}
onClick
=
{()
=>
{
sort
User
(
'status
'
);
sort
Channel
(
'created_time
'
);
}}
>
状态
创建时间
<
/Table.HeaderCell
>
<
Table
.
HeaderCell
style
=
{{
cursor
:
'pointer'
}}
onClick
=
{()
=>
{
sortChannel
(
'accessed_time'
);
}}
>
访问时间
<
/Table.HeaderCell
>
<
Table
.
HeaderCell
>
操作
<
/Table.HeaderCell
>
<
/Table.Row
>
<
/Table.Header
>
<
Table
.
Body
>
{
user
s
{
channel
s
.
slice
(
(
activePage
-
1
)
*
ITEMS_PER_PAGE
,
activePage
*
ITEMS_PER_PAGE
)
.
map
((
user
,
idx
)
=>
{
if
(
user
.
deleted
)
return
<><
/>
;
.
map
((
channel
,
idx
)
=>
{
if
(
channel
.
deleted
)
return
<><
/>
;
return
(
<
Table
.
Row
key
=
{
user
.
id
}
>
<
Table
.
Cell
>
{
user
.
username
}
<
/Table.Cell
>
<
Table
.
Cell
>
{
user
.
display_name
}
<
/Table.Cell
>
<
Table
.
Cell
>
{
user
.
email
?
user
.
email
:
'无'
}
<
/Table.Cell
>
<
Table
.
Cell
>
{
renderRole
(
user
.
role
)}
<
/Table.Cell
>
<
Table
.
Cell
>
{
renderStatus
(
user
.
status
)}
<
/Table.Cell
>
<
Table
.
Row
key
=
{
channel
.
id
}
>
<
Table
.
Cell
>
{
channel
.
id
}
<
/Table.Cell
>
<
Table
.
Cell
>
{
channel
.
name
?
channel
.
name
:
'无'
}
<
/Table.Cell
>
<
Table
.
Cell
>
{
renderType
(
channel
.
type
)}
<
/Table.Cell
>
<
Table
.
Cell
>
{
renderStatus
(
channel
.
status
)}
<
/Table.Cell
>
<
Table
.
Cell
>
{
renderTimestamp
(
channel
.
created_time
)}
<
/Table.Cell
>
<
Table
.
Cell
>
{
renderTimestamp
(
channel
.
accessed_time
)}
<
/Table.Cell
>
<
Table
.
Cell
>
<
div
>
<
Button
size
=
{
'small'
}
positive
onClick
=
{()
=>
{
manageUser
(
user
.
username
,
'promote'
,
idx
);
}}
>
提升
<
/Button
>
<
Button
size
=
{
'small'
}
color
=
{
'yellow'
}
onClick
=
{()
=>
{
manageUser
(
user
.
username
,
'demote'
,
idx
);
}}
>
降级
<
/Button
>
<
Button
size
=
{
'small'
}
negative
onClick
=
{()
=>
{
manage
User
(
user
.
username
,
'delete'
,
idx
);
manage
Channel
(
channel
.
id
,
'delete'
,
idx
);
}}
>
删除
...
...
@@ -249,19 +256,19 @@ const ChannelsTable = () => {
<
Button
size
=
{
'small'
}
onClick
=
{()
=>
{
manage
User
(
user
.
username
,
user
.
status
===
1
?
'disable'
:
'enable'
,
manage
Channel
(
channel
.
id
,
channel
.
status
===
1
?
'disable'
:
'enable'
,
idx
);
}}
>
{
user
.
status
===
1
?
'禁用'
:
'启用'
}
{
channel
.
status
===
1
?
'禁用'
:
'启用'
}
<
/Button
>
<
Button
size
=
{
'small'
}
as
=
{
Link
}
to
=
{
'/
user/edit/'
+
user
.
id
}
to
=
{
'/
channel/edit/'
+
channel
.
id
}
>
编辑
<
/Button
>
...
...
@@ -275,8 +282,8 @@ const ChannelsTable = () => {
<
Table
.
Footer
>
<
Table
.
Row
>
<
Table
.
HeaderCell
colSpan
=
'6'
>
<
Button
size
=
'small'
as
=
{
Link
}
to
=
'/
user
/add'
loading
=
{
loading
}
>
添加新的
用户
<
Button
size
=
'small'
as
=
{
Link
}
to
=
'/
channel
/add'
loading
=
{
loading
}
>
添加新的
渠道
<
/Button
>
<
Pagination
floated
=
'right'
...
...
@@ -285,8 +292,8 @@ const ChannelsTable = () => {
size
=
'small'
siblingRange
=
{
1
}
totalPages
=
{
Math
.
ceil
(
user
s
.
length
/
ITEMS_PER_PAGE
)
+
(
user
s
.
length
%
ITEMS_PER_PAGE
===
0
?
1
:
0
)
Math
.
ceil
(
channel
s
.
length
/
ITEMS_PER_PAGE
)
+
(
channel
s
.
length
%
ITEMS_PER_PAGE
===
0
?
1
:
0
)
}
/
>
<
/Table.HeaderCell
>
...
...
web/src/components/TokensTable.js
View file @
28e8e89e
...
...
@@ -115,7 +115,7 @@ const TokensTable = () => {
return
;
}
setSearching
(
true
);
const
res
=
await
API
.
get
(
`/api/token/search?keyword=
${
searchKeyword
}
/
`
);
const
res
=
await
API
.
get
(
`/api/token/search?keyword=
${
searchKeyword
}
`
);
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
setTokens
(
data
);
...
...
web/src/constants/channel.constants.js
0 → 100644
View file @
28e8e89e
export
const
CHANNEL_OPTIONS
=
[
{
key
:
1
,
text
:
'OpenAI'
,
value
:
1
,
color
:
'green'
},
{
key
:
2
,
text
:
'API2D'
,
value
:
2
,
color
:
'blue'
},
{
key
:
3
,
text
:
'Azure'
,
value
:
3
,
color
:
'olive'
},
{
key
:
4
,
text
:
'CloseAI'
,
value
:
4
,
color
:
'teal'
},
{
key
:
5
,
text
:
'OpenAI-SB'
,
value
:
5
,
color
:
'brown'
},
{
key
:
6
,
text
:
'OpenAI Max'
,
value
:
6
,
color
:
'violet'
},
{
key
:
7
,
text
:
'OhMyGPT'
,
value
:
7
,
color
:
'purple'
}
];
web/src/constants/index.js
View file @
28e8e89e
export
*
from
'./toast.constants'
;
export
*
from
'./user.constants'
;
export
*
from
'./common.constant'
;
\ No newline at end of file
export
*
from
'./common.constant'
;
export
*
from
'./channel.constants'
;
\ No newline at end of file
web/src/pages/Channel/AddChannel.js
View file @
28e8e89e
import
React
,
{
useState
}
from
'react'
;
import
{
Button
,
Form
,
Header
,
Segment
}
from
'semantic-ui-react'
;
import
{
API
,
showError
,
showSuccess
}
from
'../../helpers'
;
import
{
CHANNEL_OPTIONS
}
from
'../../constants'
;
const
AddChannel
=
()
=>
{
const
originInputs
=
{
user
name
:
''
,
display_name
:
''
,
password
:
''
,
name
:
''
,
type
:
1
,
key
:
''
};
const
[
inputs
,
setInputs
]
=
useState
(
originInputs
);
const
{
username
,
display_name
,
password
}
=
inputs
;
const
{
name
,
type
,
key
}
=
inputs
;
const
handleInputChange
=
(
e
,
{
name
,
value
})
=>
{
setInputs
((
inputs
)
=>
({
...
inputs
,
[
name
]:
value
}));
};
const
submit
=
async
()
=>
{
if
(
inputs
.
username
===
''
||
inputs
.
password
===
''
)
return
;
const
res
=
await
API
.
post
(
`/api/
user
/`
,
inputs
);
if
(
inputs
.
name
===
''
||
inputs
.
key
===
''
)
return
;
const
res
=
await
API
.
post
(
`/api/
channel
/`
,
inputs
);
const
{
success
,
message
}
=
res
.
data
;
if
(
success
)
{
showSuccess
(
'
用户账户
创建成功!'
);
showSuccess
(
'
渠道
创建成功!'
);
setInputs
(
originInputs
);
}
else
{
showError
(
message
);
...
...
@@ -30,38 +31,37 @@ const AddChannel = () => {
return
(
<>
<
Segment
>
<
Header
as
=
"h3"
>
创建新用户账户
<
/Header
>
<
Form
autoComplete
=
"off"
>
<
Header
as
=
'h3'
>
创建新的渠道
<
/Header
>
<
Form
autoComplete
=
'off'
>
<
Form
.
Field
>
<
Form
.
Input
label
=
"用户名"
name
=
"username"
placeholder
=
{
'请输入用户名'
}
<
Form
.
Select
label
=
'类型'
name
=
'type'
options
=
{
CHANNEL_OPTIONS
}
value
=
{
inputs
.
type
}
onChange
=
{
handleInputChange
}
value
=
{
username
}
autoComplete
=
"off"
required
/
>
<
/Form.Field
>
<
Form
.
Field
>
<
Form
.
Input
label
=
"显示名称"
name
=
"display_name"
placeholder
=
{
'请输入
显示
名称'
}
label
=
'名称'
name
=
'name'
placeholder
=
{
'请输入名称'
}
onChange
=
{
handleInputChange
}
value
=
{
display_name
}
autoComplete
=
"off"
value
=
{
name
}
autoComplete
=
'off'
required
/>
<
/Form.Field
>
<
Form
.
Field
>
<
Form
.
Input
label
=
"密码"
name
=
"password"
type
=
{
'password'
}
placeholder
=
{
'请输入密码'
}
label
=
'密钥'
name
=
'key'
placeholder
=
{
'请输入密钥'
}
onChange
=
{
handleInputChange
}
value
=
{
password
}
autoComplete
=
"off"
value
=
{
key
}
// type='password'
autoComplete
=
'off'
required
/>
<
/Form.Field
>
...
...
web/src/pages/Channel/EditChannel.js
View file @
28e8e89e
...
...
@@ -2,32 +2,23 @@ import React, { useEffect, useState } from 'react';
import
{
Button
,
Form
,
Header
,
Segment
}
from
'semantic-ui-react'
;
import
{
useParams
}
from
'react-router-dom'
;
import
{
API
,
showError
,
showSuccess
}
from
'../../helpers'
;
import
{
CHANNEL_OPTIONS
}
from
'../../constants'
;
const
EditChannel
=
()
=>
{
const
params
=
useParams
();
const
user
Id
=
params
.
id
;
const
channel
Id
=
params
.
id
;
const
[
loading
,
setLoading
]
=
useState
(
true
);
const
[
inputs
,
setInputs
]
=
useState
({
username
:
''
,
display_name
:
''
,
password
:
''
,
github_id
:
''
,
wechat_id
:
''
,
email
:
''
,
name
:
''
,
key
:
''
,
type
:
1
,
});
const
{
username
,
display_name
,
password
,
github_id
,
wechat_id
,
email
}
=
inputs
;
const
handleInputChange
=
(
e
,
{
name
,
value
})
=>
{
setInputs
((
inputs
)
=>
({
...
inputs
,
[
name
]:
value
}));
};
const
loadUser
=
async
()
=>
{
let
res
=
undefined
;
if
(
userId
)
{
res
=
await
API
.
get
(
`/api/user/
${
userId
}
`
);
}
else
{
res
=
await
API
.
get
(
`/api/user/self`
);
}
const
loadChannel
=
async
()
=>
{
let
res
=
await
API
.
get
(
`/api/channel/
${
channelId
}
`
);
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
data
.
password
=
''
;
...
...
@@ -38,19 +29,14 @@ const EditChannel = () => {
setLoading
(
false
);
};
useEffect
(()
=>
{
load
User
().
then
();
load
Channel
().
then
();
},
[]);
const
submit
=
async
()
=>
{
let
res
=
undefined
;
if
(
userId
)
{
res
=
await
API
.
put
(
`/api/user/`
,
{
...
inputs
,
id
:
parseInt
(
userId
)
});
}
else
{
res
=
await
API
.
put
(
`/api/user/self`
,
inputs
);
}
let
res
=
await
API
.
put
(
`/api/channel/`
,
{
...
inputs
,
id
:
parseInt
(
channelId
)
});
const
{
success
,
message
}
=
res
.
data
;
if
(
success
)
{
showSuccess
(
'
用户信息
更新成功!'
);
showSuccess
(
'
渠道
更新成功!'
);
}
else
{
showError
(
message
);
}
...
...
@@ -59,67 +45,36 @@ const EditChannel = () => {
return
(
<>
<
Segment
loading
=
{
loading
}
>
<
Header
as
=
'h3'
>
更新
用户
信息
<
/Header
>
<
Header
as
=
'h3'
>
更新
渠道
信息
<
/Header
>
<
Form
autoComplete
=
'off'
>
<
Form
.
Field
>
<
Form
.
Input
label
=
'用户名'
name
=
'username'
placeholder
=
{
'请输入新的用户名'
}
<
Form
.
Select
label
=
'类型'
name
=
'type'
options
=
{
CHANNEL_OPTIONS
}
value
=
{
inputs
.
type
}
onChange
=
{
handleInputChange
}
value
=
{
username
}
autoComplete
=
'off'
/
>
<
/Form.Field
>
<
Form
.
Field
>
<
Form
.
Input
label
=
'密码'
name
=
'password'
type
=
{
'password'
}
placeholder
=
{
'请输入新的密码'
}
label
=
'名称'
name
=
'name'
placeholder
=
{
'请输入新的名称'
}
onChange
=
{
handleInputChange
}
value
=
{
password
}
value
=
{
inputs
.
name
}
autoComplete
=
'off'
/>
<
/Form.Field
>
<
Form
.
Field
>
<
Form
.
Input
label
=
'
显示名称
'
name
=
'
display_name
'
placeholder
=
{
'请输入新的
显示名称
'
}
label
=
'
密钥
'
name
=
'
key
'
placeholder
=
{
'请输入新的
密钥
'
}
onChange
=
{
handleInputChange
}
value
=
{
display_name
}
autoComplete
=
'off'
/>
<
/Form.Field
>
<
Form
.
Field
>
<
Form
.
Input
label
=
'已绑定的 GitHub 账户'
name
=
'github_id'
value
=
{
github_id
}
autoComplete
=
'off'
placeholder
=
'此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
readOnly
/>
<
/Form.Field
>
<
Form
.
Field
>
<
Form
.
Input
label
=
'已绑定的微信账户'
name
=
'wechat_id'
value
=
{
wechat_id
}
autoComplete
=
'off'
placeholder
=
'此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
readOnly
/>
<
/Form.Field
>
<
Form
.
Field
>
<
Form
.
Input
label
=
'已绑定的邮箱账户'
name
=
'email'
value
=
{
email
}
value
=
{
inputs
.
key
}
// type='password'
autoComplete
=
'off'
placeholder
=
'此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
readOnly
/>
<
/Form.Field
>
<
Button
onClick
=
{
submit
}
>
提交
<
/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