feat: 完善Leader管理功能
- 修复LeaderList:移除不存在的字段(enabled, copyRatio),添加跟单关系数量和创建时间显示 - 修复LeaderAdd:移除不需要的字段(accountId, enabled),只保留leaderAddress, leaderName, category - 新增LeaderEdit页面:支持编辑Leader名称和分类 - 添加移动端适配:LeaderList支持卡片式布局 - 统一地址验证:前后端使用相同的正则表达式验证钱包地址格式 - 更新路由配置:添加/leaders/edit路由 - 改进用户体验:删除前提示跟单关系数量
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user