from typing import Optional, Dict, Any from fastapi import APIRouter, Query, HTTPException from tortoise.transactions import in_transaction from app.models.cleaning import ProxyConfig, ProxyProvider from app.schemas.base import Success, SuccessExtra proxy_router = APIRouter() @proxy_router.get("/configs") async def list_proxy_configs( name: Optional[str] = Query(None, description="名称"), platform: Optional[str] = Query(None, description="平台标识"), proxy_type: Optional[str] = Query(None, description="代理类型: http/socks/tunnel"), is_active: Optional[bool] = Query(None, description="是否启用"), page: int = Query(1, ge=1, description="页码"), page_size: int = Query(10, ge=1, le=200, description="每页数量"), ): qs = ProxyConfig.all() if name: qs = qs.filter(name__icontains=name) if platform: qs = qs.filter(platform=platform) if proxy_type: qs = qs.filter(proxy_type=proxy_type) if is_active is not None: qs = qs.filter(is_active=is_active) total = await qs.count() items = await qs.order_by("-id").offset((page - 1) * page_size).limit(page_size) data = [ { "id": item.id, "name": item.name, "proxy_type": item.proxy_type, "platform": item.platform, "proxy_url": item.proxy_url, "is_active": item.is_active, "created_at": item.created_at, "updated_at": item.updated_at, } for item in items ] return SuccessExtra(data=data, total=total, page=page, page_size=page_size) @proxy_router.post("/configs") async def create_proxy_config(payload: Dict[str, Any]): try: async with in_transaction(): item = await ProxyConfig.create( name=payload.get("name"), proxy_type=payload.get("proxy_type"), platform=payload.get("platform", "all"), proxy_url=payload.get("proxy_url"), is_active=bool(payload.get("is_active", True)), ) return Success(data={"id": item.id}) except Exception as exc: raise HTTPException(status_code=400, detail=str(exc)) @proxy_router.put("/configs/{config_id}") async def update_proxy_config(config_id: int, payload: Dict[str, Any]): item = await ProxyConfig.get_or_none(id=config_id) if not item: raise HTTPException(status_code=404, detail="Proxy config not found") for field in ["name", "proxy_type", "platform", "proxy_url", "is_active"]: if field in payload: setattr(item, field, payload[field]) await item.save() return Success(data={"id": item.id}) @proxy_router.delete("/configs/{config_id}") async def delete_proxy_config(config_id: int): item = await ProxyConfig.get_or_none(id=config_id) if not item: raise HTTPException(status_code=404, detail="Proxy config not found") await item.delete() return Success(data={"id": config_id}) @proxy_router.get("/providers") async def list_proxy_providers( name: Optional[str] = Query(None, description="名称"), platform: Optional[str] = Query(None, description="平台标识"), mode: Optional[str] = Query(None, description="解析模式"), page: int = Query(1, ge=1, description="页码"), page_size: int = Query(10, ge=1, le=200, description="每页数量"), ): qs = ProxyProvider.all() if name: qs = qs.filter(name__icontains=name) if platform: qs = qs.filter(platform=platform) if mode: qs = qs.filter(mode=mode) total = await qs.count() items = await qs.order_by("-id").offset((page - 1) * page_size).limit(page_size) data = [ { "id": item.id, "name": item.name, "platform": item.platform, "mode": item.mode, "list_path": item.list_path, "ip_path": item.ip_path, "port_path": item.port_path, "username_path": item.username_path, "password_path": item.password_path, "pattern": item.pattern, "template": item.template, "created_at": item.created_at, "updated_at": item.updated_at, } for item in items ] return SuccessExtra(data=data, total=total, page=page, page_size=page_size) @proxy_router.post("/providers") async def create_proxy_provider(payload: Dict[str, Any]): try: async with in_transaction(): item = await ProxyProvider.create( name=payload.get("name"), platform=payload.get("platform", "all"), mode=payload.get("mode", "json"), list_path=payload.get("list_path"), ip_path=payload.get("ip_path"), port_path=payload.get("port_path"), username_path=payload.get("username_path"), password_path=payload.get("password_path"), pattern=payload.get("pattern"), template=payload.get("template"), ) return Success(data={"id": item.id}) except Exception as exc: raise HTTPException(status_code=400, detail=str(exc)) @proxy_router.put("/providers/{provider_id}") async def update_proxy_provider(provider_id: int, payload: Dict[str, Any]): item = await ProxyProvider.get_or_none(id=provider_id) if not item: raise HTTPException(status_code=404, detail="Proxy provider not found") for field in [ "name", "platform", "mode", "list_path", "ip_path", "port_path", "username_path", "password_path", "pattern", "template", ]: if field in payload: setattr(item, field, payload[field]) await item.save() return Success(data={"id": item.id}) @proxy_router.delete("/providers/{provider_id}") async def delete_proxy_provider(provider_id: int): item = await ProxyProvider.get_or_none(id=provider_id) if not item: raise HTTPException(status_code=404, detail="Proxy provider not found") await item.delete() return Success(data={"id": provider_id})