a
This commit is contained in:
parent
fe60f12ee0
commit
18cfeaf5db
|
|
@ -87,8 +87,8 @@ async def list_accounts(user: Dict[str, Any] = Depends(get_current_user)) -> Lis
|
||||||
r = Account.get(int(aid))
|
r = Account.get(int(aid))
|
||||||
if not r:
|
if not r:
|
||||||
continue
|
continue
|
||||||
# 普通用户:不返回密钥相关字段
|
# 普通用户:不返回密钥明文,但返回“是否已配置”的状态,方便前端提示
|
||||||
_, _, use_testnet = Account.get_credentials(int(aid))
|
api_key, api_secret, use_testnet = Account.get_credentials(int(aid))
|
||||||
out.append(
|
out.append(
|
||||||
{
|
{
|
||||||
"id": int(aid),
|
"id": int(aid),
|
||||||
|
|
@ -96,6 +96,8 @@ async def list_accounts(user: Dict[str, Any] = Depends(get_current_user)) -> Lis
|
||||||
"status": r.get("status") or "active",
|
"status": r.get("status") or "active",
|
||||||
"use_testnet": bool(use_testnet),
|
"use_testnet": bool(use_testnet),
|
||||||
"role": membership_map.get(int(aid), "viewer"),
|
"role": membership_map.get(int(aid), "viewer"),
|
||||||
|
"has_api_key": bool(api_key),
|
||||||
|
"has_api_secret": bool(api_secret),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return out
|
return out
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ const ConfigPanel = ({ currentUser }) => {
|
||||||
const [systemBusy, setSystemBusy] = useState(false)
|
const [systemBusy, setSystemBusy] = useState(false)
|
||||||
const [accountTradingStatus, setAccountTradingStatus] = useState(null)
|
const [accountTradingStatus, setAccountTradingStatus] = useState(null)
|
||||||
const [accountTradingErr, setAccountTradingErr] = useState('')
|
const [accountTradingErr, setAccountTradingErr] = useState('')
|
||||||
|
const [currentAccountMeta, setCurrentAccountMeta] = useState(null)
|
||||||
|
|
||||||
// 多账号:当前账号(仅用于配置页提示;全局切换器在顶部导航)
|
// 多账号:当前账号(仅用于配置页提示;全局切换器在顶部导航)
|
||||||
const [accountId, setAccountId] = useState(getCurrentAccountId())
|
const [accountId, setAccountId] = useState(getCurrentAccountId())
|
||||||
|
|
@ -220,6 +221,21 @@ const ConfigPanel = ({ currentUser }) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const loadCurrentAccountMeta = async () => {
|
||||||
|
try {
|
||||||
|
const list = await api.getAccounts()
|
||||||
|
const accounts = Array.isArray(list) ? list : []
|
||||||
|
const meta = accounts.find((a) => parseInt(String(a?.id || '0'), 10) === parseInt(String(accountId || '0'), 10))
|
||||||
|
setCurrentAccountMeta(meta || null)
|
||||||
|
// 同步 testnet 开关到表单(仅在未输入时同步,避免打断正在输入)
|
||||||
|
if (meta && !credForm.api_key && !credForm.api_secret) {
|
||||||
|
setCredForm((prev) => ({ ...prev, use_testnet: !!meta.use_testnet }))
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
setCurrentAccountMeta(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleAccountTradingEnsure = async () => {
|
const handleAccountTradingEnsure = async () => {
|
||||||
setSystemBusy(true)
|
setSystemBusy(true)
|
||||||
setMessage('')
|
setMessage('')
|
||||||
|
|
@ -235,6 +251,12 @@ const ConfigPanel = ({ currentUser }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleAccountTradingStart = async () => {
|
const handleAccountTradingStart = async () => {
|
||||||
|
const hasKey = !!currentAccountMeta?.has_api_key
|
||||||
|
const hasSecret = !!currentAccountMeta?.has_api_secret
|
||||||
|
if (!hasKey || !hasSecret) {
|
||||||
|
setMessage('请先在“账号密钥(当前账号)”中配置 BINANCE_API_KEY 与 BINANCE_API_SECRET,然后再启动交易进程')
|
||||||
|
return
|
||||||
|
}
|
||||||
setSystemBusy(true)
|
setSystemBusy(true)
|
||||||
setMessage('')
|
setMessage('')
|
||||||
try {
|
try {
|
||||||
|
|
@ -263,6 +285,12 @@ const ConfigPanel = ({ currentUser }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleAccountTradingRestart = async () => {
|
const handleAccountTradingRestart = async () => {
|
||||||
|
const hasKey = !!currentAccountMeta?.has_api_key
|
||||||
|
const hasSecret = !!currentAccountMeta?.has_api_secret
|
||||||
|
if (!hasKey || !hasSecret) {
|
||||||
|
setMessage('请先在“账号密钥(当前账号)”中配置 BINANCE_API_KEY 与 BINANCE_API_SECRET,然后再重启交易进程')
|
||||||
|
return
|
||||||
|
}
|
||||||
setSystemBusy(true)
|
setSystemBusy(true)
|
||||||
setMessage('')
|
setMessage('')
|
||||||
try {
|
try {
|
||||||
|
|
@ -359,6 +387,7 @@ const ConfigPanel = ({ currentUser }) => {
|
||||||
}
|
}
|
||||||
loadBackendStatus()
|
loadBackendStatus()
|
||||||
loadAccountTradingStatus()
|
loadAccountTradingStatus()
|
||||||
|
loadCurrentAccountMeta()
|
||||||
|
|
||||||
const timer = setInterval(() => {
|
const timer = setInterval(() => {
|
||||||
if (isAdmin) {
|
if (isAdmin) {
|
||||||
|
|
@ -366,6 +395,7 @@ const ConfigPanel = ({ currentUser }) => {
|
||||||
}
|
}
|
||||||
loadBackendStatus()
|
loadBackendStatus()
|
||||||
loadAccountTradingStatus()
|
loadAccountTradingStatus()
|
||||||
|
loadCurrentAccountMeta()
|
||||||
}, 3000)
|
}, 3000)
|
||||||
|
|
||||||
return () => clearInterval(timer)
|
return () => clearInterval(timer)
|
||||||
|
|
@ -395,9 +425,12 @@ const ConfigPanel = ({ currentUser }) => {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
loadConfigs()
|
loadConfigs()
|
||||||
checkFeasibility()
|
checkFeasibility()
|
||||||
|
if (isAdmin) {
|
||||||
loadSystemStatus()
|
loadSystemStatus()
|
||||||
|
}
|
||||||
loadBackendStatus()
|
loadBackendStatus()
|
||||||
loadAccountTradingStatus()
|
loadAccountTradingStatus()
|
||||||
|
loadCurrentAccountMeta()
|
||||||
}, [accountId])
|
}, [accountId])
|
||||||
|
|
||||||
// 顶部导航切换账号时(localStorage更新),这里做一个轻量同步
|
// 顶部导航切换账号时(localStorage更新),这里做一个轻量同步
|
||||||
|
|
@ -829,20 +862,26 @@ const ConfigPanel = ({ currentUser }) => {
|
||||||
<div className="accounts-form">
|
<div className="accounts-form">
|
||||||
<label>
|
<label>
|
||||||
API KEY(留空=不改)
|
API KEY(留空=不改)
|
||||||
|
<div className="system-status-meta" style={{ marginTop: '4px' }}>
|
||||||
|
当前状态:{currentAccountMeta?.has_api_key ? '已配置(******)' : '未配置(必须先配置才能启动交易)'}
|
||||||
|
</div>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
value={credForm.api_key}
|
value={credForm.api_key}
|
||||||
onChange={(e) => setCredForm({ ...credForm, api_key: e.target.value })}
|
onChange={(e) => setCredForm({ ...credForm, api_key: e.target.value })}
|
||||||
placeholder="粘贴你的 Binance API KEY"
|
placeholder={currentAccountMeta?.has_api_key ? '已配置(******),如需更换请重新填写' : '粘贴你的 Binance API KEY'}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
API SECRET(留空=不改)
|
API SECRET(留空=不改)
|
||||||
|
<div className="system-status-meta" style={{ marginTop: '4px' }}>
|
||||||
|
当前状态:{currentAccountMeta?.has_api_secret ? '已配置(******)' : '未配置(必须先配置才能启动交易)'}
|
||||||
|
</div>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
value={credForm.api_secret}
|
value={credForm.api_secret}
|
||||||
onChange={(e) => setCredForm({ ...credForm, api_secret: e.target.value })}
|
onChange={(e) => setCredForm({ ...credForm, api_secret: e.target.value })}
|
||||||
placeholder="粘贴你的 Binance API SECRET"
|
placeholder={currentAccountMeta?.has_api_secret ? '已配置(******),如需更换请重新填写' : '粘贴你的 Binance API SECRET'}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="accounts-inline">
|
<label className="accounts-inline">
|
||||||
|
|
@ -1454,7 +1493,12 @@ const ConfigPanel = ({ currentUser }) => {
|
||||||
<h3>{label}</h3>
|
<h3>{label}</h3>
|
||||||
<div className="config-grid">
|
<div className="config-grid">
|
||||||
{Object.entries(configs)
|
{Object.entries(configs)
|
||||||
.filter(([key, config]) => config.category === category)
|
.filter(([key, config]) => {
|
||||||
|
if (config.category !== category) return false
|
||||||
|
// 密钥相关配置统一在“账号密钥(当前账号)”模块管理,这里不重复展示
|
||||||
|
if (key === 'BINANCE_API_KEY' || key === 'BINANCE_API_SECRET' || key === 'USE_TESTNET') return false
|
||||||
|
return true
|
||||||
|
})
|
||||||
.map(([key, config]) => (
|
.map(([key, config]) => (
|
||||||
<ConfigItem
|
<ConfigItem
|
||||||
key={key}
|
key={key}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user