feat: 重构仓位轮训逻辑并修复多语言配置
主要改动: 1. 创建独立的 PositionCheckService 服务 - 将仓位检查逻辑从 PositionPushService 中分离 - 实现待赎回仓位检查和未卖出订单检查 - 实现订单状态更新逻辑(FIFO策略) 2. 修改 PositionPushService - 后端启动时自动启动轮训任务 - 每次轮训后推送全量数据给所有订阅的客户端 - 调用 PositionCheckService 进行仓位检查 3. 自动赎回功能调整 - 将自动赎回从跟单配置级别移到系统级别 - 添加系统级自动赎回配置管理 - 支持 Builder API Key 配置检查 4. 多语言配置修复 - 修复 PositionCheckService 中的硬编码消息 - 使用 MessageSource 获取多语言文本 - 添加自动赎回和 Builder API Key 相关的多语言资源 5. 数据库迁移 - V8: 添加跟单配置名称字段 - V9: 将自动赎回配置移到系统配置表 6. 前端更新 - 添加系统级自动赎回配置界面 - 更新跟单配置管理界面 - 添加 Builder API Key 配置界面
This commit is contained in:
@@ -22,10 +22,31 @@ const CopyTradingAdd: React.FC = () => {
|
||||
const [templateModalVisible, setTemplateModalVisible] = useState(false)
|
||||
const [copyMode, setCopyMode] = useState<'RATIO' | 'FIXED'>('RATIO')
|
||||
|
||||
// 生成默认配置名
|
||||
const generateDefaultConfigName = (): string => {
|
||||
const now = new Date()
|
||||
const dateStr = now.toLocaleDateString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit'
|
||||
}).replace(/\//g, '-')
|
||||
const timeStr = now.toLocaleTimeString('zh-CN', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
return `跟单配置-${dateStr}-${timeStr}`
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchAccounts()
|
||||
fetchLeaders()
|
||||
fetchTemplates()
|
||||
|
||||
// 生成默认配置名
|
||||
const defaultConfigName = generateDefaultConfigName()
|
||||
form.setFieldsValue({ configName: defaultConfigName })
|
||||
}, [])
|
||||
|
||||
const fetchLeaders = async () => {
|
||||
@@ -114,7 +135,9 @@ const CopyTradingAdd: React.FC = () => {
|
||||
maxSpread: values.maxSpread?.toString(),
|
||||
minOrderbookDepth: values.minOrderbookDepth?.toString(),
|
||||
minPrice: values.minPrice?.toString(),
|
||||
maxPrice: values.maxPrice?.toString()
|
||||
maxPrice: values.maxPrice?.toString(),
|
||||
configName: values.configName?.trim(),
|
||||
pushFailedOrders: values.pushFailedOrders ?? false
|
||||
}
|
||||
|
||||
const response = await apiService.copyTrading.create(request)
|
||||
@@ -163,10 +186,26 @@ const CopyTradingAdd: React.FC = () => {
|
||||
useWebSocket: true,
|
||||
websocketReconnectInterval: 5000,
|
||||
websocketMaxRetries: 10,
|
||||
supportSell: true
|
||||
supportSell: true,
|
||||
pushFailedOrders: false
|
||||
}}
|
||||
>
|
||||
{/* 基础信息 */}
|
||||
<Form.Item
|
||||
label={t('copyTradingAdd.configName') || '配置名'}
|
||||
name="configName"
|
||||
rules={[
|
||||
{ required: true, message: t('copyTradingAdd.configNameRequired') || '请输入配置名' },
|
||||
{ whitespace: true, message: t('copyTradingAdd.configNameRequired') || '配置名不能为空' }
|
||||
]}
|
||||
tooltip={t('copyTradingAdd.configNameTooltip') || '为跟单配置设置一个名称,便于识别和管理'}
|
||||
>
|
||||
<Input
|
||||
placeholder={t('copyTradingAdd.configNamePlaceholder') || '例如:跟单配置1'}
|
||||
maxLength={255}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={t('copyTradingAdd.selectWallet') || '选择钱包'}
|
||||
name="accountId"
|
||||
@@ -444,7 +483,9 @@ const CopyTradingAdd: React.FC = () => {
|
||||
</Input.Group>
|
||||
</Form.Item>
|
||||
|
||||
{/* 跟单卖出 - 表单最底部 */}
|
||||
<Divider>{t('copyTradingAdd.advancedSettings') || '高级设置'}</Divider>
|
||||
|
||||
{/* 跟单卖出 */}
|
||||
<Form.Item
|
||||
label={t('copyTradingAdd.supportSell') || '跟单卖出'}
|
||||
name="supportSell"
|
||||
@@ -454,6 +495,16 @@ const CopyTradingAdd: React.FC = () => {
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
|
||||
{/* 推送失败订单 */}
|
||||
<Form.Item
|
||||
label={t('copyTradingAdd.pushFailedOrders') || '推送失败订单'}
|
||||
name="pushFailedOrders"
|
||||
tooltip={t('copyTradingAdd.pushFailedOrdersTooltip') || '开启后,失败的订单会推送到 Telegram'}
|
||||
valuePropName="checked"
|
||||
>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<Space>
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user