""" MCN机构管理API路由 """ from typing import Any, List, Optional from fastapi import APIRouter, Depends, HTTPException, Query, status from sqlalchemy import select, func, and_, or_ from sqlalchemy.ext.asyncio import AsyncSession from loguru import logger from app.database import get_async_session from app.models.streamer import McnAgency from app.schemas.streamer import ( McnAgencyCreate, McnAgencyUpdate, McnAgencyResponse, ) router = APIRouter() @router.get("", response_model=dict) async def list_mcn_agencies( page: int = Query(1, ge=1, description="页码"), size: int = Query(10, ge=1, le=100, description="每页数量"), mcn_name: str = Query(None, description="MCN机构名称"), unified_social_credit_code: str = Query(None, description="统一社会信用代码"), status: str = Query(None, description="状态"), mcn_type: str = Query(None, description="MCN类型"), db: AsyncSession = Depends(get_async_session), ): """ 获取MCN机构列表(分页查询) """ logger.info(f"获取MCN机构列表: page={page}, size={size}") # 构建查询 query = select(McnAgency) # 添加过滤条件 conditions = [] if mcn_name: conditions.append(McnAgency.mcn_name.ilike(f"%{mcn_name}%")) if unified_social_credit_code: conditions.append(McnAgency.unified_social_credit_code == unified_social_credit_code) if status: conditions.append(McnAgency.status == status) if mcn_type: conditions.append(McnAgency.mcn_type == mcn_type) if conditions: query = query.where(and_(*conditions)) # 获取总数 count_query = select(func.count()).select_from(McnAgency) if conditions: count_query = count_query.where(and_(*conditions)) total_result = await db.execute(count_query) total = total_result.scalar() # 分页 query = query.offset((page - 1) * size).limit(size) # 执行查询 result = await db.execute(query) records = result.scalars().all() # 转换为响应格式 response_records = [] for mcn in records: response_records.append({ "id": mcn.id, "mcn_id": mcn.mcn_id, "mcn_name": mcn.mcn_name, "unified_social_credit_code": mcn.unified_social_credit_code, "tax_registration_no": mcn.tax_registration_no, "tax_authority_code": mcn.tax_authority_code, "tax_authority_name": mcn.tax_authority_name, "legal_person_name": mcn.legal_person_name, "legal_person_id_card": mcn.legal_person_id_card, "registered_capital": mcn.registered_capital, "establishment_date": mcn.establishment_date, "registered_address": mcn.registered_address, "actual_address": mcn.actual_address, "business_scope": mcn.business_scope, "mcn_type": mcn.mcn_type, "streamer_count": mcn.streamer_count, "annual_revenue": mcn.annual_revenue, "annual_tax_paid": mcn.annual_tax_paid, "tax_burden_rate": mcn.tax_burden_rate, "top_10_upstream_revenue": mcn.top_10_upstream_revenue, "top_10_upstream_invoice_amount": mcn.top_10_upstream_invoice_amount, "contact_person": mcn.contact_person, "contact_phone": mcn.contact_phone, "contact_email": mcn.contact_email, "bank_account_no": mcn.bank_account_no, "bank_name": mcn.bank_name, "status": mcn.status, "risk_level": mcn.risk_level, "created_at": mcn.created_at.isoformat() if mcn.created_at else None, "updated_at": mcn.updated_at.isoformat() if mcn.updated_at else None, }) return { "records": response_records, "total": total, "page": page, "size": size, } @router.get("/{mcn_id}", response_model=McnAgencyResponse) async def get_mcn_agency( mcn_id: str, db: AsyncSession = Depends(get_async_session), ): """ 获取MCN机构详情 """ logger.info(f"获取MCN机构详情: {mcn_id}") # 查询MCN机构 result = await db.execute( select(McnAgency).where(McnAgency.mcn_id == mcn_id) ) mcn = result.scalar_one_or_none() if not mcn: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"MCN机构不存在: {mcn_id}" ) # 转换为响应格式 return { "id": mcn.id, "mcn_id": mcn.mcn_id, "mcn_name": mcn.mcn_name, "unified_social_credit_code": mcn.unified_social_credit_code, "tax_registration_no": mcn.tax_registration_no, "tax_authority_code": mcn.tax_authority_code, "tax_authority_name": mcn.tax_authority_name, "legal_person_name": mcn.legal_person_name, "legal_person_id_card": mcn.legal_person_id_card, "registered_capital": mcn.registered_capital, "establishment_date": mcn.establishment_date, "registered_address": mcn.registered_address, "actual_address": mcn.actual_address, "business_scope": mcn.business_scope, "mcn_type": mcn.mcn_type, "streamer_count": mcn.streamer_count, "annual_revenue": mcn.annual_revenue, "annual_tax_paid": mcn.annual_tax_paid, "tax_burden_rate": mcn.tax_burden_rate, "top_10_upstream_revenue": mcn.top_10_upstream_revenue, "top_10_upstream_invoice_amount": mcn.top_10_upstream_invoice_amount, "contact_person": mcn.contact_person, "contact_phone": mcn.contact_phone, "contact_email": mcn.contact_email, "bank_account_no": mcn.bank_account_no, "bank_name": mcn.bank_name, "status": mcn.status, "risk_level": mcn.risk_level, "created_at": mcn.created_at, "updated_at": mcn.updated_at, } @router.post("", response_model=McnAgencyResponse, status_code=status.HTTP_201_CREATED) async def create_mcn_agency( mcn: McnAgencyCreate, db: AsyncSession = Depends(get_async_session), ): """ 创建MCN机构 """ logger.info(f"创建MCN机构: {mcn.mcn_name}") # 生成MCN ID query = select(func.count()).select_from(McnAgency) result = await db.execute(query) count = result.scalar() mcn_id = f"MCN{2024}{(count + 1):06d}" # 创建新MCN new_mcn = McnAgency( mcn_id=mcn_id, mcn_name=mcn.mcn_name, unified_social_credit_code=mcn.unified_social_credit_code, legal_person_name=mcn.legal_person_name, legal_person_id_card=mcn.legal_person_id_card, registered_address=mcn.registered_address, bank_account_no=mcn.bank_account_no, bank_name=mcn.bank_name, mcn_type=mcn.mcn_type, contact_person=mcn.contact_person, contact_phone=mcn.contact_phone, contact_email=mcn.contact_email, status=mcn.status, ) db.add(new_mcn) await db.commit() await db.refresh(new_mcn) # 转换为响应格式 response = { "id": new_mcn.id, "mcn_id": new_mcn.mcn_id, "mcn_name": new_mcn.mcn_name, "unified_social_credit_code": new_mcn.unified_social_credit_code, "tax_registration_no": new_mcn.tax_registration_no, "tax_authority_code": new_mcn.tax_authority_code, "tax_authority_name": new_mcn.tax_authority_name, "legal_person_name": new_mcn.legal_person_name, "legal_person_id_card": new_mcn.legal_person_id_card, "registered_capital": new_mcn.registered_capital, "establishment_date": new_mcn.establishment_date, "registered_address": new_mcn.registered_address, "actual_address": new_mcn.actual_address, "business_scope": new_mcn.business_scope, "mcn_type": new_mcn.mcn_type, "streamer_count": new_mcn.streamer_count, "annual_revenue": new_mcn.annual_revenue, "annual_tax_paid": new_mcn.annual_tax_paid, "tax_burden_rate": new_mcn.tax_burden_rate, "top_10_upstream_revenue": new_mcn.top_10_upstream_revenue, "top_10_upstream_invoice_amount": new_mcn.top_10_upstream_invoice_amount, "contact_person": new_mcn.contact_person, "contact_phone": new_mcn.contact_phone, "contact_email": new_mcn.contact_email, "bank_account_no": new_mcn.bank_account_no, "bank_name": new_mcn.bank_name, "status": new_mcn.status, "risk_level": new_mcn.risk_level, "created_at": new_mcn.created_at, "updated_at": new_mcn.updated_at, } return response @router.put("/{mcn_id}", response_model=McnAgencyResponse) async def update_mcn_agency( mcn_id: str, mcn_update: McnAgencyUpdate, db: AsyncSession = Depends(get_async_session), ): """ 更新MCN机构信息 """ logger.info(f"更新MCN机构: {mcn_id}") # 查询MCN机构 result = await db.execute( select(McnAgency).where(McnAgency.mcn_id == mcn_id) ) mcn = result.scalar_one_or_none() if not mcn: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"MCN机构不存在: {mcn_id}" ) # 更新字段 update_data = mcn_update.model_dump(exclude_unset=True) for field, value in update_data.items(): setattr(mcn, field, value) await db.commit() await db.refresh(mcn) # 转换为响应格式 return { "id": mcn.id, "mcn_id": mcn.mcn_id, "mcn_name": mcn.mcn_name, "unified_social_credit_code": mcn.unified_social_credit_code, "tax_registration_no": mcn.tax_registration_no, "tax_authority_code": mcn.tax_authority_code, "tax_authority_name": mcn.tax_authority_name, "legal_person_name": mcn.legal_person_name, "legal_person_id_card": mcn.legal_person_id_card, "registered_capital": mcn.registered_capital, "establishment_date": mcn.establishment_date, "registered_address": mcn.registered_address, "actual_address": mcn.actual_address, "business_scope": mcn.business_scope, "mcn_type": mcn.mcn_type, "streamer_count": mcn.streamer_count, "annual_revenue": mcn.annual_revenue, "annual_tax_paid": mcn.annual_tax_paid, "tax_burden_rate": mcn.tax_burden_rate, "top_10_upstream_revenue": mcn.top_10_upstream_revenue, "top_10_upstream_invoice_amount": mcn.top_10_upstream_invoice_amount, "contact_person": mcn.contact_person, "contact_phone": mcn.contact_phone, "contact_email": mcn.contact_email, "bank_account_no": mcn.bank_account_no, "bank_name": mcn.bank_name, "status": mcn.status, "risk_level": mcn.risk_level, "created_at": mcn.created_at, "updated_at": mcn.updated_at, } @router.delete("/{mcn_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_mcn_agency( mcn_id: str, db: AsyncSession = Depends(get_async_session), ): """ 删除MCN机构 """ logger.info(f"删除MCN机构: {mcn_id}") # 查询MCN机构 result = await db.execute( select(McnAgency).where(McnAgency.mcn_id == mcn_id) ) mcn = result.scalar_one_or_none() if not mcn: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"MCN机构不存在: {mcn_id}" ) # 检查是否有关联的主播 if mcn.streamers: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"无法删除MCN机构:该机构下还有 {len(mcn.streamers)} 个主播" ) # 删除MCN机构 await db.delete(mcn) await db.commit() return None