_gen_bid_tech_ch1.py 2.8 KB

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