243 lines
8.7 KiB
Python
243 lines
8.7 KiB
Python
"""
|
||
实体服务
|
||
获取当前用户关联的实体列表,用于风险检测
|
||
"""
|
||
from typing import List, Dict, Any, Optional
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
from sqlalchemy import select
|
||
from loguru import logger
|
||
|
||
from app.models.user import User
|
||
from app.models.streamer import StreamerInfo, McnAgency
|
||
|
||
|
||
class EntityService:
|
||
"""实体服务"""
|
||
|
||
def __init__(self, db_session: AsyncSession):
|
||
self.db_session = db_session
|
||
|
||
async def get_user_entities(
|
||
self,
|
||
entity_id: Optional[str] = None,
|
||
entity_type: Optional[str] = None
|
||
) -> List[Dict[str, Any]]:
|
||
"""
|
||
获取当前用户关联的实体列表
|
||
|
||
Args:
|
||
entity_id: 指定要检测的实体ID(可选,如果指定则只返回该实体)
|
||
entity_type: 实体类型(mcn-机构,streamer-主播)
|
||
|
||
Returns:
|
||
实体列表,每个实体包含:entity_id, entity_type, name等
|
||
"""
|
||
# 如果指定了entity_id和entity_type,只返回该实体
|
||
if entity_id and entity_type:
|
||
entity = await self._get_entity_by_id(entity_id, entity_type)
|
||
if entity:
|
||
return [entity]
|
||
return []
|
||
|
||
# 获取当前用户的默认实体
|
||
if entity_id:
|
||
entity = await self._get_entity_by_id(entity_id, entity_type)
|
||
if entity:
|
||
return [entity]
|
||
return []
|
||
|
||
return []
|
||
|
||
async def get_user_entities_by_user(
|
||
self,
|
||
user: User
|
||
) -> List[Dict[str, Any]]:
|
||
"""
|
||
根据用户对象获取关联的实体列表
|
||
|
||
Args:
|
||
user: 当前用户对象
|
||
|
||
Returns:
|
||
实体列表
|
||
"""
|
||
# 如果用户没有关联实体,返回空列表
|
||
if not user.entity_id or not user.entity_type:
|
||
logger.warning(f"用户 {user.username} 未关联任何实体")
|
||
return []
|
||
|
||
# 根据实体类型获取实体列表
|
||
if user.entity_type == "mcn":
|
||
# MCN机构用户,返回该机构及其所有主播
|
||
return await self._get_mcn_entities(user.entity_id)
|
||
elif user.entity_type == "streamer":
|
||
# 主播用户,返回该主播
|
||
entity = await self._get_entity_by_id(user.entity_id, "streamer")
|
||
if entity:
|
||
return [entity]
|
||
return []
|
||
else:
|
||
logger.warning(f"未知的实体类型: {user.entity_type}")
|
||
return []
|
||
|
||
async def _get_mcn_entities(self, mcn_id: str) -> List[Dict[str, Any]]:
|
||
"""
|
||
获取MCN机构及其所有主播
|
||
|
||
Args:
|
||
mcn_id: MCN机构ID(mcn_agency表的mcn_id字段)
|
||
|
||
Returns:
|
||
实体列表,包含MCN机构和所有主播
|
||
"""
|
||
entities = []
|
||
|
||
# 1. 获取MCN机构信息
|
||
mcn_agency = await self._get_mcn_agency_by_id(mcn_id)
|
||
if mcn_agency:
|
||
entities.append({
|
||
"entity_id": mcn_agency["mcn_id"],
|
||
"entity_type": "mcn",
|
||
"name": mcn_agency["mcn_name"],
|
||
"entity_name": mcn_agency["mcn_name"],
|
||
"unified_social_credit_code": mcn_agency.get("unified_social_credit_code"),
|
||
"tax_registration_no": mcn_agency.get("tax_registration_no"),
|
||
})
|
||
logger.info(f"找到MCN机构: {mcn_agency['mcn_name']}")
|
||
|
||
# 2. 获取该MCN下的所有主播
|
||
streamers = await self._get_streamers_by_mcn_id(mcn_id)
|
||
for streamer in streamers:
|
||
entities.append({
|
||
"entity_id": streamer["streamer_id"],
|
||
"entity_type": "streamer",
|
||
"name": streamer["streamer_name"],
|
||
"entity_name": streamer["streamer_name"],
|
||
"entity_type_detail": streamer.get("entity_type"),
|
||
"id_card_no": streamer.get("id_card_no"),
|
||
"unified_social_credit_code": streamer.get("unified_social_credit_code"),
|
||
"tax_registration_no": streamer.get("tax_registration_no"),
|
||
"mcn_agency_id": mcn_id,
|
||
"mcn_name": mcn_agency["mcn_name"] if mcn_agency else None,
|
||
})
|
||
|
||
logger.info(f"MCN机构 {mcn_id} 共有 {len(streamers)} 个主播")
|
||
|
||
return entities
|
||
|
||
async def _get_entity_by_id(
|
||
self,
|
||
entity_id: str,
|
||
entity_type: str
|
||
) -> Optional[Dict[str, Any]]:
|
||
"""
|
||
根据ID获取单个实体
|
||
|
||
Args:
|
||
entity_id: 实体ID
|
||
entity_type: 实体类型
|
||
|
||
Returns:
|
||
实体信息或None
|
||
"""
|
||
if entity_type == "mcn":
|
||
return await self._get_mcn_agency_by_id(entity_id)
|
||
elif entity_type == "streamer":
|
||
return await self._get_streamer_by_id(entity_id)
|
||
else:
|
||
logger.warning(f"未知的实体类型: {entity_type}")
|
||
return None
|
||
|
||
async def _get_mcn_agency_by_id(self, mcn_id: str) -> Optional[Dict[str, Any]]:
|
||
"""获取MCN机构信息"""
|
||
stmt = select(McnAgency).where(McnAgency.mcn_id == mcn_id)
|
||
result = await self.db_session.execute(stmt)
|
||
mcn = result.scalar_one_or_none()
|
||
|
||
if not mcn:
|
||
logger.warning(f"MCN机构不存在: {mcn_id}")
|
||
return None
|
||
|
||
return {
|
||
"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,
|
||
"legal_person_name": mcn.legal_person_name,
|
||
"legal_person_id_card": mcn.legal_person_id_card,
|
||
"registered_address": mcn.registered_address,
|
||
"actual_address": mcn.actual_address,
|
||
"bank_account_no": mcn.bank_account_no,
|
||
"bank_name": mcn.bank_name,
|
||
"contact_person": mcn.contact_person,
|
||
"contact_phone": mcn.contact_phone,
|
||
"contact_email": mcn.contact_email,
|
||
"status": mcn.status,
|
||
}
|
||
|
||
async def _get_streamer_by_id(self, streamer_id: str) -> Optional[Dict[str, Any]]:
|
||
"""获取主播信息"""
|
||
stmt = select(StreamerInfo).where(StreamerInfo.streamer_id == streamer_id)
|
||
result = await self.db_session.execute(stmt)
|
||
streamer = result.scalar_one_or_none()
|
||
|
||
if not streamer:
|
||
logger.warning(f"主播不存在: {streamer_id}")
|
||
return None
|
||
|
||
return {
|
||
"streamer_id": streamer.streamer_id,
|
||
"streamer_name": streamer.streamer_name,
|
||
"entity_type": streamer.entity_type,
|
||
"id_card_no": streamer.id_card_no,
|
||
"unified_social_credit_code": streamer.unified_social_credit_code,
|
||
"tax_registration_no": streamer.tax_registration_no,
|
||
"legal_person_name": streamer.legal_person_name,
|
||
"legal_person_id_card": streamer.legal_person_id_card,
|
||
"registered_address": streamer.registered_address,
|
||
"actual_address": streamer.actual_address,
|
||
"bank_account_no": streamer.bank_account_no,
|
||
"bank_name": streamer.bank_name,
|
||
"phone_number": streamer.phone_number,
|
||
"mcn_agency_id": streamer.mcn_agency_id,
|
||
"status": streamer.status,
|
||
}
|
||
|
||
async def _get_streamers_by_mcn_id(self, mcn_id: str) -> List[Dict[str, Any]]:
|
||
"""获取MCN机构下的所有主播"""
|
||
# 先通过mcn_id找到mcn_agency的id(主键)
|
||
stmt_mcn = select(McnAgency).where(McnAgency.mcn_id == mcn_id)
|
||
result_mcn = await self.db_session.execute(stmt_mcn)
|
||
mcn = result_mcn.scalar_one_or_none()
|
||
|
||
if not mcn:
|
||
return []
|
||
|
||
# 通过mcn.id查找所有主播
|
||
stmt = select(StreamerInfo).where(
|
||
StreamerInfo.mcn_agency_id == mcn.id,
|
||
StreamerInfo.status == "active"
|
||
)
|
||
result = await self.db_session.execute(stmt)
|
||
streamers = result.scalars().all()
|
||
|
||
return [
|
||
{
|
||
"streamer_id": s.streamer_id,
|
||
"streamer_name": s.streamer_name,
|
||
"entity_type": s.entity_type,
|
||
"id_card_no": s.id_card_no,
|
||
"unified_social_credit_code": s.unified_social_credit_code,
|
||
"tax_registration_no": s.tax_registration_no,
|
||
"legal_person_name": s.legal_person_name,
|
||
"legal_person_id_card": s.legal_person_id_card,
|
||
"registered_address": s.registered_address,
|
||
"actual_address": s.actual_address,
|
||
"bank_account_no": s.bank_account_no,
|
||
"bank_name": s.bank_name,
|
||
"phone_number": s.phone_number,
|
||
"status": s.status,
|
||
}
|
||
for s in streamers
|
||
]
|