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:
WrBug
2026-01-04 12:13:40 +08:00
parent a097376db7
commit d9443e0d56
7 changed files with 479 additions and 38 deletions
+102 -4
View File
@@ -344,13 +344,51 @@ const CopyTradingAdd: React.FC = () => {
tooltip={t('copyTradingAdd.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单'}
>
<InputNumber
min={10}
max={1000}
step={1}
precision={0}
min={0.01}
max={10000}
step={0.01}
precision={2}
style={{ width: '100%' }}
addonAfter="%"
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>
)}
@@ -383,6 +421,12 @@ const CopyTradingAdd: React.FC = () => {
precision={4}
style={{ width: '100%' }}
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>
)}
@@ -400,6 +444,12 @@ const CopyTradingAdd: React.FC = () => {
precision={4}
style={{ width: '100%' }}
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>
@@ -427,6 +477,12 @@ const CopyTradingAdd: React.FC = () => {
precision={4}
style={{ width: '100%' }}
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>
</>
@@ -443,6 +499,12 @@ const CopyTradingAdd: React.FC = () => {
precision={4}
style={{ width: '100%' }}
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>
@@ -471,6 +533,12 @@ const CopyTradingAdd: React.FC = () => {
precision={2}
style={{ width: '100%' }}
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>
@@ -498,6 +566,12 @@ const CopyTradingAdd: React.FC = () => {
precision={4}
style={{ width: '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>
@@ -512,6 +586,12 @@ const CopyTradingAdd: React.FC = () => {
precision={4}
style={{ width: '100%' }}
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>
@@ -531,6 +611,12 @@ const CopyTradingAdd: React.FC = () => {
precision={4}
style={{ width: '50%' }}
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>
<span style={{ display: 'inline-block', width: '20px', textAlign: 'center', lineHeight: '32px' }}>-</span>
@@ -542,6 +628,12 @@ const CopyTradingAdd: React.FC = () => {
precision={4}
style={{ width: '50%' }}
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>
</Input.Group>
@@ -560,6 +652,12 @@ const CopyTradingAdd: React.FC = () => {
precision={4}
style={{ width: '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>