84 lines
2.6 KiB
Python
84 lines
2.6 KiB
Python
"""
|
|
系统生成报价单的对外文件名。
|
|
|
|
协同群发出、私聊直接生成、调价后再发,都用「工单号 + 后台模板名 + 后缀」。
|
|
表格是 .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()
|