125 lines
3.9 KiB
JavaScript
125 lines
3.9 KiB
JavaScript
import React, { useEffect } from 'react'
|
||
import { useDispatch, useSelector } from 'react-redux'
|
||
import { api } from '../services/api'
|
||
import {
|
||
setAccountId,
|
||
setAccounts,
|
||
selectFirstAccount,
|
||
selectAccountId,
|
||
selectAccounts,
|
||
selectCurrentUser,
|
||
selectIsAdmin,
|
||
} from '../store/appSlice'
|
||
|
||
const AccountSelector = ({ onChanged }) => {
|
||
const dispatch = useDispatch()
|
||
const accountId = useSelector(selectAccountId)
|
||
const accounts = useSelector(selectAccounts)
|
||
const currentUser = useSelector(selectCurrentUser)
|
||
const isAdmin = useSelector(selectIsAdmin)
|
||
|
||
// 加载当前用户的账号列表
|
||
useEffect(() => {
|
||
const load = () => {
|
||
api.getAccounts()
|
||
.then((list) => {
|
||
const accountsList = Array.isArray(list) ? list : []
|
||
dispatch(setAccounts(accountsList))
|
||
// 如果当前没有选中的账号,或者选中的账号不在列表中,自动选择第一个账号
|
||
if (accountsList.length > 0) {
|
||
const currentAccount = accountsList.find((a) => a.id === accountId)
|
||
if (!currentAccount) {
|
||
dispatch(selectFirstAccount())
|
||
}
|
||
}
|
||
})
|
||
.catch(() => dispatch(setAccounts([])))
|
||
}
|
||
load()
|
||
|
||
// 配置页创建/更新账号后会触发该事件,用于即时刷新下拉列表
|
||
const onUpdated = () => load()
|
||
window.addEventListener('ats:accounts:updated', onUpdated)
|
||
return () => window.removeEventListener('ats:accounts:updated', onUpdated)
|
||
}, [dispatch, accountId])
|
||
|
||
// 当 accountId 变化时,调用 onChanged 回调
|
||
useEffect(() => {
|
||
if (typeof onChanged === 'function') {
|
||
onChanged(accountId)
|
||
}
|
||
}, [accountId, onChanged])
|
||
|
||
const list = Array.isArray(accounts) ? accounts : []
|
||
const options = list.reduce((acc, cur) => {
|
||
if (!cur || !cur.id) return acc
|
||
if (acc.some((x) => x.id === cur.id)) return acc
|
||
acc.push(cur)
|
||
return acc
|
||
}, [])
|
||
|
||
const optionsKey = options.map((x) => x.id).join(',')
|
||
|
||
useEffect(() => {
|
||
if (!options.length) {
|
||
// 如果没有账号,清空 accountId
|
||
if (accountId) {
|
||
dispatch(setAccountId(null))
|
||
}
|
||
return
|
||
}
|
||
|
||
// 检查当前选中的账号是否在新列表中
|
||
const currentAccount = options.find((a) => a.id === accountId)
|
||
if (currentAccount) {
|
||
// 账号在新列表中,保持选中(不管是否disabled)
|
||
return
|
||
}
|
||
|
||
// 如果当前账号不在新列表中,选择第一个账号(不管是否disabled)
|
||
const firstAccount = options[0]
|
||
if (firstAccount) {
|
||
dispatch(setAccountId(parseInt(String(firstAccount.id || ''), 10)))
|
||
} else {
|
||
// 如果没有账号,清空 accountId
|
||
dispatch(setAccountId(null))
|
||
}
|
||
}, [optionsKey, accountId, dispatch])
|
||
|
||
return (
|
||
<div className="nav-account">
|
||
<span className="nav-account-label">账号</span>
|
||
<select
|
||
className="nav-account-select"
|
||
value={accountId || ''}
|
||
onChange={(e) => {
|
||
const v = parseInt(e.target.value, 10)
|
||
if (Number.isFinite(v) && v > 0) {
|
||
// 允许选择任何账号(包括disabled),由各个页面根据账号状态决定是否展示内容
|
||
dispatch(setAccountId(v))
|
||
} else {
|
||
dispatch(setAccountId(null))
|
||
}
|
||
}}
|
||
title="切换账号后:配置/持仓/交易记录/统计会按账号隔离;推荐仍是全局"
|
||
>
|
||
{options.length === 0 ? (
|
||
<option value="">暂无账号</option>
|
||
) : (
|
||
options.map((a) => {
|
||
const isDisabled = String(a?.status || 'active') === 'disabled'
|
||
return (
|
||
<option key={a.id} value={a.id}>
|
||
#{a.id} {a.name || 'account'}
|
||
{isDisabled ? '(已禁用)' : ''}
|
||
</option>
|
||
)
|
||
})
|
||
)}
|
||
</select>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default AccountSelector
|