"""生成《Ai-DOP 数据中台支撑层建设项目方案》Word 文档。""" from __future__ import annotations import os from docx import Document from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING from docx.oxml.ns import qn from docx.shared import Cm, Pt, RGBColor BASE = os.path.dirname(os.path.abspath(__file__)) OUT = os.path.join(BASE, "plan", "Ai-DOP数据中台支撑层建设项目方案.docx") doc = Document() sec = doc.sections[0] sec.page_width = Cm(21.0) sec.page_height = Cm(29.7) sec.top_margin = Cm(2.54) sec.bottom_margin = Cm(2.54) sec.left_margin = Cm(2.8) sec.right_margin = Cm(2.8) def set_run_font(run, name_cn="宋体", name_en="Times New Roman", size=12, bold=False, color=None): run.font.name = name_en run._element.rPr.rFonts.set(qn("w:eastAsia"), name_cn) run.font.size = Pt(size) run.bold = bold if color is not None: run.font.color.rgb = color def style_normal(): style = doc.styles["Normal"] style.font.name = "Times New Roman" style.font.size = Pt(12) style._element.rPr.rFonts.set(qn("w:eastAsia"), "宋体") pf = style.paragraph_format pf.line_spacing_rule = WD_LINE_SPACING.ONE_POINT_FIVE pf.space_after = Pt(6) def add_title(text: str): p = doc.add_paragraph() p.alignment = WD_ALIGN_PARAGRAPH.CENTER p.paragraph_format.space_after = Pt(12) run = p.add_run(text) set_run_font(run, "黑体", "SimHei", 18, True) def add_meta(text: str): p = doc.add_paragraph() p.alignment = WD_ALIGN_PARAGRAPH.CENTER p.paragraph_format.space_after = Pt(4) run = p.add_run(text) set_run_font(run, "宋体", "Times New Roman", 10.5) def add_h1(text: str): p = doc.add_paragraph() p.paragraph_format.space_before = Pt(14) p.paragraph_format.space_after = Pt(8) run = p.add_run(text) set_run_font(run, "黑体", "SimHei", 14, True) def add_h2(text: str): p = doc.add_paragraph() p.paragraph_format.space_before = Pt(10) p.paragraph_format.space_after = Pt(6) run = p.add_run(text) set_run_font(run, "黑体", "SimHei", 12, True) def add_body(text: str, indent=True): p = doc.add_paragraph() p.paragraph_format.first_line_indent = Pt(24) if indent else Pt(0) p.paragraph_format.space_after = Pt(6) run = p.add_run(text) set_run_font(run, "宋体", "Times New Roman", 12) def add_bullet(text: str, ordered=False, index=None): p = doc.add_paragraph() p.paragraph_format.left_indent = Cm(0.74) p.paragraph_format.first_line_indent = Pt(0) p.paragraph_format.space_after = Pt(3) prefix = f"{index}." if ordered else "•" run = p.add_run(f"{prefix} {text}") set_run_font(run, "宋体", "Times New Roman", 12) def add_table(headers, rows, col_widths=None): table = doc.add_table(rows=1 + len(rows), cols=len(headers)) table.style = "Table Grid" table.autofit = True for i, h in enumerate(headers): cell = table.rows[0].cells[i] cell.text = "" p = cell.paragraphs[0] p.alignment = WD_ALIGN_PARAGRAPH.CENTER run = p.add_run(h) set_run_font(run, "宋体", "Times New Roman", 10.5, True) # light header fill tc = cell._tc tcPr = tc.get_or_add_tcPr() shd = tcPr.makeelement(qn("w:shd"), { qn("w:val"): "clear", qn("w:color"): "auto", qn("w:fill"): "D9E2F3", }) tcPr.append(shd) for r_idx, row in enumerate(rows): for c_idx, val in enumerate(row): cell = table.rows[r_idx + 1].cells[c_idx] cell.text = "" p = cell.paragraphs[0] run = p.add_run(str(val)) set_run_font(run, "宋体", "Times New Roman", 10.5) if c_idx == len(row) - 1 and len(headers) == 2 and "人月" in str(val): p.alignment = WD_ALIGN_PARAGRAPH.RIGHT if col_widths: for row in table.rows: for i, w in enumerate(col_widths): row.cells[i].width = Cm(w) doc.add_paragraph() style_normal() add_title("Ai-DOP 数据中台支撑层建设项目方案") add_meta("文档版本:V3.0  编制日期:2026 年 7 月") add_meta("适用范围:第一阶段交付") add_h1("一、项目必要性与价值") add_body( "Ai-DOP 业务运行依赖订单、工单、物料、采购、库存、质量等多类数据," "这些数据通常来自 ERP、MES、WMS 等外部系统,字段、编码和口径不一致。" ) add_body("若不建设统一数据中台支撑层,各业务模块分别对接外部系统,将导致:") for i, t in enumerate( [ "同一数据重复接入、重复整理。", "不同模块对同一业务数据口径不一致。", "外部系统变更时,多个模块需同时改造。", "数据异常难以定位到具体环节。", ], 1, ): add_bullet(t, ordered=True, index=i) add_body( "本项目建设统一的数据中台支撑层,实现外部系统统一对接、数据统一整理、业务统一消费," "并提供基本的任务配置与运行状态查看能力。" ) add_body("项目价值如下:", indent=True) add_table( ["方面", "价值"], [ ["业务", "为产销、制造、供应、采购、仓储等协同提供一致数据基础"], ["建设", "减少重复接口与重复整理,新增模块可复用已有数据能力"], ["运维", "集中配置数据任务,集中查看运行状态与失败原因"], ], col_widths=[2.5, 13], ) add_h1("二、目标与范围") add_h2("2.1 项目定位") add_body("本项目在 Ai-DOP 系统内部建设数据中台支撑层,不建设独立软件。") add_body("沿用 Ai-DOP 现有用户、权限、菜单、数据库、任务调度和部署环境。") add_h2("2.2 建设目标") for i, t in enumerate( [ "支持数据中台与第三方系统对接。", "支持 Ai-DOP 内部业务正常消费中台数据。", "提供基本的数据任务配置能力。", "提供基本的任务运行状态显示能力。", ], 1, ): add_bullet(t, ordered=True, index=i) add_h2("2.3 建设范围") add_body("本阶段包含:") for i, t in enumerate( [ "数据中台管理入口。", "数据来源和数据任务管理。", "主要业务领域的数据标准化和共享数据服务。", "数据任务自动运行和人工触发。", "数据任务运行监控和问题追踪。", ], 1, ): add_bullet(t, ordered=True, index=i) add_body("本阶段不包含:") for i, t in enumerate( [ "数据中台工作台大屏和数据流向可视化展示。", "Ai-DOP 各业务模块自身页面、业务流程、业务表单和 BI 展示建设。", "独立的用户、权限、部署和运维体系。", "全部历史数据一次性治理。", "未确认接口资料的外部系统深度联调(可作为条件验收或后续阶段)。", ], 1, ): add_bullet(t, ordered=True, index=i) add_h2("2.4 范围边界说明") add_table( ["类型", "说明"], [ ["第三方对接", "支持数据库直连和 API 两种接入方式;具体对接对象以双方确认清单为准"], ["内部消费", "以双方确认的业务模块为主,保证可从中台标准数据取数使用"], ["任务配置", "支持任务、关联对象、调度策略的配置与维护"], ["状态显示", "支持查看任务最近运行状态、处理数量和失败原因"], ], col_widths=[3, 12.5], ) add_h1("三、主要建设内容") add_h2("3.1 数据中台管理入口") add_body("在 Ai-DOP 中提供数据中台管理菜单和功能入口,统一进入数据来源、任务配置和运行监控相关功能。") add_h2("3.2 数据来源和数据任务管理") add_body("集中管理接入 Ai-DOP 的数据来源和数据任务,包括:") for t in [ "数据来源名称、类型和用途", "数据任务名称、业务范围和启用状态", "数据任务服务的业务模块", "数据任务与定时计划的关联", "数据对象及关键字段对应关系", ]: add_bullet(t) add_h2("3.3 业务数据标准化和共享服务") add_body("对来自不同系统的数据进行统一整理,重点覆盖:") for t in [ "销售订单和交付数据", "工单、工序和排程数据", "物料、供应商和采购数据", "送货、收货、检验和退货数据", "原材料、在制品和成品库存数据", "生产执行和质量相关数据", ]: add_bullet(t) add_body("整理后形成可供业务页面、跨模块协同、异常监控和运营指标使用的标准数据服务。") add_h2("3.4 数据任务运行") add_body("复用 Ai-DOP 现有任务调度能力,实现:") for t in [ "数据任务按计划自动运行", "必要时人工触发", "记录最近运行时间和状态", "记录处理数量、运行时长和失败原因", ]: add_bullet(t) add_h2("3.5 运行监控和问题追踪") add_body("提供统一的数据任务监控入口,支持:") for t in [ "按任务、状态和时间查询", "查看运行结果和处理数量", "查看失败原因", "按批次定位数据处理问题", ]: add_bullet(t) add_h1("四、成本评估") add_h2("4.1 项目团队") add_table( ["角色", "主要职责"], [ ["项目经理", "计划、协调、范围和交付管理"], ["产品/实施顾问", "业务梳理、口径确认和用户沟通"], ["数据工程师", "数据盘点、标准化、数据整理和核对"], ["后端开发工程师", "对接任务、共享服务和运行监控"], ["前端开发工程师", "管理入口、任务配置和状态显示界面"], ["测试工程师", "功能测试、数据核对和验收支持"], ["运维工程师", "环境、部署、调度和运行保障"], ], col_widths=[4, 11.5], ) add_h2("4.2 工作量估算") add_body("工作量按本阶段功能建设测算,合计控制在 12 人月以内。下表仅列功能项,不含需求评估、测试、上线等项目事务性工作。") add_table( ["功能项", "参考工作量"], [ ["数据中台管理入口", "0.5—1 人月"], ["数据来源与任务管理", "1.5—2.5 人月"], ["业务数据标准化和共享服务", "5—6.5 人月"], ["数据任务运行(自动运行与人工触发)", "1—1.5 人月"], ["运行监控和问题追踪", "1—1.5 人月"], ["合计", "9—12 人月"], ], col_widths=[11, 4.5], ) add_h2("4.3 成本影响因素") for t in [ "接入系统和数据来源数量", "外部系统接口资料完整程度", "历史数据质量和数据量", "业务口径确认难度", "第三方厂商配合程度", "是否需要现场实施、专线或额外安全措施", ]: add_bullet(t) add_body("具体商务报价根据最终确认的数据来源、业务范围和实施条件确定。") add_h1("五、项目计划") add_body("建议项目周期为 10—14 周。") add_table( ["阶段", "参考周期", "主要成果"], [ ["范围确认与数据盘点", "2—3 周", "数据来源、任务、口径和验收清单"], ["基础能力建设", "2—3 周", "管理入口、任务配置、调度接入、基础监控"], ["业务数据接入", "4—6 周", "主要业务数据标准化和共享服务"], ["联调与验收", "2—3 周", "数据核对、测试报告、操作及运维资料"], ], col_widths=[4.5, 2.5, 8.5], ) add_body("如外部系统接口、测试数据或业务口径确认延迟,项目计划相应调整。") add_h1("六、交付与验收") add_h2("6.1 系统交付") for i, t in enumerate( [ "集成在 Ai-DOP 内的数据中台管理入口。", "数据来源和数据任务管理功能。", "主要业务领域的数据标准化和共享数据服务。", "数据任务自动运行和人工触发能力。", "数据任务运行监控和问题追踪功能。", ], 1, ): add_bullet(t, ordered=True, index=i) add_h2("6.2 文档交付") for i, t in enumerate( [ "数据中台支撑层建设方案", "数据来源和数据任务清单", "主要业务数据标准说明", "部署和配置说明", "用户操作及运维说明", "测试和数据核对报告", "项目验收报告", ], 1, ): add_bullet(t, ordered=True, index=i) add_h2("6.3 验收原则") for i, t in enumerate( [ "以双方确认的数据来源、数据任务和业务范围为依据。", "主要数据任务能够按计划运行或人工触发。", "能够查看任务运行状态、处理数量和错误信息。", "主要业务数据按确认口径完成整理,并通过抽样核对。", "确认范围内的业务模块能够正常使用中台数据。", "因外部系统不可用、源数据缺失或第三方接口变化产生的问题,先确认责任边界。", "不以全部历史数据一次性完全一致作为验收前提,差异可解释并有处理意见即可。", ], 1, ): add_bullet(t, ordered=True, index=i) os.makedirs(os.path.dirname(OUT), exist_ok=True) doc.save(OUT) print(OUT)