fix: 修复 walletType 字段问题和 WebSocket 内存泄漏,优化账户导入 UI
后端修复: - 添加 walletType 字段到 Account 实体和数据库(V17 迁移) - 修复 refreshProxyAddress 方法使用正确的 walletType - 修复 WebSocketTicketService 内存泄漏(添加定时清理任务) 前端优化: - 账户导入改为 Modal 弹窗,提升用户体验 - 默认钱包类型改为 Web3 Wallet(safe),并将其选项排在首位 - 更新多语言文本:将 MetaMask(浏览器钱包)改为 Web3钱包 - 修复 walletTypeHelp Tooltip 换行显示问题
This commit is contained in:
@@ -35,7 +35,7 @@ const AccountImportForm: React.FC<AccountImportFormProps> = ({
|
||||
const isMobile = useMediaQuery({ maxWidth: 768 })
|
||||
const { importAccount, loading } = useAccountStore()
|
||||
const [importType, setImportType] = useState<ImportType>('privateKey')
|
||||
const [walletType, setWalletType] = useState<WalletType>('magic')
|
||||
const [walletType, setWalletType] = useState<WalletType>('safe')
|
||||
const [derivedAddress, setDerivedAddress] = useState<string>('')
|
||||
const [addressError, setAddressError] = useState<string>('')
|
||||
|
||||
@@ -211,7 +211,10 @@ const AccountImportForm: React.FC<AccountImportFormProps> = ({
|
||||
label={
|
||||
<span>
|
||||
{t('accountImport.walletType')}{' '}
|
||||
<Tooltip title={t('accountImport.walletTypeHelp')}>
|
||||
<Tooltip
|
||||
title={t('accountImport.walletTypeHelp')}
|
||||
overlayInnerStyle={{ whiteSpace: 'pre-line', maxWidth: '300px' }}
|
||||
>
|
||||
<QuestionCircleOutlined style={{ color: '#999' }} />
|
||||
</Tooltip>
|
||||
</span>
|
||||
@@ -221,12 +224,12 @@ const AccountImportForm: React.FC<AccountImportFormProps> = ({
|
||||
value={walletType}
|
||||
onChange={(e) => setWalletType(e.target.value)}
|
||||
>
|
||||
<Radio value="magic">
|
||||
{t('accountImport.walletTypeMagic')}
|
||||
</Radio>
|
||||
<Radio value="safe">
|
||||
{t('accountImport.walletTypeSafe')}
|
||||
</Radio>
|
||||
<Radio value="magic">
|
||||
{t('accountImport.walletTypeMagic')}
|
||||
</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
|
||||
|
||||
@@ -201,9 +201,9 @@
|
||||
"addressError": "Cannot derive address from private key",
|
||||
"addressErrorMnemonic": "Cannot derive address from mnemonic",
|
||||
"walletType": "Wallet Type",
|
||||
"walletTypeHelp": "Magic: Polymarket accounts logged in via email or social accounts (Google, Twitter, etc.); MetaMask: Polymarket accounts connected via browser wallets like MetaMask",
|
||||
"walletTypeHelp": "Web3 Wallet: Polymarket accounts connected via browser wallets like MetaMask\nMagic: Polymarket accounts logged in via email or social accounts (Google, Twitter, etc.)",
|
||||
"walletTypeMagic": "Magic (Email/Social Login)",
|
||||
"walletTypeSafe": "MetaMask (Browser Wallet)"
|
||||
"walletTypeSafe": "Web3 Wallet"
|
||||
},
|
||||
"leader": {
|
||||
"title": "Leader Management",
|
||||
|
||||
@@ -201,9 +201,9 @@
|
||||
"addressError": "无法从私钥推导地址",
|
||||
"addressErrorMnemonic": "无法从助记词推导地址",
|
||||
"walletType": "钱包类型",
|
||||
"walletTypeHelp": "Magic:通过邮箱或社交账号(如 Google、Twitter)登录的 Polymarket 账户;MetaMask:使用 MetaMask 等浏览器钱包连接的 Polymarket 账户",
|
||||
"walletTypeHelp": "Web3钱包:使用 MetaMask 等浏览器钱包连接的 Polymarket 账户\nMagic:通过邮箱或社交账号(如 Google、Twitter)登录的 Polymarket 账户",
|
||||
"walletTypeMagic": "Magic(邮箱/社交账号登录)",
|
||||
"walletTypeSafe": "MetaMask(浏览器钱包)"
|
||||
"walletTypeSafe": "Web3钱包"
|
||||
},
|
||||
"leader": {
|
||||
"title": "Leader 管理",
|
||||
|
||||
@@ -201,9 +201,9 @@
|
||||
"addressError": "無法從私鑰推導地址",
|
||||
"addressErrorMnemonic": "無法從助記詞推導地址",
|
||||
"walletType": "錢包類型",
|
||||
"walletTypeHelp": "Magic:透過郵箱或社群帳號(如 Google、Twitter)登入的 Polymarket 帳戶;MetaMask:使用 MetaMask 等瀏覽器錢包連接的 Polymarket 帳戶",
|
||||
"walletTypeHelp": "Web3錢包:使用 MetaMask 等瀏覽器錢包連接的 Polymarket 帳戶\nMagic:透過郵箱或社群帳號(如 Google、Twitter)登入的 Polymarket 帳戶",
|
||||
"walletTypeMagic": "Magic(郵箱/社群帳號登入)",
|
||||
"walletTypeSafe": "MetaMask(瀏覽器錢包)"
|
||||
"walletTypeSafe": "Web3錢包"
|
||||
},
|
||||
"leader": {
|
||||
"title": "Leader 管理",
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useAccountStore } from '../store/accountStore'
|
||||
import type { Account } from '../types'
|
||||
import { useMediaQuery } from 'react-responsive'
|
||||
import { formatUSDC } from '../utils'
|
||||
import AccountImportForm from '../components/AccountImportForm'
|
||||
|
||||
const { Title } = Typography
|
||||
|
||||
@@ -25,11 +26,20 @@ const AccountList: React.FC = () => {
|
||||
const [editAccount, setEditAccount] = useState<Account | null>(null)
|
||||
const [editForm] = Form.useForm()
|
||||
const [editLoading, setEditLoading] = useState(false)
|
||||
const [accountImportModalVisible, setAccountImportModalVisible] = useState(false)
|
||||
const [accountImportForm] = Form.useForm()
|
||||
|
||||
useEffect(() => {
|
||||
fetchAccounts()
|
||||
}, [fetchAccounts])
|
||||
|
||||
const handleAccountImportSuccess = async () => {
|
||||
message.success(t('accountImport.importSuccess'))
|
||||
setAccountImportModalVisible(false)
|
||||
accountImportForm.resetFields()
|
||||
fetchAccounts()
|
||||
}
|
||||
|
||||
// 加载所有账户的余额
|
||||
useEffect(() => {
|
||||
const loadBalances = async () => {
|
||||
@@ -494,7 +504,7 @@ const AccountList: React.FC = () => {
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => navigate('/accounts/import')}
|
||||
onClick={() => setAccountImportModalVisible(true)}
|
||||
size={isMobile ? 'middle' : 'large'}
|
||||
block={isMobile}
|
||||
style={isMobile ? { minHeight: '44px' } : undefined}
|
||||
@@ -836,6 +846,34 @@ const AccountList: React.FC = () => {
|
||||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
|
||||
{/* 导入账户 Modal */}
|
||||
<Modal
|
||||
title={t('accountImport.title')}
|
||||
open={accountImportModalVisible}
|
||||
onCancel={() => {
|
||||
setAccountImportModalVisible(false)
|
||||
accountImportForm.resetFields()
|
||||
}}
|
||||
footer={null}
|
||||
width={isMobile ? '95%' : 600}
|
||||
style={{ top: isMobile ? 20 : 50 }}
|
||||
bodyStyle={{ padding: '24px', maxHeight: 'calc(100vh - 150px)', overflow: 'auto' }}
|
||||
destroyOnClose
|
||||
maskClosable
|
||||
closable
|
||||
>
|
||||
<AccountImportForm
|
||||
form={accountImportForm}
|
||||
onSuccess={handleAccountImportSuccess}
|
||||
onCancel={() => {
|
||||
setAccountImportModalVisible(false)
|
||||
accountImportForm.resetFields()
|
||||
}}
|
||||
showAlert={true}
|
||||
showCancelButton={true}
|
||||
/>
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ export interface Account {
|
||||
proxyAddress: string // Polymarket 代理钱包地址
|
||||
accountName?: string
|
||||
isEnabled?: boolean // 是否启用
|
||||
walletType?: string // 钱包类型:magic(邮箱/OAuth登录)或 safe(MetaMask浏览器钱包)
|
||||
apiKeyConfigured: boolean
|
||||
apiSecretConfigured: boolean
|
||||
apiPassphraseConfigured: boolean
|
||||
@@ -42,6 +43,7 @@ export interface AccountImportRequest {
|
||||
privateKey: string
|
||||
walletAddress: string
|
||||
accountName?: string
|
||||
walletType?: string // 钱包类型:magic(邮箱/OAuth登录)或 safe(MetaMask浏览器钱包)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user