fix: 修复 InputNumber formatter 正则表达式错误,导致输入 10 变成 1 的问题
- 修复 copyRatio InputNumber 的 parser 函数,正确处理 % 符号和最小值检查 - 修复所有 formatter 函数中的正则表达式:将 /\.?0+$/ 改为 /\.0+$/ - 添加调试日志用于问题排查(可后续移除) 修复的文件: - CopyTradingAdd.tsx - CopyTradingEdit.tsx - CopyTradingOrders/EditModal.tsx - CopyTradingList.tsx - TemplateList.tsx - TemplateEdit.tsx - TemplateAdd.tsx 问题原因: 错误的正则表达式 /\.?0+$/ 会匹配整数末尾的 0(如 "10" 的末尾 "0"), 导致 "10" 被错误替换为 "1"。 正确的正则表达式 /\.0+$/ 只匹配小数点后的尾随零。
This commit is contained in:
@@ -344,13 +344,51 @@ const CopyTradingAdd: React.FC = () => {
|
|||||||
tooltip={t('copyTradingAdd.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单'}
|
tooltip={t('copyTradingAdd.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单'}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
min={10}
|
min={0.01}
|
||||||
max={1000}
|
max={10000}
|
||||||
step={1}
|
step={0.01}
|
||||||
precision={0}
|
precision={2}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
addonAfter="%"
|
addonAfter="%"
|
||||||
placeholder={t('copyTradingAdd.copyRatioPlaceholder') || '例如:100 表示 100%(1:1 跟单),默认 100%'}
|
placeholder={t('copyTradingAdd.copyRatioPlaceholder') || '例如:100 表示 100%(1:1 跟单),默认 100%'}
|
||||||
|
parser={(value) => {
|
||||||
|
console.log('[CopyTradingAdd copyRatio parser] 输入值:', value, '类型:', typeof value)
|
||||||
|
// 移除 % 符号和其他非数字字符(保留小数点和负号)
|
||||||
|
const cleaned = (value || '').toString().replace(/%/g, '').trim()
|
||||||
|
console.log('[CopyTradingAdd copyRatio parser] 清理后:', cleaned)
|
||||||
|
const parsed = parseFloat(cleaned) || 0
|
||||||
|
console.log('[CopyTradingAdd copyRatio parser] 解析后:', parsed)
|
||||||
|
if (parsed > 10000) {
|
||||||
|
console.log('[CopyTradingAdd copyRatio parser] 超过最大值,返回 10000')
|
||||||
|
return 10000
|
||||||
|
}
|
||||||
|
if (parsed < 0.01) {
|
||||||
|
console.log('[CopyTradingAdd copyRatio parser] 小于最小值,返回 0.01')
|
||||||
|
return 0.01
|
||||||
|
}
|
||||||
|
console.log('[CopyTradingAdd copyRatio parser] 返回:', parsed)
|
||||||
|
return parsed
|
||||||
|
}}
|
||||||
|
formatter={(value) => {
|
||||||
|
console.log('[CopyTradingAdd copyRatio formatter] 输入值:', value, '类型:', typeof value)
|
||||||
|
if (!value && value !== 0) {
|
||||||
|
console.log('[CopyTradingAdd copyRatio formatter] 空值,返回空字符串')
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
console.log('[CopyTradingAdd copyRatio formatter] 解析后:', num)
|
||||||
|
if (isNaN(num)) {
|
||||||
|
console.log('[CopyTradingAdd copyRatio formatter] NaN,返回空字符串')
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
if (num > 10000) {
|
||||||
|
console.log('[CopyTradingAdd copyRatio formatter] 超过最大值,返回 10000')
|
||||||
|
return '10000'
|
||||||
|
}
|
||||||
|
const result = num.toString().replace(/\.0+$/, '')
|
||||||
|
console.log('[CopyTradingAdd copyRatio formatter] 格式化后返回:', result)
|
||||||
|
return result
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
@@ -383,6 +421,12 @@ const CopyTradingAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingAdd.fixedAmountPlaceholder') || '固定金额,不随 Leader 订单大小变化,必须 >= 1'}
|
placeholder={t('copyTradingAdd.fixedAmountPlaceholder') || '固定金额,不随 Leader 订单大小变化,必须 >= 1'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
@@ -400,6 +444,12 @@ const CopyTradingAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingAdd.maxOrderSizePlaceholder') || '仅在比例模式下生效(可选)'}
|
placeholder={t('copyTradingAdd.maxOrderSizePlaceholder') || '仅在比例模式下生效(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -427,6 +477,12 @@ const CopyTradingAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingAdd.minOrderSizePlaceholder') || '仅在比例模式下生效,必须 >= 1(可选)'}
|
placeholder={t('copyTradingAdd.minOrderSizePlaceholder') || '仅在比例模式下生效,必须 >= 1(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
@@ -443,6 +499,12 @@ const CopyTradingAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingAdd.maxDailyLossPlaceholder') || '默认 10000 USDC(可选)'}
|
placeholder={t('copyTradingAdd.maxDailyLossPlaceholder') || '默认 10000 USDC(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -471,6 +533,12 @@ const CopyTradingAdd: React.FC = () => {
|
|||||||
precision={2}
|
precision={2}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingAdd.priceTolerancePlaceholder') || '默认 5%(可选)'}
|
placeholder={t('copyTradingAdd.priceTolerancePlaceholder') || '默认 5%(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -498,6 +566,12 @@ const CopyTradingAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingAdd.minOrderDepthPlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
placeholder={t('copyTradingAdd.minOrderDepthPlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -512,6 +586,12 @@ const CopyTradingAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingAdd.maxSpreadPlaceholder') || '例如:0.05(5美分,可选,不填写表示不启用)'}
|
placeholder={t('copyTradingAdd.maxSpreadPlaceholder') || '例如:0.05(5美分,可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -531,6 +611,12 @@ const CopyTradingAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '50%' }}
|
style={{ width: '50%' }}
|
||||||
placeholder={t('copyTradingAdd.minPricePlaceholder') || '最低价(可选)'}
|
placeholder={t('copyTradingAdd.minPricePlaceholder') || '最低价(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
|
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
|
||||||
@@ -542,6 +628,12 @@ const CopyTradingAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '50%' }}
|
style={{ width: '50%' }}
|
||||||
placeholder={t('copyTradingAdd.maxPricePlaceholder') || '最高价(可选)'}
|
placeholder={t('copyTradingAdd.maxPricePlaceholder') || '最高价(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Input.Group>
|
</Input.Group>
|
||||||
@@ -560,6 +652,12 @@ const CopyTradingAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingAdd.maxPositionValuePlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
placeholder={t('copyTradingAdd.maxPositionValuePlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
|||||||
@@ -237,13 +237,51 @@ const CopyTradingEdit: React.FC = () => {
|
|||||||
tooltip={t('copyTradingEdit.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比'}
|
tooltip={t('copyTradingEdit.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比'}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
min={10}
|
min={0.01}
|
||||||
max={1000}
|
max={10000}
|
||||||
step={1}
|
step={0.01}
|
||||||
precision={0}
|
precision={2}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
addonAfter="%"
|
addonAfter="%"
|
||||||
placeholder={t('copyTradingEdit.copyRatioPlaceholder') || '例如:100 表示 100%(1:1 跟单)'}
|
placeholder={t('copyTradingEdit.copyRatioPlaceholder') || '例如:100 表示 100%(1:1 跟单)'}
|
||||||
|
parser={(value) => {
|
||||||
|
console.log('[CopyTradingEdit copyRatio parser] 输入值:', value, '类型:', typeof value)
|
||||||
|
// 移除 % 符号和其他非数字字符(保留小数点和负号)
|
||||||
|
const cleaned = (value || '').toString().replace(/%/g, '').trim()
|
||||||
|
console.log('[CopyTradingEdit copyRatio parser] 清理后:', cleaned)
|
||||||
|
const parsed = parseFloat(cleaned) || 0
|
||||||
|
console.log('[CopyTradingEdit copyRatio parser] 解析后:', parsed)
|
||||||
|
if (parsed > 10000) {
|
||||||
|
console.log('[CopyTradingEdit copyRatio parser] 超过最大值,返回 10000')
|
||||||
|
return 10000
|
||||||
|
}
|
||||||
|
if (parsed < 0.01) {
|
||||||
|
console.log('[CopyTradingEdit copyRatio parser] 小于最小值,返回 0.01')
|
||||||
|
return 0.01
|
||||||
|
}
|
||||||
|
console.log('[CopyTradingEdit copyRatio parser] 返回:', parsed)
|
||||||
|
return parsed
|
||||||
|
}}
|
||||||
|
formatter={(value) => {
|
||||||
|
console.log('[CopyTradingEdit copyRatio formatter] 输入值:', value, '类型:', typeof value)
|
||||||
|
if (!value && value !== 0) {
|
||||||
|
console.log('[CopyTradingEdit copyRatio formatter] 空值,返回空字符串')
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
console.log('[CopyTradingEdit copyRatio formatter] 解析后:', num)
|
||||||
|
if (isNaN(num)) {
|
||||||
|
console.log('[CopyTradingEdit copyRatio formatter] NaN,返回空字符串')
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
if (num > 10000) {
|
||||||
|
console.log('[CopyTradingEdit copyRatio formatter] 超过最大值,返回 10000')
|
||||||
|
return '10000'
|
||||||
|
}
|
||||||
|
const result = num.toString().replace(/\.0+$/, '')
|
||||||
|
console.log('[CopyTradingEdit copyRatio formatter] 格式化后返回:', result)
|
||||||
|
return result
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
@@ -276,6 +314,12 @@ const CopyTradingEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.fixedAmountPlaceholder') || '固定金额,不随 Leader 订单大小变化,必须 >= 1'}
|
placeholder={t('copyTradingEdit.fixedAmountPlaceholder') || '固定金额,不随 Leader 订单大小变化,必须 >= 1'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
@@ -293,6 +337,12 @@ const CopyTradingEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.maxOrderSizePlaceholder') || '仅在比例模式下生效(可选)'}
|
placeholder={t('copyTradingEdit.maxOrderSizePlaceholder') || '仅在比例模式下生效(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -320,6 +370,12 @@ const CopyTradingEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.minOrderSizePlaceholder') || '仅在比例模式下生效,必须 >= 1(可选)'}
|
placeholder={t('copyTradingEdit.minOrderSizePlaceholder') || '仅在比例模式下生效,必须 >= 1(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
@@ -336,6 +392,12 @@ const CopyTradingEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.maxDailyLossPlaceholder') || '默认 10000 USDC(可选)'}
|
placeholder={t('copyTradingEdit.maxDailyLossPlaceholder') || '默认 10000 USDC(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -364,6 +426,12 @@ const CopyTradingEdit: React.FC = () => {
|
|||||||
precision={2}
|
precision={2}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.priceTolerancePlaceholder') || '默认 5%(可选)'}
|
placeholder={t('copyTradingEdit.priceTolerancePlaceholder') || '默认 5%(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -391,6 +459,12 @@ const CopyTradingEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.minOrderDepthPlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
placeholder={t('copyTradingEdit.minOrderDepthPlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -405,6 +479,12 @@ const CopyTradingEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.maxSpreadPlaceholder') || '例如:0.05(5美分,可选,不填写表示不启用)'}
|
placeholder={t('copyTradingEdit.maxSpreadPlaceholder') || '例如:0.05(5美分,可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -424,6 +504,12 @@ const CopyTradingEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '50%' }}
|
style={{ width: '50%' }}
|
||||||
placeholder={t('copyTradingEdit.minPricePlaceholder') || '最低价(可选)'}
|
placeholder={t('copyTradingEdit.minPricePlaceholder') || '最低价(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
|
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
|
||||||
@@ -435,6 +521,12 @@ const CopyTradingEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '50%' }}
|
style={{ width: '50%' }}
|
||||||
placeholder={t('copyTradingEdit.maxPricePlaceholder') || '最高价(可选)'}
|
placeholder={t('copyTradingEdit.maxPricePlaceholder') || '最高价(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Input.Group>
|
</Input.Group>
|
||||||
@@ -453,6 +545,12 @@ const CopyTradingEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.maxPositionValuePlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
placeholder={t('copyTradingEdit.maxPositionValuePlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ const CopyTradingList: React.FC = () => {
|
|||||||
render: (_: any, record: CopyTrading) => (
|
render: (_: any, record: CopyTrading) => (
|
||||||
<Tag color={record.copyMode === 'RATIO' ? 'blue' : 'green'}>
|
<Tag color={record.copyMode === 'RATIO' ? 'blue' : 'green'}>
|
||||||
{record.copyMode === 'RATIO'
|
{record.copyMode === 'RATIO'
|
||||||
? `${t('copyTradingList.ratioMode') || '比例'} ${record.copyRatio}x`
|
? `${t('copyTradingList.ratioMode') || '比例'} ${(parseFloat(record.copyRatio || '0') * 100).toFixed(2).replace(/\.0+$/, '')}%`
|
||||||
: `${t('copyTradingList.fixedAmountMode') || '固定'} ${formatUSDC(record.fixedAmount || '0')}`
|
: `${t('copyTradingList.fixedAmountMode') || '固定'} ${formatUSDC(record.fixedAmount || '0')}`
|
||||||
}
|
}
|
||||||
</Tag>
|
</Tag>
|
||||||
@@ -466,7 +466,7 @@ const CopyTradingList: React.FC = () => {
|
|||||||
color: '#666'
|
color: '#666'
|
||||||
}}>
|
}}>
|
||||||
{record.copyMode === 'RATIO'
|
{record.copyMode === 'RATIO'
|
||||||
? `${t('copyTradingList.ratioMode') || '比例'} ${record.copyRatio}x`
|
? `${t('copyTradingList.ratioMode') || '比例'} ${(parseFloat(record.copyRatio || '0') * 100).toFixed(2).replace(/\.0+$/, '')}%`
|
||||||
: `${t('copyTradingList.fixedAmountMode') || '固定'} ${formatUSDC(record.fixedAmount || '0')}`
|
: `${t('copyTradingList.fixedAmountMode') || '固定'} ${formatUSDC(record.fixedAmount || '0')}`
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -237,13 +237,51 @@ const EditModal: React.FC<EditModalProps> = ({
|
|||||||
tooltip={t('copyTradingEdit.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比'}
|
tooltip={t('copyTradingEdit.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比'}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
min={10}
|
min={0.01}
|
||||||
max={1000}
|
max={10000}
|
||||||
step={1}
|
step={0.01}
|
||||||
precision={0}
|
precision={2}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
addonAfter="%"
|
addonAfter="%"
|
||||||
placeholder={t('copyTradingEdit.copyRatioPlaceholder') || '例如:100 表示 100%(1:1 跟单)'}
|
placeholder={t('copyTradingEdit.copyRatioPlaceholder') || '例如:100 表示 100%(1:1 跟单)'}
|
||||||
|
parser={(value) => {
|
||||||
|
console.log('[EditModal copyRatio parser] 输入值:', value, '类型:', typeof value)
|
||||||
|
// 移除 % 符号和其他非数字字符(保留小数点和负号)
|
||||||
|
const cleaned = (value || '').toString().replace(/%/g, '').trim()
|
||||||
|
console.log('[EditModal copyRatio parser] 清理后:', cleaned)
|
||||||
|
const parsed = parseFloat(cleaned) || 0
|
||||||
|
console.log('[EditModal copyRatio parser] 解析后:', parsed)
|
||||||
|
if (parsed > 10000) {
|
||||||
|
console.log('[EditModal copyRatio parser] 超过最大值,返回 10000')
|
||||||
|
return 10000
|
||||||
|
}
|
||||||
|
if (parsed < 0.01) {
|
||||||
|
console.log('[EditModal copyRatio parser] 小于最小值,返回 0.01')
|
||||||
|
return 0.01
|
||||||
|
}
|
||||||
|
console.log('[EditModal copyRatio parser] 返回:', parsed)
|
||||||
|
return parsed
|
||||||
|
}}
|
||||||
|
formatter={(value) => {
|
||||||
|
console.log('[EditModal copyRatio formatter] 输入值:', value, '类型:', typeof value)
|
||||||
|
if (!value && value !== 0) {
|
||||||
|
console.log('[EditModal copyRatio formatter] 空值,返回空字符串')
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
console.log('[EditModal copyRatio formatter] 解析后:', num)
|
||||||
|
if (isNaN(num)) {
|
||||||
|
console.log('[EditModal copyRatio formatter] NaN,返回空字符串')
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
if (num > 10000) {
|
||||||
|
console.log('[EditModal copyRatio formatter] 超过最大值,返回 10000')
|
||||||
|
return '10000'
|
||||||
|
}
|
||||||
|
const result = num.toString().replace(/\.0+$/, '')
|
||||||
|
console.log('[EditModal copyRatio formatter] 格式化后返回:', result)
|
||||||
|
return result
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
@@ -276,6 +314,12 @@ const EditModal: React.FC<EditModalProps> = ({
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.fixedAmountPlaceholder') || '固定金额,不随 Leader 订单大小变化,必须 >= 1'}
|
placeholder={t('copyTradingEdit.fixedAmountPlaceholder') || '固定金额,不随 Leader 订单大小变化,必须 >= 1'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
@@ -293,6 +337,12 @@ const EditModal: React.FC<EditModalProps> = ({
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.maxOrderSizePlaceholder') || '仅在比例模式下生效(可选)'}
|
placeholder={t('copyTradingEdit.maxOrderSizePlaceholder') || '仅在比例模式下生效(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -320,6 +370,12 @@ const EditModal: React.FC<EditModalProps> = ({
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.minOrderSizePlaceholder') || '仅在比例模式下生效,必须 >= 1(可选)'}
|
placeholder={t('copyTradingEdit.minOrderSizePlaceholder') || '仅在比例模式下生效,必须 >= 1(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
@@ -336,6 +392,12 @@ const EditModal: React.FC<EditModalProps> = ({
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.maxDailyLossPlaceholder') || '默认 10000 USDC(可选)'}
|
placeholder={t('copyTradingEdit.maxDailyLossPlaceholder') || '默认 10000 USDC(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -364,6 +426,12 @@ const EditModal: React.FC<EditModalProps> = ({
|
|||||||
precision={2}
|
precision={2}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.priceTolerancePlaceholder') || '默认 5%(可选)'}
|
placeholder={t('copyTradingEdit.priceTolerancePlaceholder') || '默认 5%(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -391,6 +459,12 @@ const EditModal: React.FC<EditModalProps> = ({
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.minOrderDepthPlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
placeholder={t('copyTradingEdit.minOrderDepthPlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -405,6 +479,12 @@ const EditModal: React.FC<EditModalProps> = ({
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.maxSpreadPlaceholder') || '例如:0.05(5美分,可选,不填写表示不启用)'}
|
placeholder={t('copyTradingEdit.maxSpreadPlaceholder') || '例如:0.05(5美分,可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -424,6 +504,12 @@ const EditModal: React.FC<EditModalProps> = ({
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '50%' }}
|
style={{ width: '50%' }}
|
||||||
placeholder={t('copyTradingEdit.minPricePlaceholder') || '最低价(可选)'}
|
placeholder={t('copyTradingEdit.minPricePlaceholder') || '最低价(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
|
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
|
||||||
@@ -435,6 +521,12 @@ const EditModal: React.FC<EditModalProps> = ({
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '50%' }}
|
style={{ width: '50%' }}
|
||||||
placeholder={t('copyTradingEdit.maxPricePlaceholder') || '最高价(可选)'}
|
placeholder={t('copyTradingEdit.maxPricePlaceholder') || '最高价(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Input.Group>
|
</Input.Group>
|
||||||
@@ -453,6 +545,12 @@ const EditModal: React.FC<EditModalProps> = ({
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('copyTradingEdit.maxPositionValuePlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
placeholder={t('copyTradingEdit.maxPositionValuePlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
|||||||
@@ -127,23 +127,24 @@ const TemplateAdd: React.FC = () => {
|
|||||||
tooltip={t('templateAdd.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单'}
|
tooltip={t('templateAdd.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单'}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
min={10}
|
min={0.01}
|
||||||
max={1000}
|
max={10000}
|
||||||
step={1}
|
step={0.01}
|
||||||
precision={0}
|
precision={2}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
addonAfter="%"
|
addonAfter="%"
|
||||||
placeholder={t('templateAdd.copyRatioPlaceholder') || '例如:100 表示 100%(1:1 跟单),默认 100%'}
|
placeholder={t('templateAdd.copyRatioPlaceholder') || '例如:100 表示 100%(1:1 跟单),默认 100%'}
|
||||||
parser={(value) => {
|
parser={(value) => {
|
||||||
const parsed = parseFloat(value || '0')
|
const parsed = parseFloat(value || '0')
|
||||||
if (parsed > 1000) return 1000
|
if (parsed > 10000) return 10000
|
||||||
return parsed
|
return parsed
|
||||||
}}
|
}}
|
||||||
formatter={(value) => {
|
formatter={(value) => {
|
||||||
if (!value) return ''
|
if (!value && value !== 0) return ''
|
||||||
const num = parseFloat(value.toString())
|
const num = parseFloat(value.toString())
|
||||||
if (num > 1000) return '1000'
|
if (isNaN(num)) return ''
|
||||||
return value.toString()
|
if (num > 10000) return '10000'
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -177,6 +178,12 @@ const TemplateAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('templateAdd.fixedAmountPlaceholder') || '固定金额,不随 Leader 订单大小变化,必须 >= 1'}
|
placeholder={t('templateAdd.fixedAmountPlaceholder') || '固定金额,不随 Leader 订单大小变化,必须 >= 1'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
@@ -194,6 +201,12 @@ const TemplateAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('templateAdd.maxOrderSizePlaceholder') || '仅在比例模式下生效(可选)'}
|
placeholder={t('templateAdd.maxOrderSizePlaceholder') || '仅在比例模式下生效(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -221,6 +234,12 @@ const TemplateAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('templateAdd.minOrderSizePlaceholder') || '仅在比例模式下生效,必须 >= 1(可选)'}
|
placeholder={t('templateAdd.minOrderSizePlaceholder') || '仅在比例模式下生效,必须 >= 1(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
@@ -251,6 +270,12 @@ const TemplateAdd: React.FC = () => {
|
|||||||
precision={2}
|
precision={2}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('templateAdd.priceTolerancePlaceholder') || '默认 5%(可选)'}
|
placeholder={t('templateAdd.priceTolerancePlaceholder') || '默认 5%(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -265,6 +290,12 @@ const TemplateAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('templateAdd.minOrderDepthPlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
placeholder={t('templateAdd.minOrderDepthPlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -279,6 +310,12 @@ const TemplateAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('templateAdd.maxSpreadPlaceholder') || '例如:0.05(5美分,可选,不填写表示不启用)'}
|
placeholder={t('templateAdd.maxSpreadPlaceholder') || '例如:0.05(5美分,可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -298,6 +335,12 @@ const TemplateAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '50%' }}
|
style={{ width: '50%' }}
|
||||||
placeholder={t('templateAdd.minPricePlaceholder') || '最低价(可选)'}
|
placeholder={t('templateAdd.minPricePlaceholder') || '最低价(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
|
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
|
||||||
@@ -309,6 +352,12 @@ const TemplateAdd: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '50%' }}
|
style={{ width: '50%' }}
|
||||||
placeholder={t('templateAdd.maxPricePlaceholder') || '最高价(可选)'}
|
placeholder={t('templateAdd.maxPricePlaceholder') || '最高价(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Input.Group>
|
</Input.Group>
|
||||||
|
|||||||
@@ -162,23 +162,24 @@ const TemplateEdit: React.FC = () => {
|
|||||||
tooltip={t('templateEdit.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单'}
|
tooltip={t('templateEdit.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单'}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
min={10}
|
min={0.01}
|
||||||
max={1000}
|
max={10000}
|
||||||
step={1}
|
step={0.01}
|
||||||
precision={0}
|
precision={2}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
addonAfter="%"
|
addonAfter="%"
|
||||||
placeholder={t('templateEdit.copyRatioPlaceholder') || '例如:100 表示 100%(1:1 跟单),默认 100%'}
|
placeholder={t('templateEdit.copyRatioPlaceholder') || '例如:100 表示 100%(1:1 跟单),默认 100%'}
|
||||||
parser={(value) => {
|
parser={(value) => {
|
||||||
const parsed = parseFloat(value || '0')
|
const parsed = parseFloat(value || '0')
|
||||||
if (parsed > 1000) return 1000
|
if (parsed > 10000) return 10000
|
||||||
return parsed
|
return parsed
|
||||||
}}
|
}}
|
||||||
formatter={(value) => {
|
formatter={(value) => {
|
||||||
if (!value) return ''
|
if (!value && value !== 0) return ''
|
||||||
const num = parseFloat(value.toString())
|
const num = parseFloat(value.toString())
|
||||||
if (num > 1000) return '1000'
|
if (isNaN(num)) return ''
|
||||||
return value.toString()
|
if (num > 10000) return '10000'
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -213,6 +214,12 @@ const TemplateEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('templateEdit.fixedAmountPlaceholder') || '固定金额,不随 Leader 订单大小变化,必须 >= 1'}
|
placeholder={t('templateEdit.fixedAmountPlaceholder') || '固定金额,不随 Leader 订单大小变化,必须 >= 1'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
@@ -230,6 +237,12 @@ const TemplateEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('templateEdit.maxOrderSizePlaceholder') || '仅在比例模式下生效(可选)'}
|
placeholder={t('templateEdit.maxOrderSizePlaceholder') || '仅在比例模式下生效(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -257,6 +270,12 @@ const TemplateEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('templateEdit.minOrderSizePlaceholder') || '仅在比例模式下生效,必须 >= 1(可选)'}
|
placeholder={t('templateEdit.minOrderSizePlaceholder') || '仅在比例模式下生效,必须 >= 1(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
@@ -287,6 +306,12 @@ const TemplateEdit: React.FC = () => {
|
|||||||
precision={2}
|
precision={2}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('templateEdit.priceTolerancePlaceholder') || '默认 5%(可选)'}
|
placeholder={t('templateEdit.priceTolerancePlaceholder') || '默认 5%(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -301,6 +326,12 @@ const TemplateEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('templateEdit.minOrderDepthPlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
placeholder={t('templateEdit.minOrderDepthPlaceholder') || '例如:100(可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -315,6 +346,12 @@ const TemplateEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('templateEdit.maxSpreadPlaceholder') || '例如:0.05(5美分,可选,不填写表示不启用)'}
|
placeholder={t('templateEdit.maxSpreadPlaceholder') || '例如:0.05(5美分,可选,不填写表示不启用)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -334,6 +371,12 @@ const TemplateEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '50%' }}
|
style={{ width: '50%' }}
|
||||||
placeholder={t('templateEdit.minPricePlaceholder') || '最低价(可选)'}
|
placeholder={t('templateEdit.minPricePlaceholder') || '最低价(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
|
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
|
||||||
@@ -345,6 +388,12 @@ const TemplateEdit: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '50%' }}
|
style={{ width: '50%' }}
|
||||||
placeholder={t('templateEdit.maxPricePlaceholder') || '最高价(可选)'}
|
placeholder={t('templateEdit.maxPricePlaceholder') || '最高价(可选)'}
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Input.Group>
|
</Input.Group>
|
||||||
|
|||||||
@@ -471,23 +471,24 @@ const TemplateList: React.FC = () => {
|
|||||||
tooltip="跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单"
|
tooltip="跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单"
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
min={10}
|
min={0.01}
|
||||||
max={1000}
|
max={10000}
|
||||||
step={1}
|
step={0.01}
|
||||||
precision={0}
|
precision={2}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
addonAfter="%"
|
addonAfter="%"
|
||||||
placeholder="例如:100 表示 100%(1:1 跟单),默认 100%"
|
placeholder="例如:100 表示 100%(1:1 跟单),默认 100%"
|
||||||
parser={(value) => {
|
parser={(value) => {
|
||||||
const parsed = parseFloat(value || '0')
|
const parsed = parseFloat(value || '0')
|
||||||
if (parsed > 1000) return 1000
|
if (parsed > 10000) return 10000
|
||||||
return parsed
|
return parsed
|
||||||
}}
|
}}
|
||||||
formatter={(value) => {
|
formatter={(value) => {
|
||||||
if (!value) return ''
|
if (!value && value !== 0) return ''
|
||||||
const num = parseFloat(value.toString())
|
const num = parseFloat(value.toString())
|
||||||
if (num > 1000) return '1000'
|
if (isNaN(num)) return ''
|
||||||
return value.toString()
|
if (num > 10000) return '10000'
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -520,6 +521,12 @@ const TemplateList: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder="固定金额,不随 Leader 订单大小变化,必须 >= 1"
|
placeholder="固定金额,不随 Leader 订单大小变化,必须 >= 1"
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
@@ -537,6 +544,12 @@ const TemplateList: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder="仅在比例模式下生效(可选)"
|
placeholder="仅在比例模式下生效(可选)"
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -564,6 +577,12 @@ const TemplateList: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder="仅在比例模式下生效,必须 >= 1(可选)"
|
placeholder="仅在比例模式下生效,必须 >= 1(可选)"
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
@@ -594,6 +613,12 @@ const TemplateList: React.FC = () => {
|
|||||||
precision={2}
|
precision={2}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder="默认 5%(可选)"
|
placeholder="默认 5%(可选)"
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -619,6 +644,12 @@ const TemplateList: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder="例如:100(可选,不填写表示不启用)"
|
placeholder="例如:100(可选,不填写表示不启用)"
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -633,6 +664,12 @@ const TemplateList: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder="例如:0.05(5美分,可选,不填写表示不启用)"
|
placeholder="例如:0.05(5美分,可选,不填写表示不启用)"
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -652,6 +689,12 @@ const TemplateList: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '50%' }}
|
style={{ width: '50%' }}
|
||||||
placeholder="最低价(留空不限制)"
|
placeholder="最低价(留空不限制)"
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
|
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
|
||||||
@@ -663,6 +706,12 @@ const TemplateList: React.FC = () => {
|
|||||||
precision={4}
|
precision={4}
|
||||||
style={{ width: '50%' }}
|
style={{ width: '50%' }}
|
||||||
placeholder="最高价(留空不限制)"
|
placeholder="最高价(留空不限制)"
|
||||||
|
formatter={(value) => {
|
||||||
|
if (!value && value !== 0) return ''
|
||||||
|
const num = parseFloat(value.toString())
|
||||||
|
if (isNaN(num)) return ''
|
||||||
|
return num.toString().replace(/\.0+$/, '')
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Input.Group>
|
</Input.Group>
|
||||||
|
|||||||
Reference in New Issue
Block a user