feat: 完善Leader管理功能

- 修复LeaderList:移除不存在的字段(enabled, copyRatio),添加跟单关系数量和创建时间显示
- 修复LeaderAdd:移除不需要的字段(accountId, enabled),只保留leaderAddress, leaderName, category
- 新增LeaderEdit页面:支持编辑Leader名称和分类
- 添加移动端适配:LeaderList支持卡片式布局
- 统一地址验证:前后端使用相同的正则表达式验证钱包地址格式
- 更新路由配置:添加/leaders/edit路由
- 改进用户体验:删除前提示跟单关系数量
This commit is contained in:
WrBug
2025-12-01 23:36:23 +08:00
parent 4d322424c1
commit 844cd686eb
5 changed files with 318 additions and 67 deletions
+19 -39
View File
@@ -1,10 +1,10 @@
import { useState, useEffect } from 'react'
import { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { Card, Form, Input, Button, Select, Switch, message, Typography, Space } from 'antd'
import { Card, Form, Input, Button, Select, message, Typography, Space } from 'antd'
import { ArrowLeftOutlined } from '@ant-design/icons'
import { apiService } from '../services/api'
import { useAccountStore } from '../store/accountStore'
import { useMediaQuery } from 'react-responsive'
import { isValidWalletAddress } from '../utils'
const { Title } = Typography
const { Option } = Select
@@ -12,23 +12,16 @@ const { Option } = Select
const LeaderAdd: React.FC = () => {
const navigate = useNavigate()
const isMobile = useMediaQuery({ maxWidth: 768 })
const { accounts, fetchAccounts } = useAccountStore()
const [form] = Form.useForm()
const [loading, setLoading] = useState(false)
useEffect(() => {
fetchAccounts()
}, [fetchAccounts])
const handleSubmit = async (values: any) => {
setLoading(true)
try {
const response = await apiService.leaders.add({
leaderAddress: values.leaderAddress,
leaderName: values.leaderName,
accountId: values.accountId,
category: values.category,
enabled: values.enabled !== false
leaderAddress: values.leaderAddress.trim(),
leaderName: values.leaderName?.trim() || undefined,
category: values.category || undefined
})
if (response.data.code === 0) {
@@ -73,39 +66,34 @@ const LeaderAdd: React.FC = () => {
rules={[
{ required: true, message: '请输入 Leader 钱包地址' },
{
pattern: /^0x[a-fA-F0-9]{40}$/,
message: '钱包地址格式不正确'
validator: (_, value) => {
if (!value) {
return Promise.reject(new Error('请输入 Leader 钱包地址'))
}
if (!isValidWalletAddress(value.trim())) {
return Promise.reject(new Error('钱包地址格式不正确(必须是 0x 开头的 42 位地址)'))
}
return Promise.resolve()
}
}
]}
tooltip="被跟单者的钱包地址,系统将监控该地址的交易并自动跟单"
>
<Input placeholder="0x..." />
<Input placeholder="0x..." style={{ fontFamily: 'monospace' }} />
</Form.Item>
<Form.Item
label="Leader 名称"
name="leaderName"
tooltip="可选,用于标识 Leader,方便管理"
>
<Input placeholder="可选,用于标识 Leader" />
</Form.Item>
<Form.Item
label="使用的账户"
name="accountId"
help="选择用于跟单此 Leader 的账户,不选择则使用默认账户"
>
<Select placeholder="选择账户(可选)" allowClear>
{accounts.map(account => (
<Option key={account.id} value={account.id}>
{account.accountName || account.walletAddress} {account.isDefault && '(默认)'}
</Option>
))}
</Select>
</Form.Item>
<Form.Item
label="分类筛选"
name="category"
help="仅跟单该分类的交易,不选择则跟单所有分类"
tooltip="仅跟单该分类的交易,不选择则跟单所有分类sports 或 crypto"
>
<Select placeholder="选择分类(可选)" allowClear>
<Option value="sports">Sports</Option>
@@ -113,14 +101,6 @@ const LeaderAdd: React.FC = () => {
</Select>
</Form.Item>
<Form.Item
label="启用跟单"
name="enabled"
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item>
<Space>
<Button