# -*- coding: utf-8 -*- """从各模块蓝图设计方案中抽取主线流程图,存到 doc/_bid_assets/ 供技术方案引用。""" import os import shutil import sys import tempfile sys.stdout.reconfigure(encoding="utf-8", errors="replace") from docx import Document from docx.oxml.ns import qn ROOT = r"C:\Users\skygu\OneDrive\Projects\AIDOP\项目\项目管理\产互联项目管理\交付文档" ASSETS = os.path.join(os.path.dirname(os.path.abspath(__file__)), "_bid_assets") os.makedirs(ASSETS, exist_ok=True) # (蓝图相对路径, 图序号(1起), 输出名, 说明) PICKS = [ ("S0/S0-基础主数据建模-业务蓝图设计方案-V0.2.docx", 1, "s0_master_dataflow", "S0 主数据与下游 S1–S9 数据流关系"), ("S1/S1产销协同模块蓝图设计方案.docx", 1, "s1_otd_mainline", "S1 产销协同 订单履约全链路主线流程"), ("S1/S1产销协同模块蓝图设计方案.docx", 3, "s1_order_delivery", "S1 订单交付 8Tab 全景追踪流程"), ("S1/S1产销协同模块蓝图设计方案.docx", 8, "s1_kanban", "S1 产销协同看板 L1–L4 指标下钻"), ("S2/S2制造协同模块蓝图设计方案.docx", 1, "s2_plan_to_exec", "S2 制造协同 排程到执行主线流程"), ("S3/S3供应协同模块蓝图设计方案.docx", 1, "s3_domains", "S3 供应协同 物料计划/采购管理/协同看板三域关系"), ("S3/S3供应协同模块蓝图设计方案.docx", 11, "s3_shortage", "S3 齐套计算与缺料预警流程"), ("S4/S4采购执行模块蓝图设计方案.docx", 1, "s4_domains", "S4 采购执行 交货执行/退货闭环/执行看板三域关系"), ("S5/S5-物料仓储-业务蓝图设计方案.docx", 1, "s5_lifecycle", "S5 物料仓储 贴源同步只读生命周期"), ("S6/S6-生产执行-业务蓝图设计方案.docx", 1, "s6_ipqc", "S6 生产执行 贴源同步与 IPQC 检验流转"), ("S7/S7-成品仓储-业务蓝图设计方案.docx", 1, "s7_lifecycle", "S7 成品仓储 贴源同步只读生命周期"), ] tmpdir = tempfile.mkdtemp() cache = {} manifest = [] for rel, idx, name, desc in PICKS: src = os.path.join(ROOT, rel.replace("/", os.sep)) if src not in cache: local = os.path.join(tmpdir, os.path.basename(src)) shutil.copy2(src, local) cache[src] = Document(local) doc = cache[src] found = 0 blob = ext = None for p in doc.paragraphs: for blip in p._p.findall(".//" + qn("a:blip")): found += 1 if found == idx: rid = blip.get(qn("r:embed")) part = doc.part.related_parts[rid] 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 out = os.path.join(ASSETS, name + ext) with open(out, "wb") as f: f.write(blob) manifest.append((name + ext, len(blob) // 1024, desc, rel)) print(f" [OK] {name + ext:<28} {len(blob) // 1024:>6} KB {desc}") shutil.rmtree(tmpdir, ignore_errors=True) with open(os.path.join(ASSETS, "_manifest.txt"), "w", encoding="utf-8") as f: for n, kb, d, r in manifest: f.write(f"{n}\t{kb}KB\t{d}\t来源:{r}\n") print(f"\n共抽取 {len(manifest)} 张 -> {ASSETS}")