# -*- coding: utf-8 -*- """生成《附件五 技术响应文件》第 1 章 项目需求理解及综合分析(9 分)。 格式自拟部分,独立成文交付评审确认;确认后再并入完整技术方案。 """ import os import re import shutil import sys sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from _bid_ch1_a import BLOCKS_A # noqa: E402 from _bid_ch1_b import BLOCKS_B # noqa: E402 from _bid_docx_kit import Counter, h1, new_doc, para, render # noqa: E402 HERE = os.path.dirname(os.path.abspath(__file__)) OUT = os.path.join(HERE, "附件五-技术方案-第1章 项目需求理解及综合分析.docx") SYNC_DIR = r"C:\Users\skygu\OneDrive\Projects\AIDOP\项目\项目招投标" CHAPTER_TITLE = "第 1 章 项目需求理解及综合分析" LEAD = ("本章依据询比文件第五章采购需求与评审办法中技术部分“项目需求理解及综合分析”" "的评分要素编写,逐一阐述我方对项目现状、应用环境、体系结构需求、功能需求、" "性能要求、实施要求的理解,对制造业核心业务场景、智能诊断场景、闭环管理逻辑与" "数据分析需求的理解,并在此基础上输出本项目的总体设计蓝图。") def stats(doc): chars = sum(len(p.text) for p in doc.paragraphs) for tb in doc.tables: for row in tb.rows: for c in row.cells: chars += len(c.text) return chars def check_placeholders(blocks): """自检:正文不得残留占位符或内部备注。""" bad = [] for kind, payload in blocks: text = "" if isinstance(payload, str): text = payload elif isinstance(payload, (list, tuple)): text = " ".join(str(x) for x in _flatten(payload)) for m in re.finditer(r"【[^】]*】|待填|TODO|xxx|XXX", text): bad.append((kind, m.group(0), text[:40])) return bad def _flatten(x): if isinstance(x, (list, tuple)): for i in x: yield from _flatten(i) else: yield x def main(): blocks = BLOCKS_A + BLOCKS_B bad = check_placeholders(blocks) if bad: for kind, tok, ctx in bad: print(f" !残留占位 {tok!r} [{kind}] {ctx}") raise SystemExit("正文存在未填写内容,已中止生成") doc = new_doc() cnt = Counter(chapter=1) h1(doc, CHAPTER_TITLE) para(doc, LEAD) render(doc, cnt, blocks) doc.save(OUT) print(f"[完成] {OUT}") print(f" 正文约 {stats(doc):,} 字 图 {cnt.fig} 张 表 {cnt.tbl} 张") if os.path.isdir(SYNC_DIR): dst = os.path.join(SYNC_DIR, os.path.basename(OUT)) shutil.copy2(OUT, dst) print(f"[已同步] {dst}") if __name__ == "__main__": main()