From d9443e0d56018fe057e023cc85eec965976a4d71 Mon Sep 17 00:00:00 2001 From: WrBug Date: Sun, 4 Jan 2026 12:13:40 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20InputNumber=20forma?= =?UTF-8?q?tter=20=E6=AD=A3=E5=88=99=E8=A1=A8=E8=BE=BE=E5=BC=8F=E9=94=99?= =?UTF-8?q?=E8=AF=AF=EF=BC=8C=E5=AF=BC=E8=87=B4=E8=BE=93=E5=85=A5=2010=20?= =?UTF-8?q?=E5=8F=98=E6=88=90=201=20=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复 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+$/ 只匹配小数点后的尾随零。 --- frontend/src/pages/CopyTradingAdd.tsx | 106 +++++++++++++++++- frontend/src/pages/CopyTradingEdit.tsx | 106 +++++++++++++++++- frontend/src/pages/CopyTradingList.tsx | 4 +- .../src/pages/CopyTradingOrders/EditModal.tsx | 106 +++++++++++++++++- frontend/src/pages/TemplateAdd.tsx | 65 +++++++++-- frontend/src/pages/TemplateEdit.tsx | 65 +++++++++-- frontend/src/pages/TemplateList.tsx | 65 +++++++++-- 7 files changed, 479 insertions(+), 38 deletions(-) diff --git a/frontend/src/pages/CopyTradingAdd.tsx b/frontend/src/pages/CopyTradingAdd.tsx index 8a7dfe0..3b0a79e 100644 --- a/frontend/src/pages/CopyTradingAdd.tsx +++ b/frontend/src/pages/CopyTradingAdd.tsx @@ -344,13 +344,51 @@ const CopyTradingAdd: React.FC = () => { tooltip={t('copyTradingAdd.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单'} > { + 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 + }} /> )} @@ -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+$/, '') + }} /> )} @@ -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+$/, '') + }} /> @@ -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+$/, '') + }} /> @@ -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+$/, '') + }} /> @@ -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+$/, '') + }} /> @@ -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+$/, '') + }} /> @@ -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+$/, '') + }} /> @@ -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+$/, '') + }} /> - @@ -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+$/, '') + }} /> @@ -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+$/, '') + }} /> diff --git a/frontend/src/pages/CopyTradingEdit.tsx b/frontend/src/pages/CopyTradingEdit.tsx index db1abf8..c8b2469 100644 --- a/frontend/src/pages/CopyTradingEdit.tsx +++ b/frontend/src/pages/CopyTradingEdit.tsx @@ -237,13 +237,51 @@ const CopyTradingEdit: React.FC = () => { tooltip={t('copyTradingEdit.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比'} > { + 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 + }} /> )} @@ -276,6 +314,12 @@ const CopyTradingEdit: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> )} @@ -293,6 +337,12 @@ const CopyTradingEdit: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -320,6 +370,12 @@ const CopyTradingEdit: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -336,6 +392,12 @@ const CopyTradingEdit: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -364,6 +426,12 @@ const CopyTradingEdit: React.FC = () => { precision={2} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -391,6 +459,12 @@ const CopyTradingEdit: React.FC = () => { precision={4} style={{ width: '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+$/, '') + }} /> @@ -405,6 +479,12 @@ const CopyTradingEdit: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -424,6 +504,12 @@ const CopyTradingEdit: React.FC = () => { precision={4} style={{ width: '50%' }} 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+$/, '') + }} /> - @@ -435,6 +521,12 @@ const CopyTradingEdit: React.FC = () => { precision={4} style={{ width: '50%' }} 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+$/, '') + }} /> @@ -453,6 +545,12 @@ const CopyTradingEdit: React.FC = () => { precision={4} style={{ width: '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+$/, '') + }} /> diff --git a/frontend/src/pages/CopyTradingList.tsx b/frontend/src/pages/CopyTradingList.tsx index 4e08494..8ee8cbe 100644 --- a/frontend/src/pages/CopyTradingList.tsx +++ b/frontend/src/pages/CopyTradingList.tsx @@ -196,7 +196,7 @@ const CopyTradingList: React.FC = () => { render: (_: any, record: CopyTrading) => ( {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')}` } @@ -466,7 +466,7 @@ const CopyTradingList: React.FC = () => { color: '#666' }}> {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')}` } diff --git a/frontend/src/pages/CopyTradingOrders/EditModal.tsx b/frontend/src/pages/CopyTradingOrders/EditModal.tsx index ecca19c..61942b3 100644 --- a/frontend/src/pages/CopyTradingOrders/EditModal.tsx +++ b/frontend/src/pages/CopyTradingOrders/EditModal.tsx @@ -237,13 +237,51 @@ const EditModal: React.FC = ({ tooltip={t('copyTradingEdit.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比'} > { + 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 + }} /> )} @@ -276,6 +314,12 @@ const EditModal: React.FC = ({ precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> )} @@ -293,6 +337,12 @@ const EditModal: React.FC = ({ precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -320,6 +370,12 @@ const EditModal: React.FC = ({ precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -336,6 +392,12 @@ const EditModal: React.FC = ({ precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -364,6 +426,12 @@ const EditModal: React.FC = ({ precision={2} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -391,6 +459,12 @@ const EditModal: React.FC = ({ precision={4} style={{ width: '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+$/, '') + }} /> @@ -405,6 +479,12 @@ const EditModal: React.FC = ({ precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -424,6 +504,12 @@ const EditModal: React.FC = ({ precision={4} style={{ width: '50%' }} 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+$/, '') + }} /> - @@ -435,6 +521,12 @@ const EditModal: React.FC = ({ precision={4} style={{ width: '50%' }} 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+$/, '') + }} /> @@ -453,6 +545,12 @@ const EditModal: React.FC = ({ precision={4} style={{ width: '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+$/, '') + }} /> diff --git a/frontend/src/pages/TemplateAdd.tsx b/frontend/src/pages/TemplateAdd.tsx index 63a8a1a..0256425 100644 --- a/frontend/src/pages/TemplateAdd.tsx +++ b/frontend/src/pages/TemplateAdd.tsx @@ -127,23 +127,24 @@ const TemplateAdd: React.FC = () => { tooltip={t('templateAdd.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单'} > { const parsed = parseFloat(value || '0') - if (parsed > 1000) return 1000 + if (parsed > 10000) return 10000 return parsed }} formatter={(value) => { - if (!value) return '' + if (!value && value !== 0) return '' const num = parseFloat(value.toString()) - if (num > 1000) return '1000' - return value.toString() + if (isNaN(num)) return '' + if (num > 10000) return '10000' + return num.toString().replace(/\.0+$/, '') }} /> @@ -177,6 +178,12 @@ const TemplateAdd: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> )} @@ -194,6 +201,12 @@ const TemplateAdd: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -221,6 +234,12 @@ const TemplateAdd: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -251,6 +270,12 @@ const TemplateAdd: React.FC = () => { precision={2} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -265,6 +290,12 @@ const TemplateAdd: React.FC = () => { precision={4} style={{ width: '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+$/, '') + }} /> @@ -279,6 +310,12 @@ const TemplateAdd: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -298,6 +335,12 @@ const TemplateAdd: React.FC = () => { precision={4} style={{ width: '50%' }} 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+$/, '') + }} /> - @@ -309,6 +352,12 @@ const TemplateAdd: React.FC = () => { precision={4} style={{ width: '50%' }} 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+$/, '') + }} /> diff --git a/frontend/src/pages/TemplateEdit.tsx b/frontend/src/pages/TemplateEdit.tsx index 8d0e212..2aa379d 100644 --- a/frontend/src/pages/TemplateEdit.tsx +++ b/frontend/src/pages/TemplateEdit.tsx @@ -162,23 +162,24 @@ const TemplateEdit: React.FC = () => { tooltip={t('templateEdit.copyRatioTooltip') || '跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单'} > { const parsed = parseFloat(value || '0') - if (parsed > 1000) return 1000 + if (parsed > 10000) return 10000 return parsed }} formatter={(value) => { - if (!value) return '' + if (!value && value !== 0) return '' const num = parseFloat(value.toString()) - if (num > 1000) return '1000' - return value.toString() + if (isNaN(num)) return '' + if (num > 10000) return '10000' + return num.toString().replace(/\.0+$/, '') }} /> @@ -213,6 +214,12 @@ const TemplateEdit: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> )} @@ -230,6 +237,12 @@ const TemplateEdit: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -257,6 +270,12 @@ const TemplateEdit: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -287,6 +306,12 @@ const TemplateEdit: React.FC = () => { precision={2} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -301,6 +326,12 @@ const TemplateEdit: React.FC = () => { precision={4} style={{ width: '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+$/, '') + }} /> @@ -315,6 +346,12 @@ const TemplateEdit: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -334,6 +371,12 @@ const TemplateEdit: React.FC = () => { precision={4} style={{ width: '50%' }} 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+$/, '') + }} /> - @@ -345,6 +388,12 @@ const TemplateEdit: React.FC = () => { precision={4} style={{ width: '50%' }} 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+$/, '') + }} /> diff --git a/frontend/src/pages/TemplateList.tsx b/frontend/src/pages/TemplateList.tsx index 5eeeb5e..dc1bb9f 100644 --- a/frontend/src/pages/TemplateList.tsx +++ b/frontend/src/pages/TemplateList.tsx @@ -471,23 +471,24 @@ const TemplateList: React.FC = () => { tooltip="跟单比例表示跟单金额相对于 Leader 订单金额的百分比。例如:100% 表示 1:1 跟单,50% 表示半仓跟单,200% 表示双倍跟单" > { const parsed = parseFloat(value || '0') - if (parsed > 1000) return 1000 + if (parsed > 10000) return 10000 return parsed }} formatter={(value) => { - if (!value) return '' + if (!value && value !== 0) return '' const num = parseFloat(value.toString()) - if (num > 1000) return '1000' - return value.toString() + if (isNaN(num)) return '' + if (num > 10000) return '10000' + return num.toString().replace(/\.0+$/, '') }} /> @@ -520,6 +521,12 @@ const TemplateList: React.FC = () => { precision={4} style={{ width: '100%' }} placeholder="固定金额,不随 Leader 订单大小变化,必须 >= 1" + formatter={(value) => { + if (!value && value !== 0) return '' + const num = parseFloat(value.toString()) + if (isNaN(num)) return '' + return num.toString().replace(/\.0+$/, '') + }} /> )} @@ -537,6 +544,12 @@ const TemplateList: React.FC = () => { precision={4} style={{ width: '100%' }} placeholder="仅在比例模式下生效(可选)" + formatter={(value) => { + if (!value && value !== 0) return '' + const num = parseFloat(value.toString()) + if (isNaN(num)) return '' + return num.toString().replace(/\.0+$/, '') + }} /> @@ -564,6 +577,12 @@ const TemplateList: React.FC = () => { precision={4} style={{ width: '100%' }} placeholder="仅在比例模式下生效,必须 >= 1(可选)" + formatter={(value) => { + if (!value && value !== 0) return '' + const num = parseFloat(value.toString()) + if (isNaN(num)) return '' + return num.toString().replace(/\.0+$/, '') + }} /> @@ -594,6 +613,12 @@ const TemplateList: React.FC = () => { precision={2} style={{ width: '100%' }} placeholder="默认 5%(可选)" + formatter={(value) => { + if (!value && value !== 0) return '' + const num = parseFloat(value.toString()) + if (isNaN(num)) return '' + return num.toString().replace(/\.0+$/, '') + }} /> @@ -619,6 +644,12 @@ const TemplateList: React.FC = () => { precision={4} style={{ width: '100%' }} placeholder="例如:100(可选,不填写表示不启用)" + formatter={(value) => { + if (!value && value !== 0) return '' + const num = parseFloat(value.toString()) + if (isNaN(num)) return '' + return num.toString().replace(/\.0+$/, '') + }} /> @@ -633,6 +664,12 @@ const TemplateList: React.FC = () => { precision={4} style={{ width: '100%' }} 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+$/, '') + }} /> @@ -652,6 +689,12 @@ const TemplateList: React.FC = () => { precision={4} style={{ width: '50%' }} placeholder="最低价(留空不限制)" + formatter={(value) => { + if (!value && value !== 0) return '' + const num = parseFloat(value.toString()) + if (isNaN(num)) return '' + return num.toString().replace(/\.0+$/, '') + }} /> - @@ -663,6 +706,12 @@ const TemplateList: React.FC = () => { precision={4} style={{ width: '50%' }} placeholder="最高价(留空不限制)" + formatter={(value) => { + if (!value && value !== 0) return '' + const num = parseFloat(value.toString()) + if (isNaN(num)) return '' + return num.toString().replace(/\.0+$/, '') + }} />