fix: 修复 walletType 字段问题和 WebSocket 内存泄漏,优化账户导入 UI

后端修复:
- 添加 walletType 字段到 Account 实体和数据库(V17 迁移)
- 修复 refreshProxyAddress 方法使用正确的 walletType
- 修复 WebSocketTicketService 内存泄漏(添加定时清理任务)

前端优化:
- 账户导入改为 Modal 弹窗,提升用户体验
- 默认钱包类型改为 Web3 Wallet(safe),并将其选项排在首位
- 更新多语言文本:将 MetaMask(浏览器钱包)改为 Web3钱包
- 修复 walletTypeHelp Tooltip 换行显示问题
This commit is contained in:
WrBug
2026-01-03 18:29:39 +08:00
parent 21da06d8b0
commit 6e5ccdfe5c
11 changed files with 109 additions and 15 deletions
@@ -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>
+2 -2
View File
@@ -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",
+2 -2
View File
@@ -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 管理",
+2 -2
View File
@@ -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 管理",
+39 -1
View File
@@ -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>
)
}
+2
View File
@@ -16,6 +16,7 @@ export interface Account {
proxyAddress: string // Polymarket 代理钱包地址
accountName?: string
isEnabled?: boolean // 是否启用
walletType?: string // 钱包类型:magic(邮箱/OAuth登录)或 safeMetaMask浏览器钱包)
apiKeyConfigured: boolean
apiSecretConfigured: boolean
apiPassphraseConfigured: boolean
@@ -42,6 +43,7 @@ export interface AccountImportRequest {
privateKey: string
walletAddress: string
accountName?: string
walletType?: string // 钱包类型:magic(邮箱/OAuth登录)或 safeMetaMask浏览器钱包)
}
/**