# -*- coding: utf-8 -*- """抽取已交付系统的真实界面截图,供技术方案第 2 章「系统功能展示」引用。 来源为各模块蓝图设计方案与功能设计说明中的实际系统截图(非示意图)。 """ import io import os import shutil import sys import tempfile from docx import Document from docx.oxml.ns import qn sys.stdout.reconfigure(encoding="utf-8", errors="replace") ROOT = (r"C:\Users\skygu\OneDrive\Projects\AIDOP\项目\项目管理" r"\产互联项目管理\交付文档") ASSETS = os.path.join(os.path.dirname(os.path.abspath(__file__)), "_bid_assets") os.makedirs(ASSETS, exist_ok=True) S0 = r"S0\S0-基础主数据建模-业务蓝图设计方案-V0.2.docx" S1 = r"S1\Tmp\S1-功能设计说明.docx" S2 = r"S2\Tmp\S2-功能设计说明.docx" S5 = r"S5\S5-物料仓储-业务蓝图设计方案.docx" S6 = r"S6\S6-生产执行-业务蓝图设计方案.docx" S7 = r"S7\S7-成品仓储-业务蓝图设计方案.docx" # (源文档, 文档内第几张图, 输出名, 图题) PICKS = [ (S0, 5, "ui_s0_material", "物料主数据管理(FUNC-S0-020)"), (S0, 2, "ui_s0_customer", "客户主数据管理(FUNC-S0-021)"), (S0, 10, "ui_s0_supplier", "供应商主数据管理(FUNC-S0-027)"), (S0, 30, "ui_s0_bom", "标准 BOM 管理(FUNC-S0-001)"), (S0, 15, "ui_s0_routing", "标准工艺路线管理(FUNC-S0-002)"), (S0, 48, "ui_s0_location", "库位管理(FUNC-S0-034)"), # S1、S2 功能设计说明中的配图为早期线框原型(指标卡为「指标A/当前值/目标值」占位、 # 列表仅一行样例数据),与其余模块的实际系统截图风格不一致,不用于响应文件。 (S5, 2, "ui_s5_iqc", "来料检验申请列表"), (S5, 7, "ui_s5_stock", "库存查询"), (S5, 8, "ui_s5_inout", "进出存查询"), (S5, 11, "ui_s5_stocktake", "盘点结果查询"), (S6, 2, "ui_s6_ipqc", "过程检验单列表与详情"), (S6, 3, "ui_s6_equipment", "生产设备台账"), (S6, 4, "ui_s6_tooling", "模具工装台账管理"), (S7, 2, "ui_s7_prodin", "生产入库单列表"), (S7, 3, "ui_s7_shipment", "销售发货通知"), (S7, 4, "ui_s7_fqc_task", "FQC 检验任务列表"), (S7, 5, "ui_s7_fqc_result", "FQC 检验结果列表与详情"), ] def load(cache, rel, tmpdir): if rel not in cache: local = os.path.join(tmpdir, os.path.basename(rel)) shutil.copy2(os.path.join(ROOT, rel), local) cache[rel] = Document(local) return cache[rel] def main(): tmpdir = tempfile.mkdtemp() cache = {} manifest = [] for rel, idx, name, caption in PICKS: doc = load(cache, rel, tmpdir) found, blob, ext = 0, None, ".png" for p in doc.paragraphs: for blip in p._p.findall(".//" + qn("a:blip")): found += 1 if found == idx: part = doc.part.related_parts[blip.get(qn("r:embed"))] blob = part.blob ext = os.path.splitext(str(part.partname))[1] or ".png" break if blob is not None: break if blob is None: print(f" [缺] {rel} 第 {idx} 张") continue with open(os.path.join(ASSETS, name + ext), "wb") as f: f.write(blob) manifest.append((name + ext, len(blob) // 1024, caption, rel)) print(f" [OK] {name + ext:<24} {len(blob) // 1024:>5} KB {caption}") shutil.rmtree(tmpdir, ignore_errors=True) with io.open(os.path.join(ASSETS, "_manifest_ui.txt"), "w", encoding="utf-8") as f: for n, kb, c, r in manifest: f.write(f"{n}\t{kb}KB\t{c}\t来源:{r}\n") print(f"\n共抽取 {len(manifest)} 张界面截图 -> {ASSETS}") if __name__ == "__main__": main()