diff --git a/backend/api/routes/config.py b/backend/api/routes/config.py index a019dd1..39d25ba 100644 --- a/backend/api/routes/config.py +++ b/backend/api/routes/config.py @@ -800,6 +800,10 @@ async def check_config_feasibility( except Exception: suggestions = [] + max_open_positions = int(_tc("MAX_OPEN_POSITIONS", 3)) + max_daily_entries = int(_tc("MAX_DAILY_ENTRIES", 8)) + max_single_position_margin_usdt = round(available_balance * max_position_percent, 2) + return { "feasible": is_feasible, "account_balance": available_balance, @@ -809,7 +813,10 @@ async def check_config_feasibility( "current_config": { "min_margin_usdt": min_margin_usdt, "min_position_percent": min_position_percent, - "max_position_percent": max_position_percent + "max_position_percent": max_position_percent, + "max_open_positions": max_open_positions, + "max_daily_entries": max_daily_entries, + "max_single_position_margin_usdt": max_single_position_margin_usdt, }, "calculated_values": { "required_position_value": base_result['required_position_value'], diff --git a/frontend/src/components/ConfigPanel.jsx b/frontend/src/components/ConfigPanel.jsx index dc4d966..fff0316 100644 --- a/frontend/src/components/ConfigPanel.jsx +++ b/frontend/src/components/ConfigPanel.jsx @@ -42,6 +42,19 @@ const ConfigPanel = () => { } } + // 普通用户仅可编辑的配置项(与后端 USER_RISK_KNOBS 一致;用于隐藏不可编辑分组与项) + const USER_RISK_KNOBS_SET = new Set([ + 'MIN_MARGIN_USDT', 'MIN_POSITION_PERCENT', 'MAX_POSITION_PERCENT', 'MAX_TOTAL_POSITION_PERCENT', + 'AUTO_TRADE_ENABLED', 'MAX_OPEN_POSITIONS', 'MAX_DAILY_ENTRIES', + 'TOP_N_SYMBOLS', 'MIN_SIGNAL_STRENGTH', 'MIN_VOLUME_24H', 'MIN_VOLATILITY', + 'SCAN_EXTRA_SYMBOLS_FOR_SUPPLEMENT', 'EXCLUDE_MAJOR_COINS', 'MAX_SCAN_SYMBOLS', 'SCAN_INTERVAL', + ]) + const USER_EDITABLE_KEYS = new Set([ + ...USER_RISK_KNOBS_SET, + 'BINANCE_API_KEY', 'BINANCE_API_SECRET', 'USE_TESTNET', + ]) + const isKeyEditableForUser = (key) => USER_EDITABLE_KEYS.has(key) + const [credForm, setCredForm] = useState({ api_key: '', api_secret: '', use_testnet: false }) // 预设方案配置 @@ -521,8 +534,8 @@ const ConfigPanel = () => { } // 重新加载配置 await loadConfigs() - // 如果更新的是与可行性相关的配置,重新检查可行性 - if (['MIN_MARGIN_USDT', 'MIN_POSITION_PERCENT', 'MAX_POSITION_PERCENT', 'LEVERAGE'].includes(key)) { + // 如果更新的是与可行性/展示相关的配置,重新检查可行性(含最大单笔、持仓数、每日开仓等) + if (['MIN_MARGIN_USDT', 'MIN_POSITION_PERCENT', 'MAX_POSITION_PERCENT', 'MAX_OPEN_POSITIONS', 'MAX_DAILY_ENTRIES', 'LEVERAGE'].includes(key)) { await checkFeasibility() } } catch (error) { @@ -811,6 +824,17 @@ const ConfigPanel = () => { 'api': 'API配置' } + // 普通用户只展示含“可编辑项”的分组,避免出现不可修改的策略组 + const visibleCategories = isAdmin + ? configCategories + : Object.fromEntries( + Object.entries(configCategories).filter(([cat]) => + Object.keys(configs).some( + (key) => configs[key]?.category === cat && isKeyEditableForUser(key) + ) + ) + ) + return (
@@ -1047,6 +1071,15 @@ const ConfigPanel = () => { )} | 最小保证金: {feasibilityCheck.current_config?.min_margin_usdt?.toFixed(2) || 'N/A'} USDT

+

+ 最大单笔保证金: {feasibilityCheck.current_config?.max_single_position_margin_usdt != null ? feasibilityCheck.current_config.max_single_position_margin_usdt.toFixed(2) : 'N/A'} USDT + {feasibilityCheck.current_config?.max_open_positions != null && ( + <> | 最多持仓: {feasibilityCheck.current_config.max_open_positions} 个 + )} + {feasibilityCheck.current_config?.max_daily_entries != null && ( + <> | 每日最多开仓: {feasibilityCheck.current_config.max_daily_entries} 次 + )} +

{!feasibilityCheck.feasible && (

@@ -1148,17 +1181,18 @@ const ConfigPanel = () => {

)} - {/* 配置项(禁用account时不显示) */} + {/* 配置项(禁用account时不显示);普通用户只显示可编辑的风险旋钮与 API 配置 */} {currentAccountMeta && currentAccountMeta.status === 'active' ? ( - Object.entries(configCategories).map(([category, label]) => ( + Object.entries(visibleCategories).map(([category, label]) => (

{label}

{Object.entries(configs) .filter(([key, config]) => { if (config.category !== category) return false - // 密钥相关配置统一在“账号密钥(当前账号)”模块管理,这里不重复展示 - if (key === 'BINANCE_API_KEY' || key === 'BINANCE_API_SECRET' || key === 'USE_TESTNET') return false + // 密钥在“账号密钥”模块展示,此处可选展示(api 组保留) + if (key === 'BINANCE_API_KEY' || key === 'BINANCE_API_SECRET' || key === 'USE_TESTNET') return true + if (!isAdmin && !isKeyEditableForUser(key)) return false return true }) .map(([key, config]) => (