This commit is contained in:
薇薇安 2026-01-15 09:03:33 +08:00
parent 02d1fccf29
commit fb3b973d78
2 changed files with 44 additions and 15 deletions

View File

@ -315,6 +315,9 @@
} }
.config-input-wrapper { .config-input-wrapper {
display: flex;
align-items: center;
gap: 0.5rem;
display: flex; display: flex;
gap: 0.5rem; gap: 0.5rem;
align-items: center; align-items: center;
@ -324,6 +327,13 @@
flex: 1; flex: 1;
} }
.percent-suffix {
color: #666;
font-size: 0.9rem;
font-weight: 500;
white-space: nowrap;
}
.save-btn { .save-btn {
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
background: #4CAF50; background: #4CAF50;

View File

@ -10,17 +10,18 @@ const ConfigPanel = () => {
const [message, setMessage] = useState('') const [message, setMessage] = useState('')
// //
// 使2.02%0.02
const presets = { const presets = {
conservative: { conservative: {
name: '保守配置', name: '保守配置',
desc: '适合新手,风险较低,交易频率适中', desc: '适合新手,风险较低,交易频率适中',
configs: { configs: {
SCAN_INTERVAL: 3600, SCAN_INTERVAL: 3600,
MIN_CHANGE_PERCENT: 2.0, MIN_CHANGE_PERCENT: 2.0, // 2%
MIN_SIGNAL_STRENGTH: 5, MIN_SIGNAL_STRENGTH: 5,
TOP_N_SYMBOLS: 10, TOP_N_SYMBOLS: 10,
MAX_SCAN_SYMBOLS: 150, MAX_SCAN_SYMBOLS: 150,
MIN_VOLATILITY: 0.02 MIN_VOLATILITY: 0.02 //
} }
}, },
balanced: { balanced: {
@ -28,11 +29,11 @@ const ConfigPanel = () => {
desc: '推荐使用,平衡频率和质量', desc: '推荐使用,平衡频率和质量',
configs: { configs: {
SCAN_INTERVAL: 600, SCAN_INTERVAL: 600,
MIN_CHANGE_PERCENT: 1.5, MIN_CHANGE_PERCENT: 1.5, // 1.5%
MIN_SIGNAL_STRENGTH: 4, MIN_SIGNAL_STRENGTH: 4,
TOP_N_SYMBOLS: 12, TOP_N_SYMBOLS: 12,
MAX_SCAN_SYMBOLS: 250, MAX_SCAN_SYMBOLS: 250,
MIN_VOLATILITY: 0.018 MIN_VOLATILITY: 0.018 //
} }
}, },
aggressive: { aggressive: {
@ -40,11 +41,11 @@ const ConfigPanel = () => {
desc: '晚间波动大时使用,交易频率高', desc: '晚间波动大时使用,交易频率高',
configs: { configs: {
SCAN_INTERVAL: 300, SCAN_INTERVAL: 300,
MIN_CHANGE_PERCENT: 1.0, MIN_CHANGE_PERCENT: 1.0, // 1%
MIN_SIGNAL_STRENGTH: 3, MIN_SIGNAL_STRENGTH: 3,
TOP_N_SYMBOLS: 18, TOP_N_SYMBOLS: 18,
MAX_SCAN_SYMBOLS: 350, MAX_SCAN_SYMBOLS: 350,
MIN_VOLATILITY: 0.015 MIN_VOLATILITY: 0.015 //
} }
} }
} }
@ -267,10 +268,15 @@ const ConfigItem = ({ label, config, onUpdate, disabled }) => {
// //
let finalValue = localValue let finalValue = localValue
if (config.type === 'number') { if (config.type === 'number') {
finalValue = parseFloat(localValue) || 0 const numValue = parseFloat(localValue)
// if (isNaN(numValue)) {
//
return
}
finalValue = numValue
// 50.05
if (label.includes('PERCENT')) { if (label.includes('PERCENT')) {
finalValue = finalValue finalValue = finalValue / 100
} }
} else if (config.type === 'boolean') { } else if (config.type === 'boolean') {
finalValue = localValue === 'true' || localValue === true finalValue = localValue === 'true' || localValue === true
@ -292,8 +298,9 @@ const ConfigItem = ({ label, config, onUpdate, disabled }) => {
} }
} }
// 5
const displayValue = config.type === 'number' && label.includes('PERCENT') const displayValue = config.type === 'number' && label.includes('PERCENT')
? (localValue * 100).toFixed(2) ? (localValue === '' || isNaN(localValue) ? '' : Math.round(localValue * 100))
: localValue : localValue
if (config.type === 'boolean') { if (config.type === 'boolean') {
@ -402,19 +409,31 @@ const ConfigItem = ({ label, config, onUpdate, disabled }) => {
<div className="config-input-wrapper"> <div className="config-input-wrapper">
<input <input
type={config.type === 'number' ? 'number' : 'text'} type={config.type === 'number' ? 'number' : 'text'}
value={label.includes('PERCENT') ? displayValue : localValue} value={label.includes('PERCENT') ? (displayValue === '' ? '' : displayValue) : (localValue === '' ? '' : localValue)}
onChange={(e) => { onChange={(e) => {
const newValue = config.type === 'number' && label.includes('PERCENT') // 5
? parseFloat(e.target.value) / 100 // 使
: e.target.value let newValue
if (config.type === 'number' && label.includes('PERCENT')) {
//
const numValue = parseFloat(e.target.value)
newValue = isNaN(numValue) ? '' : numValue
} else if (config.type === 'number') {
//
const numValue = parseFloat(e.target.value)
newValue = isNaN(numValue) ? '' : numValue
} else {
newValue = e.target.value
}
handleChange(newValue) handleChange(newValue)
}} }}
onBlur={handleBlur} onBlur={handleBlur}
onKeyPress={handleKeyPress} onKeyPress={handleKeyPress}
disabled={disabled} disabled={disabled}
step={config.type === 'number' ? '0.01' : undefined} step={config.type === 'number' && label.includes('PERCENT') ? '1' : (config.type === 'number' ? '0.01' : undefined)}
className={isEditing ? 'editing' : ''} className={isEditing ? 'editing' : ''}
/> />
{label.includes('PERCENT') && <span className="percent-suffix">%</span>}
{isEditing && ( {isEditing && (
<button <button
className="save-btn" className="save-btn"