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
bc0b1b86
authored
Nov 12, 2024
by
licoy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化设置页面的模块间距与部分数据获取提示
parent
11cc44b4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
745 additions
and
744 deletions
+745
-744
web/src/components/OperationSetting.js
+1
-1
web/src/components/PersonalSetting.js
+744
-743
No files found.
web/src/components/OperationSetting.js
View file @
bc0b1b86
...
@@ -90,7 +90,7 @@ const OperationSetting = () => {
...
@@ -90,7 +90,7 @@ const OperationSetting = () => {
try
{
try
{
setLoading
(
true
);
setLoading
(
true
);
await
getOptions
();
await
getOptions
();
showSuccess
(
'刷新成功'
);
//
showSuccess('刷新成功');
}
catch
(
error
)
{
}
catch
(
error
)
{
showError
(
'刷新失败'
);
showError
(
'刷新失败'
);
}
finally
{
}
finally
{
...
...
web/src/components/PersonalSetting.js
View file @
bc0b1b86
import
React
,
{
useContext
,
useEffect
,
useState
}
from
'react'
;
import
React
,
{
useContext
,
useEffect
,
useState
}
from
'react'
;
import
{
useNavigate
}
from
'react-router-dom'
;
import
{
useNavigate
}
from
'react-router-dom'
;
import
{
import
{
API
,
API
,
copy
,
copy
,
isRoot
,
isRoot
,
showError
,
showError
,
showInfo
,
showInfo
,
showSuccess
,
showSuccess
,
}
from
'../helpers'
;
}
from
'../helpers'
;
import
Turnstile
from
'react-turnstile'
;
import
Turnstile
from
'react-turnstile'
;
import
{
UserContext
}
from
'../context/User'
;
import
{
UserContext
}
from
'../context/User'
;
import
{
onGitHubOAuthClicked
,
onLinuxDOOAuthClicked
}
from
'./utils'
;
import
{
onGitHubOAuthClicked
,
onLinuxDOOAuthClicked
}
from
'./utils'
;
import
{
import
{
Avatar
,
Avatar
,
Banner
,
Banner
,
Button
,
Button
,
Card
,
Card
,
Descriptions
,
Descriptions
,
Image
,
Image
,
Input
,
Input
,
InputNumber
,
InputNumber
,
Layout
,
Layout
,
Modal
,
Modal
,
Space
,
Space
,
Tag
,
Tag
,
Typography
,
Typography
,
}
from
'@douyinfe/semi-ui'
;
}
from
'@douyinfe/semi-ui'
;
import
{
import
{
getQuotaPerUnit
,
getQuotaPerUnit
,
renderQuota
,
renderQuota
,
renderQuotaWithPrompt
,
renderQuotaWithPrompt
,
stringToColor
,
stringToColor
,
}
from
'../helpers/render'
;
}
from
'../helpers/render'
;
import
TelegramLoginButton
from
'react-telegram-login'
;
import
TelegramLoginButton
from
'react-telegram-login'
;
const
PersonalSetting
=
()
=>
{
const
PersonalSetting
=
()
=>
{
const
[
userState
,
userDispatch
]
=
useContext
(
UserContext
);
const
[
userState
,
userDispatch
]
=
useContext
(
UserContext
);
let
navigate
=
useNavigate
();
let
navigate
=
useNavigate
();
const
[
inputs
,
setInputs
]
=
useState
({
const
[
inputs
,
setInputs
]
=
useState
({
wechat_verification_code
:
''
,
wechat_verification_code
:
''
,
email_verification_code
:
''
,
email_verification_code
:
''
,
email
:
''
,
email
:
''
,
self_account_deletion_confirmation
:
''
,
self_account_deletion_confirmation
:
''
,
set_new_password
:
''
,
set_new_password
:
''
,
set_new_password_confirmation
:
''
,
set_new_password_confirmation
:
''
,
});
});
const
[
status
,
setStatus
]
=
useState
({});
const
[
status
,
setStatus
]
=
useState
({});
const
[
showChangePasswordModal
,
setShowChangePasswordModal
]
=
useState
(
false
);
const
[
showChangePasswordModal
,
setShowChangePasswordModal
]
=
useState
(
false
);
const
[
showWeChatBindModal
,
setShowWeChatBindModal
]
=
useState
(
false
);
const
[
showWeChatBindModal
,
setShowWeChatBindModal
]
=
useState
(
false
);
const
[
showEmailBindModal
,
setShowEmailBindModal
]
=
useState
(
false
);
const
[
showEmailBindModal
,
setShowEmailBindModal
]
=
useState
(
false
);
const
[
showAccountDeleteModal
,
setShowAccountDeleteModal
]
=
useState
(
false
);
const
[
showAccountDeleteModal
,
setShowAccountDeleteModal
]
=
useState
(
false
);
const
[
turnstileEnabled
,
setTurnstileEnabled
]
=
useState
(
false
);
const
[
turnstileEnabled
,
setTurnstileEnabled
]
=
useState
(
false
);
const
[
turnstileSiteKey
,
setTurnstileSiteKey
]
=
useState
(
''
);
const
[
turnstileSiteKey
,
setTurnstileSiteKey
]
=
useState
(
''
);
const
[
turnstileToken
,
setTurnstileToken
]
=
useState
(
''
);
const
[
turnstileToken
,
setTurnstileToken
]
=
useState
(
''
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
disableButton
,
setDisableButton
]
=
useState
(
false
);
const
[
disableButton
,
setDisableButton
]
=
useState
(
false
);
const
[
countdown
,
setCountdown
]
=
useState
(
30
);
const
[
countdown
,
setCountdown
]
=
useState
(
30
);
const
[
affLink
,
setAffLink
]
=
useState
(
''
);
const
[
affLink
,
setAffLink
]
=
useState
(
''
);
const
[
systemToken
,
setSystemToken
]
=
useState
(
''
);
const
[
systemToken
,
setSystemToken
]
=
useState
(
''
);
const
[
models
,
setModels
]
=
useState
([]);
const
[
models
,
setModels
]
=
useState
([]);
const
[
openTransfer
,
setOpenTransfer
]
=
useState
(
false
);
const
[
openTransfer
,
setOpenTransfer
]
=
useState
(
false
);
const
[
transferAmount
,
setTransferAmount
]
=
useState
(
0
);
const
[
transferAmount
,
setTransferAmount
]
=
useState
(
0
);
useEffect
(()
=>
{
useEffect
(()
=>
{
// let user = localStorage.getItem('user');
// let user = localStorage.getItem('user');
// if (user) {
// if (user) {
// userDispatch({ type: 'login', payload: user });
// userDispatch({ type: 'login', payload: user });
// }
// }
// console.log(localStorage.getItem('user'))
// console.log(localStorage.getItem('user'))
let
status
=
localStorage
.
getItem
(
'status'
);
let
status
=
localStorage
.
getItem
(
'status'
);
if
(
status
)
{
if
(
status
)
{
status
=
JSON
.
parse
(
status
);
status
=
JSON
.
parse
(
status
);
setStatus
(
status
);
setStatus
(
status
);
if
(
status
.
turnstile_check
)
{
if
(
status
.
turnstile_check
)
{
setTurnstileEnabled
(
true
);
setTurnstileEnabled
(
true
);
setTurnstileSiteKey
(
status
.
turnstile_site_key
);
setTurnstileSiteKey
(
status
.
turnstile_site_key
);
}
}
}
}
getUserData
().
then
((
res
)
=>
{
getUserData
().
then
((
res
)
=>
{
console
.
log
(
userState
);
console
.
log
(
userState
);
});
});
loadModels
().
then
();
loadModels
().
then
();
getAffLink
().
then
();
getAffLink
().
then
();
setTransferAmount
(
getQuotaPerUnit
());
setTransferAmount
(
getQuotaPerUnit
());
},
[]);
},
[]);
useEffect
(()
=>
{
useEffect
(()
=>
{
let
countdownInterval
=
null
;
let
countdownInterval
=
null
;
if
(
disableButton
&&
countdown
>
0
)
{
if
(
disableButton
&&
countdown
>
0
)
{
countdownInterval
=
setInterval
(()
=>
{
countdownInterval
=
setInterval
(()
=>
{
setCountdown
(
countdown
-
1
);
setCountdown
(
countdown
-
1
);
},
1000
);
},
1000
);
}
else
if
(
countdown
===
0
)
{
}
else
if
(
countdown
===
0
)
{
setDisableButton
(
false
);
setDisableButton
(
false
);
setCountdown
(
30
);
setCountdown
(
30
);
}
}
return
()
=>
clearInterval
(
countdownInterval
);
// Clean up on unmount
return
()
=>
clearInterval
(
countdownInterval
);
// Clean up on unmount
},
[
disableButton
,
countdown
]);
},
[
disableButton
,
countdown
]);
const
handleInputChange
=
(
name
,
value
)
=>
{
const
handleInputChange
=
(
name
,
value
)
=>
{
setInputs
((
inputs
)
=>
({
...
inputs
,
[
name
]:
value
}));
setInputs
((
inputs
)
=>
({...
inputs
,
[
name
]:
value
}));
};
};
const
generateAccessToken
=
async
()
=>
{
const
generateAccessToken
=
async
()
=>
{
const
res
=
await
API
.
get
(
'/api/user/token'
);
const
res
=
await
API
.
get
(
'/api/user/token'
);
const
{
success
,
message
,
data
}
=
res
.
data
;
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
setSystemToken
(
data
);
setSystemToken
(
data
);
await
copy
(
data
);
await
copy
(
data
);
showSuccess
(
`令牌已重置并已复制到剪贴板`
);
showSuccess
(
`令牌已重置并已复制到剪贴板`
);
}
else
{
}
else
{
showError
(
message
);
showError
(
message
);
}
}
};
};
const
getAffLink
=
async
()
=>
{
const
getAffLink
=
async
()
=>
{
const
res
=
await
API
.
get
(
'/api/user/aff'
);
const
res
=
await
API
.
get
(
'/api/user/aff'
);
const
{
success
,
message
,
data
}
=
res
.
data
;
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
let
link
=
`
${
window
.
location
.
origin
}
/register?aff=
${
data
}
`
;
let
link
=
`
${
window
.
location
.
origin
}
/register?aff=
${
data
}
`
;
setAffLink
(
link
);
setAffLink
(
link
);
}
else
{
}
else
{
showError
(
message
);
showError
(
message
);
}
}
};
};
const
getUserData
=
async
()
=>
{
const
getUserData
=
async
()
=>
{
let
res
=
await
API
.
get
(
`/api/user/self`
);
let
res
=
await
API
.
get
(
`/api/user/self`
);
const
{
success
,
message
,
data
}
=
res
.
data
;
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
userDispatch
({
type
:
'login'
,
payload
:
data
});
userDispatch
({
type
:
'login'
,
payload
:
data
});
}
else
{
}
else
{
showError
(
message
);
showError
(
message
);
}
}
};
};
const
loadModels
=
async
()
=>
{
const
loadModels
=
async
()
=>
{
let
res
=
await
API
.
get
(
`/api/user/models`
);
let
res
=
await
API
.
get
(
`/api/user/models`
);
const
{
success
,
message
,
data
}
=
res
.
data
;
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
setModels
(
data
);
setModels
(
data
);
console
.
log
(
data
);
console
.
log
(
data
);
}
else
{
}
else
{
showError
(
message
);
showError
(
message
);
}
}
};
};
const
handleAffLinkClick
=
async
(
e
)
=>
{
const
handleAffLinkClick
=
async
(
e
)
=>
{
e
.
target
.
select
();
e
.
target
.
select
();
await
copy
(
e
.
target
.
value
);
await
copy
(
e
.
target
.
value
);
showSuccess
(
`邀请链接已复制到剪切板`
);
showSuccess
(
`邀请链接已复制到剪切板`
);
};
};
const
handleSystemTokenClick
=
async
(
e
)
=>
{
const
handleSystemTokenClick
=
async
(
e
)
=>
{
e
.
target
.
select
();
e
.
target
.
select
();
await
copy
(
e
.
target
.
value
);
await
copy
(
e
.
target
.
value
);
showSuccess
(
`系统令牌已复制到剪切板`
);
showSuccess
(
`系统令牌已复制到剪切板`
);
};
};
const
deleteAccount
=
async
()
=>
{
const
deleteAccount
=
async
()
=>
{
if
(
inputs
.
self_account_deletion_confirmation
!==
userState
.
user
.
username
)
{
if
(
inputs
.
self_account_deletion_confirmation
!==
userState
.
user
.
username
)
{
showError
(
'请输入你的账户名以确认删除!'
);
showError
(
'请输入你的账户名以确认删除!'
);
return
;
return
;
}
}
const
res
=
await
API
.
delete
(
'/api/user/self'
);
const
res
=
await
API
.
delete
(
'/api/user/self'
);
const
{
success
,
message
}
=
res
.
data
;
const
{
success
,
message
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
showSuccess
(
'账户已删除!'
);
showSuccess
(
'账户已删除!'
);
await
API
.
get
(
'/api/user/logout'
);
await
API
.
get
(
'/api/user/logout'
);
userDispatch
({
type
:
'logout'
});
userDispatch
({
type
:
'logout'
});
localStorage
.
removeItem
(
'user'
);
localStorage
.
removeItem
(
'user'
);
navigate
(
'/login'
);
navigate
(
'/login'
);
}
else
{
}
else
{
showError
(
message
);
showError
(
message
);
}
}
};
};
const
bindWeChat
=
async
()
=>
{
const
bindWeChat
=
async
()
=>
{
if
(
inputs
.
wechat_verification_code
===
''
)
return
;
if
(
inputs
.
wechat_verification_code
===
''
)
return
;
const
res
=
await
API
.
get
(
const
res
=
await
API
.
get
(
`/api/oauth/wechat/bind?code=
${
inputs
.
wechat_verification_code
}
`
,
`/api/oauth/wechat/bind?code=
${
inputs
.
wechat_verification_code
}
`
,
);
);
const
{
success
,
message
}
=
res
.
data
;
const
{
success
,
message
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
showSuccess
(
'微信账户绑定成功!'
);
showSuccess
(
'微信账户绑定成功!'
);
setShowWeChatBindModal
(
false
);
setShowWeChatBindModal
(
false
);
}
else
{
}
else
{
showError
(
message
);
showError
(
message
);
}
}
};
};
const
changePassword
=
async
()
=>
{
const
changePassword
=
async
()
=>
{
if
(
inputs
.
set_new_password
!==
inputs
.
set_new_password_confirmation
)
{
if
(
inputs
.
set_new_password
!==
inputs
.
set_new_password_confirmation
)
{
showError
(
'两次输入的密码不一致!'
);
showError
(
'两次输入的密码不一致!'
);
return
;
return
;
}
}
const
res
=
await
API
.
put
(
`/api/user/self`
,
{
const
res
=
await
API
.
put
(
`/api/user/self`
,
{
password
:
inputs
.
set_new_password
,
password
:
inputs
.
set_new_password
,
});
});
const
{
success
,
message
}
=
res
.
data
;
const
{
success
,
message
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
showSuccess
(
'密码修改成功!'
);
showSuccess
(
'密码修改成功!'
);
setShowWeChatBindModal
(
false
);
setShowWeChatBindModal
(
false
);
}
else
{
}
else
{
showError
(
message
);
showError
(
message
);
}
}
setShowChangePasswordModal
(
false
);
setShowChangePasswordModal
(
false
);
};
};
const
transfer
=
async
()
=>
{
const
transfer
=
async
()
=>
{
if
(
transferAmount
<
getQuotaPerUnit
())
{
if
(
transferAmount
<
getQuotaPerUnit
())
{
showError
(
'划转金额最低为'
+
renderQuota
(
getQuotaPerUnit
()));
showError
(
'划转金额最低为'
+
renderQuota
(
getQuotaPerUnit
()));
return
;
return
;
}
}
const
res
=
await
API
.
post
(
`/api/user/aff_transfer`
,
{
const
res
=
await
API
.
post
(
`/api/user/aff_transfer`
,
{
quota
:
transferAmount
,
quota
:
transferAmount
,
});
});
const
{
success
,
message
}
=
res
.
data
;
const
{
success
,
message
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
showSuccess
(
message
);
showSuccess
(
message
);
setOpenTransfer
(
false
);
setOpenTransfer
(
false
);
getUserData
().
then
();
getUserData
().
then
();
}
else
{
}
else
{
showError
(
message
);
showError
(
message
);
}
}
};
};
const
sendVerificationCode
=
async
()
=>
{
const
sendVerificationCode
=
async
()
=>
{
if
(
inputs
.
email
===
''
)
{
if
(
inputs
.
email
===
''
)
{
showError
(
'请输入邮箱!'
);
showError
(
'请输入邮箱!'
);
return
;
return
;
}
}
setDisableButton
(
true
);
setDisableButton
(
true
);
if
(
turnstileEnabled
&&
turnstileToken
===
''
)
{
if
(
turnstileEnabled
&&
turnstileToken
===
''
)
{
showInfo
(
'请稍后几秒重试,Turnstile 正在检查用户环境!'
);
showInfo
(
'请稍后几秒重试,Turnstile 正在检查用户环境!'
);
return
;
return
;
}
}
setLoading
(
true
);
setLoading
(
true
);
const
res
=
await
API
.
get
(
const
res
=
await
API
.
get
(
`/api/verification?email=
${
inputs
.
email
}
&turnstile=
${
turnstileToken
}
`
,
`/api/verification?email=
${
inputs
.
email
}
&turnstile=
${
turnstileToken
}
`
,
);
);
const
{
success
,
message
}
=
res
.
data
;
const
{
success
,
message
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
showSuccess
(
'验证码发送成功,请检查邮箱!'
);
showSuccess
(
'验证码发送成功,请检查邮箱!'
);
}
else
{
}
else
{
showError
(
message
);
showError
(
message
);
}
}
setLoading
(
false
);
setLoading
(
false
);
};
};
const
bindEmail
=
async
()
=>
{
const
bindEmail
=
async
()
=>
{
if
(
inputs
.
email_verification_code
===
''
)
{
if
(
inputs
.
email_verification_code
===
''
)
{
showError
(
'请输入邮箱验证码!'
);
showError
(
'请输入邮箱验证码!'
);
return
;
return
;
}
}
setLoading
(
true
);
setLoading
(
true
);
const
res
=
await
API
.
get
(
const
res
=
await
API
.
get
(
`/api/oauth/email/bind?email=
${
inputs
.
email
}
&code=
${
inputs
.
email_verification_code
}
`
,
`/api/oauth/email/bind?email=
${
inputs
.
email
}
&code=
${
inputs
.
email_verification_code
}
`
,
);
);
const
{
success
,
message
}
=
res
.
data
;
const
{
success
,
message
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
showSuccess
(
'邮箱账户绑定成功!'
);
showSuccess
(
'邮箱账户绑定成功!'
);
setShowEmailBindModal
(
false
);
setShowEmailBindModal
(
false
);
userState
.
user
.
email
=
inputs
.
email
;
userState
.
user
.
email
=
inputs
.
email
;
}
else
{
}
else
{
showError
(
message
);
showError
(
message
);
}
}
setLoading
(
false
);
setLoading
(
false
);
};
};
const
getUsername
=
()
=>
{
const
getUsername
=
()
=>
{
if
(
userState
.
user
)
{
if
(
userState
.
user
)
{
return
userState
.
user
.
username
;
return
userState
.
user
.
username
;
}
else
{
}
else
{
return
'null'
;
return
'null'
;
}
}
};
};
const
handleCancel
=
()
=>
{
const
handleCancel
=
()
=>
{
setOpenTransfer
(
false
);
setOpenTransfer
(
false
);
};
};
const
copyText
=
async
(
text
)
=>
{
const
copyText
=
async
(
text
)
=>
{
if
(
await
copy
(
text
))
{
if
(
await
copy
(
text
))
{
showSuccess
(
'已复制:'
+
text
);
showSuccess
(
'已复制:'
+
text
);
}
else
{
}
else
{
// setSearchKeyword(text);
// setSearchKeyword(text);
Modal
.
error
({
title
:
'无法复制到剪贴板,请手动复制'
,
content
:
text
});
Modal
.
error
({
title
:
'无法复制到剪贴板,请手动复制'
,
content
:
text
});
}
}
};
};
return
(
return
(
<
div
>
<
div
>
<
Layout
>
<
Layout
>
<
Layout
.
Content
>
<
Layout
.
Content
>
<
Modal
<
Modal
title
=
'请输入要划转的数量'
title
=
'请输入要划转的数量'
visible
=
{
openTransfer
}
visible
=
{
openTransfer
}
onOk
=
{
transfer
}
onOk
=
{
transfer
}
onCancel
=
{
handleCancel
}
onCancel
=
{
handleCancel
}
maskClosable
=
{
false
}
maskClosable
=
{
false
}
size
=
{
'small'
}
size
=
{
'small'
}
centered
=
{
true
}
centered
=
{
true
}
>
<
div
style
=
{{
marginTop
:
20
}}
>
<
Typography
.
Text
>
{
`可用额度
${
renderQuotaWithPrompt
(
userState
?.
user
?.
aff_quota
)}
`}</Typography.Text>
<Input
style={{ marginTop: 5 }}
value={userState?.user?.aff_quota}
disabled={true}
></Input>
</div>
<div style={{ marginTop: 20 }}>
<Typography.Text>
{`
划转额度
$
{
renderQuotaWithPrompt
(
transferAmount
)}
最低
` +
renderQuota(getQuotaPerUnit())}
</Typography.Text>
<div>
<InputNumber
min={0}
style={{ marginTop: 5 }}
value={transferAmount}
onChange={(value) => setTransferAmount(value)}
disabled={false}
></InputNumber>
</div>
</div>
</Modal>
<div style={{ marginTop: 20 }}>
<Card
title={
<Card.Meta
avatar={
<Avatar
size='default'
color={stringToColor(getUsername())}
style={{ marginRight: 4 }}
>
>
{typeof getUsername() === 'string' &&
<
div
style
=
{{
marginTop
:
20
}}
>
getUsername().slice(0, 1)}
<
Typography
.
Text
>
{
`可用额度
${
renderQuotaWithPrompt
(
userState
?.
user
?.
aff_quota
)}
`}</Typography.Text>
</Avatar>
<Input
}
style={{marginTop: 5}}
title={<Typography.Text>{getUsername()}</Typography.Text>}
value={userState?.user?.aff_quota}
description={
disabled={true}
isRoot() ? (
></Input>
<Tag color='red'>管理员</Tag>
</div>
) : (
<div style={{marginTop: 20}}>
<Tag color='blue'>普通用户</Tag>
<Typography.Text>
)
{`
划转额度
$
{
renderQuotaWithPrompt
(
transferAmount
)}
最低
` +
}
renderQuota(getQuotaPerUnit())}
></Card.Meta>
</Typography.Text>
}
<div>
headerExtraContent={
<InputNumber
<>
min={0}
<Space vertical align='start'>
style={{marginTop: 5}}
<Tag color='green'>{'ID: ' + userState?.user?.id}</Tag>
value={transferAmount}
<Tag color='blue'>{userState?.user?.group}</Tag>
onChange={(value) => setTransferAmount(value)}
</Space>
disabled={false}
</>
></InputNumber>
}
</div>
footer={
</div>
<Descriptions row>
</Modal>
<Descriptions.Item itemKey='当前余额'>
<div style={{marginTop: 20}}>
{renderQuota(userState?.user?.quota)}
<Card
</Descriptions.Item>
title={
<Descriptions.Item itemKey='历史消耗'>
<Card.Meta
{renderQuota(userState?.user?.used_quota)}
avatar={
</Descriptions.Item>
<Avatar
<Descriptions.Item itemKey='请求次数'>
size='default'
{userState.user?.request_count}
color={stringToColor(getUsername())}
</Descriptions.Item>
style={{marginRight: 4}}
</Descriptions>
>
}
{typeof getUsername() === 'string' &&
>
getUsername().slice(0, 1)}
<Typography.Title heading={6}>可用模型</Typography.Title>
</Avatar>
<div style={{ marginTop: 10 }}>
}
<Space wrap>
title={<Typography.Text>{getUsername()}</Typography.Text>}
{models.map((model) => (
description={
<Tag
isRoot() ? (
key={model}
<Tag color='red'>管理员</Tag>
color='cyan'
) : (
onClick={() => {
<Tag color='blue'>普通用户</Tag>
copyText(model);
)
}}
}
>
></Card.Meta>
{model}
}
</Tag>
headerExtraContent={
))}
<>
</Space>
<Space vertical align='start'>
</div>
<Tag color='green'>{'ID: ' + userState?.user?.id}</Tag>
</Card>
<Tag color='blue'>{userState?.user?.group}</Tag>
<Card
</Space>
footer={
</>
<div>
}
<Typography.Text>邀请链接</Typography.Text>
footer={
<Input
<Descriptions row>
style={{ marginTop: 10 }}
<Descriptions.Item itemKey='当前余额'>
value={affLink}
{renderQuota(userState?.user?.quota)}
onClick={handleAffLinkClick}
</Descriptions.Item>
readOnly
<Descriptions.Item itemKey='历史消耗'>
/>
{renderQuota(userState?.user?.used_quota)}
</div>
</Descriptions.Item>
}
<Descriptions.Item itemKey='请求次数'>
>
{userState.user?.request_count}
<Typography.Title heading={6}>邀请信息</Typography.Title>
</Descriptions.Item>
<div style={{ marginTop: 10 }}>
</Descriptions>
<Descriptions row>
}
<Descriptions.Item itemKey='待使用收益'>
>
<span style={{ color: 'rgba(var(--semi-red-5), 1)' }}>
<Typography.Title heading={6}>可用模型</Typography.Title>
<div style={{marginTop: 10}}>
<Space wrap>
{models.map((model) => (
<Tag
key={model}
color='cyan'
onClick={() => {
copyText(model);
}}
>
{model}
</Tag>
))}
</Space>
</div>
</Card>
<Card
style={{marginTop: 10}}
footer={
<div>
<Typography.Text>邀请链接</Typography.Text>
<Input
style={{marginTop: 10}}
value={affLink}
onClick={handleAffLinkClick}
readOnly
/>
</div>
}
>
<Typography.Title heading={6}>邀请信息</Typography.Title>
<div style={{marginTop: 10}}>
<Descriptions row>
<Descriptions.Item itemKey='待使用收益'>
<span style={{color: 'rgba(var(--semi-red-5), 1)'}}>
{renderQuota(userState?.user?.aff_quota)}
{renderQuota(userState?.user?.aff_quota)}
</span>
</span>
<Button
<Button
type={'secondary'}
type={'secondary'}
onClick={() => setOpenTransfer(true)}
onClick={() => setOpenTransfer(true)}
size={'small'}
size={'small'}
style={{ marginLeft: 10
}}
style={{marginLeft: 10
}}
>
>
划转
划转
</Button>
</Button>
</Descriptions.Item>
</Descriptions.Item>
<Descriptions.Item itemKey='总收益'>
<Descriptions.Item itemKey='总收益'>
{renderQuota(userState?.user?.aff_history_quota)}
{renderQuota(userState?.user?.aff_history_quota)}
</Descriptions.Item>
</Descriptions.Item>
<Descriptions.Item itemKey='邀请人数'>
<Descriptions.Item itemKey='邀请人数'>
{userState?.user?.aff_count}
{userState?.user?.aff_count}
</Descriptions.Item>
</Descriptions.Item>
</Descriptions>
</Descriptions>
</div>
</div>
</Card>
</Card>
<Card
>
<Card style={{marginTop: 10}}
>
<Typography.Title heading={6}>个人信息</Typography.Title>
<Typography.Title heading={6}>个人信息</Typography.Title>
<div style={{ marginTop: 20
}}>
<div style={{marginTop: 20
}}>
<Typography.Text strong>邮箱</Typography.Text>
<Typography.Text strong>邮箱</Typography.Text>
<div
<div
style={{ display: 'flex', justifyContent: 'space-between'
}}
style={{display: 'flex', justifyContent: 'space-between'
}}
>
>
<div>
<div>
<Input
<Input
value={
value={
userState.user && userState.user.email !== ''
userState.user && userState.user.email !== ''
? userState.user.email
? userState.user.email
: '未绑定'
: '未绑定'
}
}
readonly={true}
readonly={true}
></Input>
></Input>
</div>
</div>
<div>
<div>
<Button
<Button
onClick={() => {
onClick={() => {
setShowEmailBindModal(true);
setShowEmailBindModal(true);
}}
}}
>
>
{userState.user && userState.user.email !== ''
{userState.user && userState.user.email !== ''
? '修改绑定'
? '修改绑定'
: '绑定邮箱'}
: '绑定邮箱'}
</Button>
</Button>
</div>
</div>
</div>
</div>
</div>
</div>
<div style={{ marginTop: 10
}}>
<div style={{marginTop: 10
}}>
<Typography.Text strong>微信</Typography.Text>
<Typography.Text strong>微信</Typography.Text>
<div
<div
style={{ display: 'flex', justifyContent: 'space-between'
}}
style={{display: 'flex', justifyContent: 'space-between'
}}
>
>
<div>
<div>
<Input
<Input
value={
value={
userState.user && userState.user.wechat_id !== ''
userState.user && userState.user.wechat_id !== ''
? '已绑定'
? '已绑定'
: '未绑定'
: '未绑定'
}
}
readonly={true}
readonly={true}
></Input>
></Input>
</div>
</div>
<div>
<div>
<Button
<Button
disabled={
disabled={
(userState.user && userState.user.wechat_id !== '') ||
(userState.user && userState.user.wechat_id !== '') ||
!status.wechat_login
!status.wechat_login
}
}
>
>
{status.wechat_login ? '绑定' : '未启用'}
{status.wechat_login ? '绑定' : '未启用'}
</Button>
</Button>
</div>
</div>
</div>
</div>
</div>
</div>
<div style={{ marginTop: 10
}}>
<div style={{marginTop: 10
}}>
<Typography.Text strong>GitHub</Typography.Text>
<Typography.Text strong>GitHub</Typography.Text>
<div
<div
style={{ display: 'flex', justifyContent: 'space-between'
}}
style={{display: 'flex', justifyContent: 'space-between'
}}
>
>
<div>
<div>
<Input
<Input
value={
value={
userState.user && userState.user.github_id !== ''
userState.user && userState.user.github_id !== ''
? userState.user.github_id
? userState.user.github_id
: '未绑定'
: '未绑定'
}
}
readonly={true}
readonly={true}
></Input>
></Input>
</div>
</div>
<div>
<div>
<Button
<Button
onClick={() => {
onClick={() => {
onGitHubOAuthClicked(status.github_client_id);
onGitHubOAuthClicked(status.github_client_id);
}}
}}
disabled={
disabled={
(userState.user && userState.user.github_id !== '') ||
(userState.user && userState.user.github_id !== '') ||
!status.github_oauth
!status.github_oauth
}
}
>
>
{status.github_oauth ? '绑定' : '未启用'}
{status.github_oauth ? '绑定' : '未启用'}
</Button>
</Button>
</div>
</div>
</div>
</div>
</div>
</div>
<div style={{ marginTop: 10
}}>
<div style={{marginTop: 10
}}>
<Typography.Text strong>Telegram</Typography.Text>
<Typography.Text strong>Telegram</Typography.Text>
<div
<div
style={{ display: 'flex', justifyContent: 'space-between'
}}
style={{display: 'flex', justifyContent: 'space-between'
}}
>
>
<div>
<div>
<Input
<Input
value={
value={
userState.user && userState.user.telegram_id !== ''
userState.user && userState.user.telegram_id !== ''
? userState.user.telegram_id
? userState.user.telegram_id
: '未绑定'
: '未绑定'
}
}
readonly={true}
readonly={true}
></Input>
></Input>
</div>
</div>
<div>
<div>
{status.telegram_oauth ? (
{status.telegram_oauth ? (
userState.user.telegram_id !== '' ? (
userState.user.telegram_id !== '' ? (
<Button disabled={true}>已绑定</Button>
<Button disabled={true}>已绑定</Button>
) : (
) : (
<TelegramLoginButton
<TelegramLoginButton
dataAuthUrl='/api/oauth/telegram/bind'
dataAuthUrl='/api/oauth/telegram/bind'
botName={status.telegram_bot_name}
botName={status.telegram_bot_name}
/>
/>
)
)
) : (
) : (
<Button disabled={true}>未启用</Button>
<Button disabled={true}>未启用</Button>
)}
)}
</div>
</div>
</div>
</div>
</div>
</div>
<div style={{ marginTop: 10
}}>
<div style={{marginTop: 10
}}>
<Typography.Text strong>LinuxDO</Typography.Text>
<Typography.Text strong>LinuxDO</Typography.Text>
<div
<div
style={{ display: 'flex', justifyContent: 'space-between'
}}
style={{display: 'flex', justifyContent: 'space-between'
}}
>
>
<div>
<div>
<Input
<Input
value={
value={
userState.user && userState.user.linux_do_id !== ''
userState.user && userState.user.linux_do_id !== ''
? userState.user.linux_do_id
? userState.user.linux_do_id
: '未绑定'
: '未绑定'
}
}
readonly={true}
readonly={true}
></Input>
></Input>
</div>
</div>
<div>
<div>
<Button
<Button
onClick={() => {
onClick={() => {
onLinuxDOOAuthClicked(status.linuxdo_client_id);
onLinuxDOOAuthClicked(status.linuxdo_client_id);
}}
}}
disabled={
disabled={
(userState.user && userState.user.linux_do_id !== '') ||
(userState.user && userState.user.linux_do_id !== '') ||
!status.linuxdo_oauth
!status.linuxdo_oauth
}
}
>
>
{status.linuxdo_oauth ? '绑定' : '未启用'}
{status.linuxdo_oauth ? '绑定' : '未启用'}
</Button>
</Button>
</div>
</div>
</div>
</div>
</div>
</div>
<div style={{ marginTop: 10
}}>
<div style={{marginTop: 10
}}>
<Space>
<Space>
<Button onClick={generateAccessToken}>
<Button onClick={generateAccessToken}>
生成系统访问令牌
生成系统访问令牌
</Button>
</Button>
<Button
<Button
onClick={() => {
onClick={() => {
setShowChangePasswordModal(true);
setShowChangePasswordModal(true);
}}
}}
>
>
修改密码
修改密码
</Button>
</Button>
<Button
<Button
type={'danger'}
type={'danger'}
onClick={() => {
onClick={() => {
setShowAccountDeleteModal(true);
setShowAccountDeleteModal(true);
}}
}}
>
>
删除个人账户
删除个人账户
</Button>
</Button>
</Space>
</Space>
{systemToken && (
{systemToken && (
<Input
<Input
readOnly
readOnly
value={systemToken}
value={systemToken}
onClick={handleSystemTokenClick}
onClick={handleSystemTokenClick}
style={{ marginTop: '10px'
}}
style={{marginTop: '10px'
}}
/>
/>
)}
)}
{status.wechat_login && (
{status.wechat_login && (
<Button
<Button
onClick={() => {
onClick={() => {
setShowWeChatBindModal(true);
setShowWeChatBindModal(true);
}}
}}
>
>
绑定微信账号
绑定微信账号
</Button>
</Button>
)}
)}
<Modal
<Modal
onCancel={() => setShowWeChatBindModal(false)}
onCancel={() => setShowWeChatBindModal(false)}
// onOpen={() => setShowWeChatBindModal(true)}
// onOpen={() => setShowWeChatBindModal(true)}
visible={showWeChatBindModal}
visible={showWeChatBindModal}
size={'small'}
size={'small'}
>
>
<Image src={status.wechat_qrcode}
/>
<Image src={status.wechat_qrcode}
/>
<div style={{ textAlign: 'center'
}}>
<div style={{textAlign: 'center'
}}>
<p>
<p>
微信扫码关注公众号,输入「验证码」获取验证码(三分钟内有效)
微信扫码关注公众号,输入「验证码」获取验证码(三分钟内有效)
</p>
</p>
</div>
</div>
<Input
<Input
placeholder='验证码'
placeholder='验证码'
name='wechat_verification_code'
name='wechat_verification_code'
value={inputs.wechat_verification_code}
value={inputs.wechat_verification_code}
onChange={(v) =>
onChange={(v) =>
handleInputChange('wechat_verification_code', v)
handleInputChange('wechat_verification_code', v)
}
}
/>
/>
<Button color='' fluid size='large' onClick={bindWeChat}>
<Button color='' fluid size='large' onClick={bindWeChat}>
绑定
绑定
</Button>
</Button>
</Modal>
</Modal>
</div>
</div>
</Card>
</Card>
<Modal
<Modal
onCancel={() => setShowEmailBindModal(false)}
onCancel={() => setShowEmailBindModal(false)}
// onOpen={() => setShowEmailBindModal(true)}
// onOpen={() => setShowEmailBindModal(true)}
onOk={bindEmail}
onOk={bindEmail}
visible={showEmailBindModal}
visible={showEmailBindModal}
size={'small'}
size={'small'}
centered={true}
centered={true}
maskClosable={false}
maskClosable={false}
>
>
<Typography.Title heading={6}>绑定邮箱地址</Typography.Title>
<Typography.Title heading={6}>绑定邮箱地址</Typography.Title>
<div
<div
style={{
style={{
marginTop: 20,
marginTop: 20,
display: 'flex',
display: 'flex',
justifyContent: 'space-between',
justifyContent: 'space-between',
}}
}}
>
>
<Input
<Input
fluid
fluid
placeholder='输入邮箱地址'
placeholder='输入邮箱地址'
onChange={(value) => handleInputChange('email', value)}
onChange={(value) => handleInputChange('email', value)}
name='email'
name='email'
type='email'
type='email'
/>
/>
<Button
<Button
onClick={sendVerificationCode}
onClick={sendVerificationCode}
disabled={disableButton || loading}
disabled={disableButton || loading}
>
>
{disableButton ? `
重新发送
(
$
{
countdown
})
` : '获取验证码'}
{disableButton ? `
重新发送
(
$
{
countdown
})
` : '获取验证码'}
</Button>
</Button>
</div>
</div>
<div style={{ marginTop: 10
}}>
<div style={{marginTop: 10
}}>
<Input
<Input
fluid
fluid
placeholder='验证码'
placeholder='验证码'
name='email_verification_code'
name='email_verification_code'
value={inputs.email_verification_code}
value={inputs.email_verification_code}
onChange={(value) =>
onChange={(value) =>
handleInputChange('email_verification_code', value)
handleInputChange('email_verification_code', value)
}
}
/>
/>
</div>
</div>
{turnstileEnabled ? (
{turnstileEnabled ? (
<Turnstile
<Turnstile
sitekey={turnstileSiteKey}
sitekey={turnstileSiteKey}
onVerify={(token) => {
onVerify={(token) => {
setTurnstileToken(token);
setTurnstileToken(token);
}}
}}
/>
/>
) : (
) : (
<></>
<></>
)}
)}
</Modal>
</Modal>
<Modal
<Modal
onCancel={() => setShowAccountDeleteModal(false)}
onCancel={() => setShowAccountDeleteModal(false)}
visible={showAccountDeleteModal}
visible={showAccountDeleteModal}
size={'small'}
size={'small'}
centered={true}
centered={true}
onOk={deleteAccount}
onOk={deleteAccount}
>
>
<div style={{ marginTop: 20
}}>
<div style={{marginTop: 20
}}>
<Banner
<Banner
type='danger'
type='danger'
description='您正在删除自己的帐户,将清空所有数据且不可恢复'
description='您正在删除自己的帐户,将清空所有数据且不可恢复'
closeIcon={null}
closeIcon={null}
/>
/>
</div>
</div>
<div style={{ marginTop: 20
}}>
<div style={{marginTop: 20
}}>
<Input
<Input
placeholder={`
输入你的账户名
$
{
userState
?.
user
?.
username
}
以确认删除
`}
placeholder={`
输入你的账户名
$
{
userState
?.
user
?.
username
}
以确认删除
`}
name='self_account_deletion_confirmation'
name='self_account_deletion_confirmation'
value={inputs.self_account_deletion_confirmation}
value={inputs.self_account_deletion_confirmation}
onChange={(value) =>
onChange={(value) =>
handleInputChange(
handleInputChange(
'self_account_deletion_confirmation',
'self_account_deletion_confirmation',
value,
value,
)
)
}
}
/>
/>
{turnstileEnabled ? (
{turnstileEnabled ? (
<Turnstile
<Turnstile
sitekey={turnstileSiteKey}
sitekey={turnstileSiteKey}
onVerify={(token) => {
onVerify={(token) => {
setTurnstileToken(token);
setTurnstileToken(token);
}}
}}
/>
/>
) : (
) : (
<></>
<></>
)}
)}
</div>
</div>
</Modal>
</Modal>
<Modal
<Modal
onCancel={() => setShowChangePasswordModal(false)}
onCancel={() => setShowChangePasswordModal(false)}
visible={showChangePasswordModal}
visible={showChangePasswordModal}
size={'small'}
size={'small'}
centered={true}
centered={true}
onOk={changePassword}
onOk={changePassword}
>
>
<div style={{ marginTop: 20
}}>
<div style={{marginTop: 20
}}>
<Input
<Input
name='set_new_password'
name='set_new_password'
placeholder='新密码'
placeholder='新密码'
value={inputs.set_new_password}
value={inputs.set_new_password}
onChange={(value) =>
onChange={(value) =>
handleInputChange('set_new_password', value)
handleInputChange('set_new_password', value)
}
}
/>
/>
<Input
<Input
style={{ marginTop: 20
}}
style={{marginTop: 20
}}
name='set_new_password_confirmation'
name='set_new_password_confirmation'
placeholder='确认新密码'
placeholder='确认新密码'
value={inputs.set_new_password_confirmation}
value={inputs.set_new_password_confirmation}
onChange={(value) =>
onChange={(value) =>
handleInputChange('set_new_password_confirmation', value)
handleInputChange('set_new_password_confirmation', value)
}
}
/>
/>
{turnstileEnabled ? (
{turnstileEnabled ? (
<Turnstile
<Turnstile
sitekey={turnstileSiteKey}
sitekey={turnstileSiteKey}
onVerify={(token) => {
onVerify={(token) => {
setTurnstileToken(token);
setTurnstileToken(token);
}}
}}
/>
/>
) : (
) : (
<></>
<></>
)}
)}
</div>
</div>
</Modal>
</Modal>
</div>
</div>
</Layout.Content>
</Layout.Content>
</Layout>
</Layout>
</div>
</div>
);
);
};
};
export default PersonalSetting;
export default PersonalSetting;
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