diff --git a/app/services/suppliers.py b/app/services/suppliers.py index 229f9e9..99404c5 100644 --- a/app/services/suppliers.py +++ b/app/services/suppliers.py @@ -142,8 +142,6 @@ class SupplierProfileService: ) .group_by(AnomalyCase.supplier, AnomalyCase.defect_level) ) - if keyword and keyword.strip(): - statement = statement.where(AnomalyCase.supplier.ilike(f"%{keyword.strip()}%")) grouped: dict[str, dict[str, int]] = defaultdict( lambda: {"total": 0, "a": 0, "b": 0} ) @@ -151,6 +149,8 @@ class SupplierProfileService: name = (supplier or "").strip() if not name: continue + if keyword and not self.matches(name, keyword): + continue value = grouped[name] amount = int(count or 0) value["total"] += amount @@ -184,7 +184,11 @@ class SupplierProfileService: @staticmethod def matches(value: str | None, target: str) -> bool: - return bool(value and target.strip().lower() in value.lower()) + if not value: + return False + source = "".join(value.casefold().split()) + query = "".join(target.casefold().split()) + return bool(query and (query in source or source in query)) @classmethod def _group_suppliers(cls, rows: list[dict], keyword: str | None) -> dict[str, list[dict]]: diff --git a/tests/test_suppliers.py b/tests/test_suppliers.py index ff9ca1d..7d175d3 100644 --- a/tests/test_suppliers.py +++ b/tests/test_suppliers.py @@ -14,6 +14,11 @@ def test_supplier_tier_rules_follow_prd() -> None: assert SupplierProfileService.tier_for(121, 0, 0) == "C级" +def test_supplier_name_matching_supports_full_name_and_short_name() -> None: + assert SupplierProfileService.matches("佳亿", "佛山市佳亿包装有限公司") + assert SupplierProfileService.matches("佛山市佳亿包装有限公司", "佳亿") + + def test_supplier_alpha_is_capped_and_rounded() -> None: assert SupplierProfileService.alpha(0) == 1.0 assert SupplierProfileService.alpha(42) == 1.13