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
+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>
)
}