""" 配置管理路由 """ from typing import List from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.db.session import get_db from app.schemas.config import SDKConfigCreate, SDKConfigUpdate, SDKConfigResponse, SDKConfigTestResponse from app.schemas.base import ResponseModel, PaginatedResponse, PaginatedData from app.services.config_service import ConfigService from app.services.amazing_data_adapter import AmazingDataAdapter from app.services.sdk_manager import sdk_manager from app.core.security import get_current_user from app.models.user import User from app.models.config import SystemConfig router = APIRouter() @router.get("/sdk", response_model=ResponseModel[List[SDKConfigResponse]]) async def get_sdk_configs( db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """获取SDK配置列表""" configs = ConfigService.get_sdk_configs(db) return ResponseModel(data=[SDKConfigResponse.model_validate(c) for c in configs]) @router.get("/sdk/{config_id}", response_model=ResponseModel[SDKConfigResponse]) async def get_sdk_config( config_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """获取指定SDK配置""" config = ConfigService.get_sdk_config(db, config_id) if not config: raise HTTPException(status_code=404, detail="配置不存在") return ResponseModel(data=SDKConfigResponse.model_validate(config)) @router.post("/sdk", response_model=ResponseModel[SDKConfigResponse]) async def create_sdk_config( config_data: SDKConfigCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """创建SDK配置""" config_dict = config_data.model_dump() config = ConfigService.create_sdk_config(db, config_dict) return ResponseModel(data=SDKConfigResponse.model_validate(config)) @router.put("/sdk/{config_id}", response_model=ResponseModel[SDKConfigResponse]) async def update_sdk_config( config_id: int, config_data: SDKConfigUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """更新SDK配置""" config_dict = config_data.model_dump(exclude_unset=True) config = ConfigService.update_sdk_config(db, config_id, config_dict) return ResponseModel(data=SDKConfigResponse.model_validate(config)) @router.delete("/sdk/{config_id}", response_model=ResponseModel) async def delete_sdk_config( config_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """删除SDK配置""" ConfigService.delete_sdk_config(db, config_id) return ResponseModel(message="删除成功") @router.post("/sdk/{config_id}/test", response_model=ResponseModel[SDKConfigTestResponse]) async def test_sdk_config( config_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """测试SDK连接(连接成功后会保持登录状态)""" import asyncio config = ConfigService.get_sdk_config(db, config_id) if not config: raise HTTPException(status_code=404, detail="配置不存在") def _test_connection(): adapter = sdk_manager.get_connection(config_id) if adapter: return True return False success = await asyncio.to_thread(_test_connection) if success: return ResponseModel(data=SDKConfigTestResponse(success=True, message="连接成功(已保持登录状态)")) else: return ResponseModel( code=1001, message="连接失败", data=SDKConfigTestResponse(success=False, message="SDK连接失败,请检查配置") ) @router.post("/sdk/{config_id}/release", response_model=ResponseModel) async def release_sdk_connection( config_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """释放SDK连接(登出释放资源)""" import asyncio config = ConfigService.get_sdk_config(db, config_id) if not config: raise HTTPException(status_code=404, detail="配置不存在") def _release(): sdk_manager.release_connection(config_id) await asyncio.to_thread(_release) return ResponseModel(message="SDK连接已释放") @router.get("/sdk/{config_id}/status", response_model=ResponseModel) async def get_sdk_connection_status( config_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """获取SDK连接状态""" config = ConfigService.get_sdk_config(db, config_id) if not config: raise HTTPException(status_code=404, detail="配置不存在") status_info = sdk_manager.get_status(config_id) return ResponseModel(data={ "connected": status_info["connected"], "last_activity": status_info["last_activity"], "config_id": status_info["config_id"] }) @router.post("/sdk/{config_id}/set-default", response_model=ResponseModel) async def set_default_config( config_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """设为默认配置""" ConfigService.set_default_config(db, config_id) return ResponseModel(message="设置成功") @router.get("/system", response_model=ResponseModel[dict]) async def get_system_configs( db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """获取系统配置(数据库、Redis等)""" try: configs = db.query(SystemConfig).all() configs_list = [ { "configName": c.config_name, "configKey": c.config_key, "configValue": c.config_value, "currentDbType": c.current_db_type, "isActive": c.is_active } for c in configs ] return ResponseModel(data={"configs": configs_list}) except Exception as e: raise HTTPException(status_code=500, detail="获取系统配置失败") @router.put("/system", response_model=ResponseModel) async def update_system_configs( configs: dict, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """更新系统配置""" if "configs" in configs: try: for config in configs["configs"]: if not config.get("configKey") or not config.get("configValue"): raise HTTPException(status_code=400, detail="配置键和配置值不能为空") ConfigService.set_system_config( db, config.get("configKey"), config.get("configValue"), config.get("configName"), config.get("currentDbType"), config.get("description"), config.get("isActive", True), auto_commit=False ) db.commit() except HTTPException: db.rollback() raise except Exception as e: db.rollback() raise HTTPException(status_code=500, detail=f"更新系统配置失败: {str(e)}") return ResponseModel(message="更新成功") @router.post("/system/test", response_model=ResponseModel[dict]) async def test_system_connection( configs: dict, current_user: User = Depends(get_current_user) ): """测试系统连接(数据库和Redis)""" import sqlalchemy import redis result = { "database": False, "redis": False } # 测试数据库连接 if "database" in configs: try: engine = sqlalchemy.create_engine( configs["database"], connect_args={"check_same_thread": False} if "sqlite" in configs["database"] else {} ) with engine.connect() as conn: result["database"] = True except Exception as e: pass # 测试Redis连接 if "redis" in configs: try: redis_client = redis.from_url(configs["redis"]) redis_client.ping() result["redis"] = True except Exception as e: pass return ResponseModel(data=result) @router.post("/system/init", response_model=ResponseModel[dict]) async def init_system_database( current_user: User = Depends(get_current_user) ): """初始化数据库结构""" try: from app.db.session import init_db init_db() return ResponseModel(data={"success": True}) except Exception as e: return ResponseModel( code=1001, message=str(e), data={"success": False} ) @router.get("/system/structure", response_model=ResponseModel[dict]) async def check_database_structure( current_user: User = Depends(get_current_user) ): """检测数据库结构是否完整""" try: from sqlalchemy import inspect from app.db.session import engine inspector = inspect(engine) existing_tables = inspector.get_table_names() # 检查必要的表是否存在 required_tables = [ 'users', 'sdk_configs', 'system_configs', 'stock_kline_daily', 'stock_kline_minute', 'future_kline_daily', 'future_kline_minute', 'cache_tasks', 'stock_basic', 'index_basic', 'index_trade' ] missing_tables = [table for table in required_tables if table not in existing_tables] complete = len(missing_tables) == 0 return ResponseModel(data={ "complete": complete, "missing_tables": missing_tables, "existing_tables": existing_tables }) except Exception as e: return ResponseModel( code=1001, message=str(e), data={"complete": False, "missing_tables": [], "existing_tables": []} )