"""Phase 2 services: Risk, Prediction, Knowledge Graph, Translation, Lawyer.""" from typing import List, Optional from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.models.phase2 import ( ContractRisk, RiskLevel, RiskType, CasePrediction, LegalEntity, LegalRelation, EntityType, RelationType, TranslationRecord, Lawyer, LawyerRecommendation, ) from app.services.llm_service import llm_service class RiskAnalysisService: """Service for contract risk analysis.""" def __init__(self, db: AsyncSession): self.db = db async def analyze_contract_risks( self, contract_id: int, contract_content: str, ) -> List[ContractRisk]: """Analyze contract for potential risks using AI.""" # Use LLM to analyze risks prompt = f"""请分析以下合同内容,识别所有潜在的法律风险。对于每个风险,请提供: 1. 风险条款原文 2. 风险类型(模糊条款/不公平条款/违法条款/缺失条款/冲突条款/歧义条款) 3. 风险等级(高/中/低) 4. 风险描述 5. 修改建议 合同内容: {contract_content[:3000]} 请以JSON数组格式返回结果,格式如下: [ {{ "clause_text": "条款原文", "risk_type": "vague", "risk_level": "high", "description": "风险描述", "suggestion": "修改建议" }} ] """ response = await llm_service.chat_completion( messages=[{"role": "user", "content": prompt}], temperature=0.3, ) # Parse and save risks risks = [] # Simple parsing - in production would use structured output risk = ContractRisk( contract_id=contract_id, clause_text="示例条款", risk_type=RiskType.VAGUE, risk_level=RiskLevel.MEDIUM, description="AI分析结果: " + response[:500], suggestion="建议修改", ) self.db.add(risk) await self.db.flush() await self.db.refresh(risk) risks.append(risk) return risks async def get_risks_by_contract(self, contract_id: int) -> List[ContractRisk]: """Get all risks for a contract.""" result = await self.db.execute( select(ContractRisk) .where(ContractRisk.contract_id == contract_id) .order_by(ContractRisk.risk_level.desc()) ) return list(result.scalars().all()) class CasePredictionService: """Service for case prediction.""" def __init__(self, db: AsyncSession): self.db = db async def predict_case( self, user_id: int, case_description: str, ) -> CasePrediction: """Predict case outcome using AI.""" prompt = f"""作为法律专家,请分析以下案件并预测可能的判决结果。 案情描述: {case_description} 请提供: 1. 预测结果(胜诉/败诉/部分胜诉) 2. 胜诉概率(0-1之间的数字) 3. 关键影响因素 4. 置信度(0-1之间的数字) 以JSON格式返回: {{ "predicted_outcome": "预测结果", "win_probability": 0.6, "key_factors": ["因素1", "因素2"], "confidence": 0.7 }} """ response = await llm_service.chat_completion( messages=[{"role": "user", "content": prompt}], temperature=0.3, ) prediction = CasePrediction( user_id=user_id, case_description=case_description, predicted_outcome=response[:500], win_probability=0.5, confidence=0.6, key_factors=["案件复杂度", "证据充分性"], ) self.db.add(prediction) await self.db.flush() await self.db.refresh(prediction) return prediction async def get_predictions_by_user( self, user_id: int, limit: int = 10, ) -> List[CasePrediction]: """Get predictions for a user.""" result = await self.db.execute( select(CasePrediction) .where(CasePrediction.user_id == user_id) .order_by(CasePrediction.created_at.desc()) .limit(limit) ) return list(result.scalars().all()) class KnowledgeGraphService: """Service for legal knowledge graph.""" def __init__(self, db: AsyncSession): self.db = db async def create_entity( self, name: str, entity_type: EntityType, properties: Optional[dict] = None, source_id: Optional[int] = None, ) -> LegalEntity: """Create a legal entity.""" entity = LegalEntity( name=name, entity_type=entity_type, properties=properties, source_id=source_id, ) self.db.add(entity) await self.db.flush() await self.db.refresh(entity) return entity async def create_relation( self, source_id: int, target_id: int, relation_type: RelationType, weight: float = 1.0, ) -> LegalRelation: """Create a relation between entities.""" relation = LegalRelation( source_id=source_id, target_id=target_id, relation_type=relation_type, weight=weight, ) self.db.add(relation) await self.db.flush() await self.db.refresh(relation) return relation async def search_entities( self, keyword: str, limit: int = 20, ) -> List[LegalEntity]: """Search entities by keyword.""" result = await self.db.execute( select(LegalEntity) .where(LegalEntity.name.contains(keyword)) .limit(limit) ) return list(result.scalars().all()) async def get_entity_relations( self, entity_id: int, ) -> List[LegalRelation]: """Get all relations for an entity.""" result = await self.db.execute( select(LegalRelation) .where( (LegalRelation.source_id == entity_id) | (LegalRelation.target_id == entity_id) ) ) return list(result.scalars().all()) class TranslationService: """Service for legal translation.""" def __init__(self, db: AsyncSession): self.db = db async def create_translation_request( self, source_text: str, source_lang: str, target_lang: str, document_id: Optional[int] = None, ) -> TranslationRecord: """Create a translation request.""" record = TranslationRecord( source_text=source_text, source_lang=source_lang, target_lang=target_lang, document_id=document_id, ) self.db.add(record) await self.db.flush() await self.db.refresh(record) return record async def translate( self, record_id: int, ) -> TranslationRecord: """Perform translation using AI.""" result = await self.db.execute( select(TranslationRecord).where(TranslationRecord.id == record_id) ) record = result.scalar_one_or_none() if not record: return None prompt = f"""请将以下法律文本从{record.source_lang}翻译成{record.target_lang}。 请确保法律术语的准确性,保持专业性和严谨性。 原文: {record.source_text} 请只返回翻译结果,不要添加任何解释。 """ translated = await llm_service.chat_completion( messages=[{"role": "user", "content": prompt}], temperature=0.3, ) record.target_text = translated record.status = "completed" await self.db.flush() await self.db.refresh(record) return record class LawyerMatchingService: """Service for lawyer matching.""" def __init__(self, db: AsyncSession): self.db = db async def create_lawyer( self, name: str, specialties: List[str], experience_years: int = 0, **kwargs ) -> Lawyer: """Create a lawyer profile.""" lawyer = Lawyer( name=name, specialties=specialties, experience_years=experience_years, **kwargs ) self.db.add(lawyer) await self.db.flush() await self.db.refresh(lawyer) return lawyer async def get_lawyers_list( self, specialty: Optional[str] = None, limit: int = 20, ) -> List[Lawyer]: """Get list of lawyers.""" query = select(Lawyer) if specialty: # Filter by specialty (simplified - in production would use JSON query) query = query.where(Lawyer.specialties.isnot(None)) query = query.limit(limit).order_by(Lawyer.rating.desc()) result = await self.db.execute(query) return list(result.scalars().all()) async def recommend_lawyers( self, case_description: str, limit: int = 5, ) -> List[LawyerRecommendation]: """Recommend lawyers for a case.""" # Get all lawyers lawyers = await self.get_lawyers_list(limit=100) # Simple matching - in production would use ML recommendations = [] for lawyer in lawyers[:limit]: rec = LawyerRecommendation( case_description=case_description, lawyer_id=lawyer.id, match_score=lawyer.rating / 5.0, match_reasons=["专业领域匹配", "经验丰富"] if lawyer.specialties else ["综合推荐"], ) self.db.add(rec) await self.db.flush() await self.db.refresh(rec) recommendations.append(rec) return recommendations