deep-risk/backend/app/api/v1/endpoints/mcn.py
2025-12-14 20:08:27 +08:00

343 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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