""" 系统生成报价单的对外文件名。 协同群发出、私聊直接生成、调价后再发,都用「工单号 + 后台模板名 + 后缀」。 表格是 .xlsx,转成 PDF 再发出去是 .pdf。 航线、产品自己上传的附件不走这里,原文件名存后台。 """ from __future__ import annotations from typing import Any # 模板名若自带这些后缀,发出去时去掉。中文名本身不动。 _SUFFIXES = (".xlsx", ".xls", ".xlsm", ".pdf") # Windows / 企微文件名不允许的字符。其余(含中文)原样保留。 _ILLEGAL = set('\\/:*?"<>|') def quote_sheet_filename( work_order_no: str, template_name: str, *, suffix: str = ".xlsx", ) -> str: """ 工单号紧挨后台模板名,再加文件后缀。没有模板名则返回空。 模板名里如果已经写了 .xlsx / .pdf,先去掉再按这次要发的格式重加,避免两个后缀。 副作用:无。纯字符串,可在请求线程调用。 """ no = str(work_order_no or "").strip() name = _plain_name(template_name) if not no or not name: return "" return f"{no}{name}{_suffix(suffix)}" def filename_from_render( work_order_no: str, result: dict[str, Any] | None, *, suffix: str = ".xlsx", ) -> str: """ 出单结果里的对外文件名。有模板名就用工单号拼接,并带上这次的后缀。 主账即使仍回 WO_quote.xlsx,只要带了 templateName,销售侧仍是「工单号+模板名.xlsx」。 PDF 出站传入 suffix=".pdf"。 """ src = result or {} ext = _suffix(suffix) shown = quote_sheet_filename( work_order_no, str(src.get("templateName") or ""), suffix=ext ) if shown: return shown raw = _plain_name(str(src.get("fileName") or "")) if raw: return f"{raw}{ext}" no = str(work_order_no or "").strip() return f"{no}_quote{ext}" if no else f"quote{ext}" def _suffix(suffix: str) -> str: """只接受已知表格/PDF 后缀,其余一律按 Excel。""" text = str(suffix or "").strip().lower() if not text.startswith("."): text = f".{text}" if text else "" if text in _SUFFIXES: return text return ".xlsx" def _plain_name(name: str) -> str: """去掉已知后缀和非法字符。空则返回空。""" text = str(name or "").strip() lower = text.lower() for ext in _SUFFIXES: if lower.endswith(ext): text = text[: -len(ext)].rstrip(" .") break cleaned = "".join(ch for ch in text if ch not in _ILLEGAL and ord(ch) >= 32) return cleaned.strip()