"""名称拼音首字母缩写:库内存小写,检索时大小写不敏感。""" from __future__ import annotations import re from typing import Optional from pypinyin import Style, lazy_pinyin _MAX_LEN = 100 _ALNUM = re.compile(r"[a-zA-Z0-9]") def normalize_name_pinyin_abbr(value: Optional[str]) -> str: raw = (value or "").strip().lower() if not raw: return "" return raw[:_MAX_LEN] def build_name_pinyin_abbr(name: Optional[str]) -> str: text = (name or "").strip() if not text: return "" parts: list[str] = [] for ch in text: if "\u4e00" <= ch <= "\u9fff": pys = lazy_pinyin(ch, style=Style.FIRST_LETTER) if pys and pys[0]: parts.append(str(pys[0]).lower()[0]) elif _ALNUM.match(ch): parts.append(ch.lower()) # else: drop punctuation / spaces / % / brackets return "".join(parts)[:_MAX_LEN] def resolve_name_pinyin_abbr( *, name: Optional[str], submitted: Optional[str] = None, existing: Optional[str] = None, submitted_provided: bool = False, ) -> Optional[str]: """保存时解析拼音字段。 - submitted_provided=True:用提交值(空则按 name 生成) - 否则:已有非空 existing 则保留;existing 空则按 name 生成 """ if submitted_provided: normalized = normalize_name_pinyin_abbr(submitted) if normalized: return normalized generated = build_name_pinyin_abbr(name) return generated or None existing_norm = normalize_name_pinyin_abbr(existing) if existing_norm: return existing_norm generated = build_name_pinyin_abbr(name) return generated or None