"""资产 CRUD 路由 统一入口 /api/assets,写操作(POST/PUT/DELETE)受 API Key 保护。 """ from typing import List, Optional from fastapi import APIRouter, Body, Depends, Query from sqlmodel import Session from app.core.security import require_api_key from app.database import get_session from app.models.asset import AssetStatus, AssetType from app.schemas.asset import AssetCreate, AssetRead, AssetUpdate from app.services import asset_service, sync_service router = APIRouter(prefix="/api/assets", tags=["assets"]) @router.get("", response_model=List[AssetRead], summary="资产列表") def list_assets( asset_type: Optional[AssetType] = Query(default=None, description="按类型筛选"), status_filter: Optional[AssetStatus] = Query(default=None, alias="status", description="按状态筛选"), is_archived: Optional[bool] = Query(default=None, description="按归档标记筛选"), q: Optional[str] = Query(default=None, description="搜索名称/服务商"), provider: Optional[str] = Query(default=None, description="按平台筛选(slug 或平台 ID)"), sort: str = Query(default="expiry_date", description="排序字段"), order: str = Query(default="asc", description="排序方向 asc/desc"), session: Session = Depends(get_session), ): return asset_service.list_assets( session, asset_type, status_filter, is_archived, q, provider, sort, order ) @router.get("/export", summary="导出所有资产(数据迁移/备份)", dependencies=[Depends(require_api_key)]) def export_assets(session: Session = Depends(get_session)) -> dict: return asset_service.export_assets(session) @router.post( "/import", summary="导入资产(从导出数据,按 name+类型+服务商去重)", dependencies=[Depends(require_api_key)], ) def import_assets_endpoint( data: dict = Body(...), session: Session = Depends(get_session) ) -> dict: return asset_service.import_assets(session, data.get("assets", [])) @router.get("/{asset_id}", response_model=AssetRead, summary="资产详情") def get_asset(asset_id: int, session: Session = Depends(get_session)): return asset_service.get_asset(session, asset_id) @router.post( "", response_model=AssetRead, status_code=201, summary="创建资产", dependencies=[Depends(require_api_key)], ) def create_asset(data: AssetCreate, session: Session = Depends(get_session)): return asset_service.create_asset(session, data) @router.put( "/{asset_id}", response_model=AssetRead, summary="更新资产", dependencies=[Depends(require_api_key)], ) def update_asset( asset_id: int, data: AssetUpdate, session: Session = Depends(get_session) ): return asset_service.update_asset(session, asset_id, data) @router.delete( "/{asset_id}", status_code=204, summary="删除资产", dependencies=[Depends(require_api_key)], ) def delete_asset(asset_id: int, session: Session = Depends(get_session)): asset_service.delete_asset(session, asset_id) @router.post( "/{asset_id}/refresh-balance", summary="刷新 AI 账号余额(调用适配器查询)", dependencies=[Depends(require_api_key)], ) def refresh_balance(asset_id: int, session: Session = Depends(get_session)) -> dict: return sync_service.refresh_ai_balance(session, asset_id)