"""CRM 列头 facet:从 column_filter_kwargs 中清除当前列自身条件。""" from __future__ import annotations import re from typing import Any, Dict, Mapping, MutableMapping, Optional, Sequence # field(prop/API) → column_filter_kwargs 中应清空的 snake 键 CRM_FACET_FIELD_KWARG_KEYS: Dict[str, Sequence[str]] = { # customer "customerNo": ("customer_no", "customer_no_in"), "customerName": ("customer_name", "customer_name_in"), "shortName": ("short_name", "short_name_in"), # product "productNo": ("product_no", "product_no_in"), "productName": ("product_name", "product_name_in"), "categoryName": ("category_name", "category_name_in"), "brands": ("brands", "brands_in", "brand", "brand_in"), "aliases": ("aliases", "aliases_in", "alias", "alias_in"), "model": ("model", "model_in"), # clue "clueName": ("clue_name", "clue_name_in"), "company": ("company", "company_in"), # opportunity "opportunityNo": ("opportunity_no", "opportunity_no_in"), "opportunityName": ("opportunity_name", "opportunity_name_in"), # quote / contract share customerName "quoteNo": ("quote_no", "quote_no_in"), "contractNo": ("contract_no", "contract_no_in"), "contractName": ("contract_name", "contract_name_in"), "templateNo": ("template_no", "template_no_in"), "templateName": ("template_name", "template_name_in"), # supplier / price letter "supplierCode": ("supplier_code", "supplier_code_in"), "supplierName": ("supplier_name", "supplier_name_in"), } _META_KEYS = frozenset( { "field", "keyword", "limit", "page", "pageSize", "page_size", "pageNum", "page_num", "ids", "columns", "sortField", "sort_field", "sortOrder", "sort_order", } ) def _camel_to_snake(name: str) -> str: s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name) return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower() def clear_facet_field_kwargs( kwargs: Mapping[str, object], field: str, *, extra_keys: Optional[Sequence[str]] = None, ) -> Dict[str, object]: """返回清除当前 facet 列相关键后的 kwargs 副本(值置 None)。""" out: Dict[str, object] = dict(kwargs) keys = list(CRM_FACET_FIELD_KWARG_KEYS.get(str(field or "").strip(), ())) if extra_keys: keys.extend(extra_keys) for key in keys: if key in out: out[key] = None return out def strip_crm_facet_body_params( params: MutableMapping[str, object], field: str ) -> Dict[str, object]: """从原始 camelCase body dump 中去掉本列键与元数据(兼容无 mixin 路径)。""" from app.services.pl.facet_context import strip_simple_facet_self_params return strip_simple_facet_self_params(params, field) def facet_filter_kwargs_from_body(body: Any, field: str) -> Dict[str, object]: """从 Facet Body(含 extra=allow)提取 snake_case 列筛 kwargs,并清除当前列。""" dumped = body.model_dump( by_alias=False, exclude_none=False, exclude={"field", "keyword", "limit"}, ) out: Dict[str, object] = {} for key, value in dumped.items(): if key in _META_KEYS or value is None or value == "": continue out[key] = value extra = getattr(body, "model_extra", None) or {} for key, value in extra.items(): if key in _META_KEYS or value is None or value == "": continue snake = _camel_to_snake(key) if any(c.isupper() for c in key) else key if snake in _META_KEYS: continue out[snake] = value return clear_facet_field_kwargs(out, field)