""" 实体服务 获取当前用户关联的实体列表,用于风险检测 """ 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 ]