"""基金推荐候选过滤与排序。""" from __future__ import annotations from collections import defaultdict from typing import Iterable from common.common_const import MEMORY_INFO_TYPE_OPINION from common.suitability import check_suitability def _opinion_bonuses(memories: Iterable[dict]) -> dict[str, float]: bonuses: dict[str, float] = defaultdict(float) for memory in memories: if memory.get("info_type") != MEMORY_INFO_TYPE_OPINION: continue product_code = memory.get("product_code") if product_code: bonuses[str(product_code)] += float(memory.get("score", 0.0) or 0.0) return bonuses def recommend_candidates( customer_risk: str, candidates: Iterable[dict], *, memories: Iterable[dict] = (), ) -> list[dict]: """硬过滤不适当产品,再按业绩和主观观点排序。""" bonuses = _opinion_bonuses(memories) result = [] for candidate in candidates: suitability = check_suitability(customer_risk, candidate.get("risk_level", "")) if not suitability.ok: continue item = dict(candidate) base_score = float(item.get("performance_score", 0.0) or 0.0) item["recommendation_score"] = base_score + bonuses.get( str(item.get("product_code")), 0.0 ) result.append(item) return sorted( result, key=lambda item: item["recommendation_score"], reverse=True, )