This commit is contained in:
薇薇安 2026-01-22 21:49:42 +08:00
parent d051be3f65
commit 1c1580b344
3 changed files with 128 additions and 28 deletions

View File

@ -107,11 +107,37 @@ const AccountSelector = ({ onChanged }) => {
const optionsKey = options.map((x) => x.id).join(',') const optionsKey = options.map((x) => x.id).join(',')
useEffect(() => { useEffect(() => {
if (!options.length) return if (!options.length) {
if (options.some((a) => a.id === accountId)) return // accountId
const firstActive = options.find((a) => String(a?.status || 'active') === 'active') || options[0] if (accountId) {
dispatch(setAccountId(null))
}
return
}
// active
const currentAccount = options.find((a) => a.id === accountId)
if (currentAccount) {
// disabled active
if (String(currentAccount?.status || 'active') === 'disabled') {
const firstActive = options.find((a) => String(a?.status || 'active') === 'active')
if (firstActive) {
dispatch(setAccountId(parseInt(String(firstActive.id || ''), 10)))
} else {
// active accountId
dispatch(setAccountId(null))
}
}
return
}
// active
const firstActive = options.find((a) => String(a?.status || 'active') === 'active')
if (firstActive) { if (firstActive) {
dispatch(setAccountId(parseInt(String(firstActive.id || ''), 10))) dispatch(setAccountId(parseInt(String(firstActive.id || ''), 10)))
} else {
// active accountId
dispatch(setAccountId(null))
} }
}, [optionsKey, accountId, dispatch]) }, [optionsKey, accountId, dispatch])
@ -123,20 +149,46 @@ const AccountSelector = ({ onChanged }) => {
value={accountId || ''} value={accountId || ''}
onChange={(e) => { onChange={(e) => {
const v = parseInt(e.target.value, 10) const v = parseInt(e.target.value, 10)
dispatch(setAccountId(Number.isFinite(v) && v > 0 ? v : 1)) if (Number.isFinite(v) && v > 0) {
// disabled
const selectedAccount = options.find((a) => a.id === v)
if (selectedAccount && String(selectedAccount?.status || 'active') === 'disabled') {
// disabled
return
}
dispatch(setAccountId(v))
} else {
dispatch(setAccountId(null))
}
}} }}
title="切换账号后:配置/持仓/交易记录/统计会按账号隔离;推荐仍是全局" title="切换账号后:配置/持仓/交易记录/统计会按账号隔离;推荐仍是全局"
disabled={isAdmin && !effectiveUserId} disabled={isAdmin && !effectiveUserId}
> >
{options.length === 0 ? ( {options.length === 0 ? (
<option value="">{isAdmin && !effectiveUserId ? '请先选择用户' : '暂无账号'}</option> <option value="">{isAdmin && !effectiveUserId ? '请先选择用户' : '暂无账号'}</option>
) : accountId === null ? (
<>
<option value="">请选择账号</option>
{options.map((a) => {
const isDisabled = String(a?.status || 'active') === 'disabled'
return (
<option key={a.id} value={a.id} disabled={isDisabled}>
#{a.id} {a.name || 'account'}
{isDisabled ? '(已禁用)' : ''}
</option>
)
})}
</>
) : ( ) : (
options.map((a) => ( options.map((a) => {
<option key={a.id} value={a.id}> const isDisabled = String(a?.status || 'active') === 'disabled'
#{a.id} {a.name || 'account'} return (
{String(a?.status || 'active') === 'disabled' ? '(已禁用)' : ''} <option key={a.id} value={a.id} disabled={isDisabled}>
</option> #{a.id} {a.name || 'account'}
)) {isDisabled ? '(已禁用)' : ''}
</option>
)
})
)} )}
</select> </select>
</div> </div>

View File

@ -361,18 +361,30 @@ const GlobalConfig = () => {
const loadConfigs = async () => { const loadConfigs = async () => {
try { try {
// 使 account // 使 account
if (isAdmin && configMeta?.global_strategy_account_id) { // 使 configMeta 使 1
const globalAccountId = parseInt(String(configMeta?.global_strategy_account_id || '1'), 10) || 1 if (isAdmin) {
const globalAccountId = configMeta?.global_strategy_account_id
? parseInt(String(configMeta.global_strategy_account_id || '1'), 10) || 1
: 1 // configMeta 使 1
const data = await api.getGlobalConfigs(globalAccountId) const data = await api.getGlobalConfigs(globalAccountId)
setConfigs(data) setConfigs(data)
} else { } else {
// configMeta 使 // 使 account 访
const data = await api.getConfigs() const data = await api.getConfigs()
setConfigs(data) setConfigs(data)
} }
} catch (error) { } catch (error) {
console.error('Failed to load configs:', error) console.error('Failed to load configs:', error)
// 使 1
if (isAdmin) {
try {
const data = await api.getGlobalConfigs(1)
setConfigs(data)
} catch (retryError) {
console.error('Retry load configs with accountId=1 failed:', retryError)
}
}
} }
} }
@ -440,11 +452,20 @@ const GlobalConfig = () => {
loadAccounts() loadAccounts()
// //
if (isAdmin) { if (isAdmin) {
// configMeta configs loadConfigs global_strategy_account_id // configs configMeta使 1
// configMeta configs global_strategy_account_id 1
loadConfigs().catch(() => {})
loadConfigMeta() loadConfigMeta()
.then(() => { .then(() => {
// configMeta configs // configMeta global_strategy_account_id 1 configs
loadConfigs().catch(() => {}) // 使ID
const globalAccountId = configMeta?.global_strategy_account_id
? parseInt(String(configMeta.global_strategy_account_id || '1'), 10) || 1
: 1
// globalAccountId 1
if (globalAccountId !== 1) {
loadConfigs().catch(() => {})
}
}) })
.catch(() => {}) // .catch(() => {}) //
loadSystemStatus().catch(() => {}) // loadSystemStatus().catch(() => {}) //
@ -608,12 +629,15 @@ const GlobalConfig = () => {
} }
}).filter(Boolean) }).filter(Boolean)
// // 使使 configMeta 使 1
let response let response
if (isAdmin && configMeta?.global_strategy_account_id) { if (isAdmin) {
const globalAccountId = parseInt(String(configMeta?.global_strategy_account_id || '1'), 10) || 1 const globalAccountId = configMeta?.global_strategy_account_id
? parseInt(String(configMeta.global_strategy_account_id || '1'), 10) || 1
: 1
response = await api.updateGlobalConfigsBatch(configItems, globalAccountId) response = await api.updateGlobalConfigsBatch(configItems, globalAccountId)
} else { } else {
// 访
response = await api.updateConfigsBatch(configItems) response = await api.updateConfigsBatch(configItems)
} }
setMessage(response.message || `已应用${preset.name}`) setMessage(response.message || `已应用${preset.name}`)
@ -654,10 +678,12 @@ const GlobalConfig = () => {
} }
const buildConfigSnapshot = async (includeSecrets) => { const buildConfigSnapshot = async (includeSecrets) => {
// 使 // 使使 configMeta 使 1
let data let data
if (isAdmin && configMeta?.global_strategy_account_id) { if (isAdmin) {
const globalAccountId = parseInt(String(configMeta?.global_strategy_account_id || '1'), 10) || 1 const globalAccountId = configMeta?.global_strategy_account_id
? parseInt(String(configMeta.global_strategy_account_id || '1'), 10) || 1
: 1
data = await api.getGlobalConfigs(globalAccountId) data = await api.getGlobalConfigs(globalAccountId)
} else { } else {
data = await api.getConfigs() data = await api.getConfigs()
@ -1169,10 +1195,16 @@ const GlobalConfig = () => {
try { try {
setSaving(true) setSaving(true)
setMessage('') setMessage('')
// configMeta 使 1 // 使使 configMeta 使 1
const globalAccountId = configMeta?.global_strategy_account_id const globalAccountId = isAdmin
? parseInt(String(configMeta?.global_strategy_account_id || '1'), 10) || 1 ? (configMeta?.global_strategy_account_id
: 1 ? parseInt(String(configMeta.global_strategy_account_id || '1'), 10) || 1
: 1)
: null
if (!isAdmin || !globalAccountId) {
setMessage('只有管理员可以修改全局配置')
return
}
await api.updateGlobalConfigsBatch([{ await api.updateGlobalConfigsBatch([{
key, key,
value, value,

View File

@ -74,6 +74,13 @@ const appSlice = createSlice({
} catch (e) { } catch (e) {
// ignore // ignore
} }
} else {
// 如果 accountId 为 null清空 localStorage
try {
localStorage.removeItem(ACCOUNT_ID_STORAGE_KEY)
} catch (e) {
// ignore
}
} }
}, },
setAccounts: (state, action) => { setAccounts: (state, action) => {
@ -97,8 +104,9 @@ const appSlice = createSlice({
// 等待账号列表加载完成后再切换 // 等待账号列表加载完成后再切换
}, },
// 切换用户后账号列表加载完成自动选择第一个active账号 // 切换用户后账号列表加载完成自动选择第一个active账号
// 如果没有 active 账号,不改变当前 accountId保持为 null 或之前的值)
selectFirstActiveAccount: (state) => { selectFirstActiveAccount: (state) => {
const firstActive = state.accounts.find((a) => String(a?.status || 'active') === 'active') || state.accounts[0] const firstActive = state.accounts.find((a) => String(a?.status || 'active') === 'active')
if (firstActive) { if (firstActive) {
const nextAccountId = parseInt(String(firstActive.id || ''), 10) const nextAccountId = parseInt(String(firstActive.id || ''), 10)
if (Number.isFinite(nextAccountId) && nextAccountId > 0) { if (Number.isFinite(nextAccountId) && nextAccountId > 0) {
@ -115,6 +123,14 @@ const appSlice = createSlice({
// ignore // ignore
} }
} }
} else {
// 如果没有 active 账号,清空 accountId
state.accountId = null
try {
localStorage.removeItem(ACCOUNT_ID_STORAGE_KEY)
} catch (e) {
// ignore
}
} }
}, },
}, },