""" 配置管理API """ from fastapi import APIRouter, HTTPException from api.models.config import ConfigItem, ConfigUpdate import sys from pathlib import Path # 添加项目根目录到路径 project_root = Path(__file__).parent.parent.parent.parent sys.path.insert(0, str(project_root)) sys.path.insert(0, str(project_root / 'backend')) from database.models import TradingConfig router = APIRouter() @router.get("") @router.get("/") async def get_all_configs(): """获取所有配置""" try: configs = TradingConfig.get_all() result = {} for config in configs: result[config['config_key']] = { 'value': TradingConfig._convert_value( config['config_value'], config['config_type'] ), 'type': config['config_type'], 'category': config['category'], 'description': config['description'] } return result except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/{key}") async def get_config(key: str): """获取单个配置""" try: config = TradingConfig.get(key) if not config: raise HTTPException(status_code=404, detail="Config not found") return { 'key': config['config_key'], 'value': TradingConfig._convert_value( config['config_value'], config['config_type'] ), 'type': config['config_type'], 'category': config['category'], 'description': config['description'] } except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.put("/{key}") async def update_config(key: str, item: ConfigUpdate): """更新配置""" try: # 获取现有配置以确定类型和分类 existing = TradingConfig.get(key) if not existing: raise HTTPException(status_code=404, detail="Config not found") config_type = item.type or existing['config_type'] category = item.category or existing['category'] description = item.description or existing['description'] # 验证配置值 if config_type == 'number': try: float(item.value) except (ValueError, TypeError): raise HTTPException(status_code=400, detail=f"Invalid number value for {key}") elif config_type == 'boolean': if not isinstance(item.value, bool): # 尝试转换 if isinstance(item.value, str): item.value = item.value.lower() in ('true', '1', 'yes', 'on') else: item.value = bool(item.value) # 特殊验证:百分比配置应该在0-1之间 if 'PERCENT' in key and config_type == 'number': if not (0 <= float(item.value) <= 1): raise HTTPException( status_code=400, detail=f"{key} must be between 0 and 1 (0% to 100%)" ) # 更新配置 TradingConfig.set(key, item.value, config_type, category, description) return { "message": "配置已更新", "key": key, "value": item.value, "note": "交易系统将在下次扫描时自动使用新配置" } except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/batch") async def update_configs_batch(configs: list[ConfigItem]): """批量更新配置""" try: updated_count = 0 errors = [] for item in configs: try: # 验证配置值 if item.type == 'number': try: float(item.value) except (ValueError, TypeError): errors.append(f"{item.key}: Invalid number value") continue # 特殊验证:百分比配置 if 'PERCENT' in item.key and item.type == 'number': if not (0 <= float(item.value) <= 1): errors.append(f"{item.key}: Must be between 0 and 1") continue TradingConfig.set( item.key, item.value, item.type, item.category, item.description ) updated_count += 1 except Exception as e: errors.append(f"{item.key}: {str(e)}") if errors: return { "message": f"部分配置更新成功: {updated_count}/{len(configs)}", "updated": updated_count, "errors": errors, "note": "交易系统将在下次扫描时自动使用新配置" } return { "message": f"成功更新 {updated_count} 个配置", "updated": updated_count, "note": "交易系统将在下次扫描时自动使用新配置" } except Exception as e: raise HTTPException(status_code=500, detail=str(e))