diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/LeaderService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/LeaderService.kt
index 7035181..e87a193 100644
--- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/LeaderService.kt
+++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/LeaderService.kt
@@ -186,9 +186,10 @@ class LeaderService(
/**
* 验证钱包地址格式
+ * 必须是 0x 开头的 42 位十六进制字符串
*/
private fun isValidWalletAddress(address: String): Boolean {
- return address.startsWith("0x") && address.length == 42
+ return address.matches(Regex("^0x[a-fA-F0-9]{40}$"))
}
}
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index effee75..23e0ed4 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -9,6 +9,7 @@ import AccountDetail from './pages/AccountDetail'
import AccountEdit from './pages/AccountEdit'
import LeaderList from './pages/LeaderList'
import LeaderAdd from './pages/LeaderAdd'
+import LeaderEdit from './pages/LeaderEdit'
import ConfigPage from './pages/ConfigPage'
import PositionList from './pages/PositionList'
import Statistics from './pages/Statistics'
@@ -129,6 +130,7 @@ function App() {
} />
} />
} />
+ } />
} />
} />
} />
diff --git a/frontend/src/pages/LeaderAdd.tsx b/frontend/src/pages/LeaderAdd.tsx
index dcca342..864fc07 100644
--- a/frontend/src/pages/LeaderAdd.tsx
+++ b/frontend/src/pages/LeaderAdd.tsx
@@ -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="被跟单者的钱包地址,系统将监控该地址的交易并自动跟单"
>
-
+
-
-
-
-
-
-
-
-