| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338 |
- # -*- coding: utf-8 -*-
- """S1 风格四合一交付文档生成器(BRD / BBP / DDS / UM)。
- 以 S1 模块四份文档为模板底(复制后清空正文,保留 styles.xml 与页面设置),
- 按 S1 实测版式重写全部内容:
- - BRD:封面 28/22/13 + 文档编号表;H2 范围说明 + H2(一)功能名(REQ-xxx)+ H3 功能说明/业务描述
- - BBP:封面 26/26/14 + 版本行;H1「N 功能名(FUNC-xxx)」+ 7 子节 + 流程图 + 活动/情形/权限/接口/报表五表
- - DDS:封面项目信息表;1.文档概述/2.总体设计/3.功能详设/4.数据库/5.接口/6.安全多租户/7.附录
- - UM :封面 18/24/22 + 作者日期版本行;1.系统登录与首页 + 2.模块操作说明(步骤表+截图+注意+FAQ)
- 数据源:_gen_s9_modules_data.MODULES(功能/流程/规则/角色/接口/报表/TC)+ 本文件 ENRICH(UM步骤、BBP表格行、DDS设计细节)。
- 用法:
- python _gen_s1style_delivery.py gen # 生成到 doc/_tmp_docx_out/s1style/
- python _gen_s1style_delivery.py deploy # 生成并部署到待确认目录(旧版移入 _backup_20260915_pre_s1style)
- """
- from __future__ import annotations
- import shutil
- import sys
- from pathlib import Path
- from docx import Document
- from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_BREAK
- from docx.oxml import OxmlElement
- from docx.oxml.ns import qn
- from docx.shared import Cm, Pt, RGBColor
- HERE = Path(__file__).resolve().parent
- sys.path.insert(0, str(HERE))
- from _gen_s9_modules_data import MODULES # noqa: E402
- BASE = Path(r"C:\Users\skygu\OneDrive\Projects\AIDOP\项目\项目管理\产互联项目管理\交付文档\Release产互联")
- PENDING = BASE / "待确认"
- BACKUP = PENDING / "_backup_20260915_pre_s1style"
- OUT = HERE / "_tmp_docx_out" / "s1style"
- SHOTS = HERE / "_tmp_docx_out" / "shots"
- FLOWS = HERE / "_tmp_docx_out" / "flows"
- TPL = {
- "brd": BASE / "S1产销协同业务需求描述-V0.4.docx",
- "bbp": BASE / "S1产销协同模块蓝图设计方案-V2.2.docx",
- "dds": BASE / "S1产销协同模块详细设计说明书-V1.2.docx",
- "um": BASE / "S1产销协同模块用户操作手册-V1.2.docx",
- }
- FONT = "微软雅黑"
- HDR_FILL = "D6E3F0"
- CN_NUM = "零一二三四五六七八九十"
- TODAY_ISO = "2026-09-15"
- TODAY_CN = "2026年9月15日"
- TODAY_SLASH = "2026/09/15"
- SYSTEM_NAME = "Ai-DOP智慧运营管理系统"
- AUTHOR = "智造易项目组"
- FLOW_PREFIX = {"系统集成": "int", "S9": "s9", "运营诊断": "od", "运营改善": "oi", "ChatBI": "cb"}
- # ─────────────────────────────────────────────────────────────
- # 基础辅助
- # ─────────────────────────────────────────────────────────────
- def new_doc(kind: str) -> Document:
- """复制 S1 模板并清空正文(保留 sectPr),样式/页面设置全部继承 S1。"""
- OUT.mkdir(parents=True, exist_ok=True)
- tmp = OUT / f"_tpl_{kind}.docx"
- shutil.copy2(TPL[kind], tmp)
- doc = Document(str(tmp))
- body = doc.element.body
- for child in list(body):
- if child.tag == qn("w:sectPr"):
- continue
- body.remove(child)
- return doc
- def set_font(run, *, size=None, bold=None):
- run.font.name = FONT
- r_pr = run._element.get_or_add_rPr()
- r_fonts = r_pr.find(qn("w:rFonts"))
- if r_fonts is None:
- r_fonts = OxmlElement("w:rFonts")
- r_pr.insert(0, r_fonts)
- r_fonts.set(qn("w:ascii"), FONT)
- r_fonts.set(qn("w:hAnsi"), FONT)
- r_fonts.set(qn("w:eastAsia"), FONT)
- if size is not None:
- run.font.size = size
- if bold is not None:
- run.bold = bold
- def para(doc, text="", *, size=None, bold=False, align=None, style=None, space_after=None):
- p = doc.add_paragraph(style=style) if style else doc.add_paragraph()
- if align is not None:
- p.alignment = align
- if space_after is not None:
- p.paragraph_format.space_after = Pt(space_after)
- if text:
- run = p.add_run(text)
- set_font(run, size=Pt(size) if size else None, bold=bold)
- return p
- def h1(doc, text):
- p = doc.add_paragraph(style="Heading 1")
- p.add_run(text)
- return p
- def h2(doc, text):
- p = doc.add_paragraph(style="Heading 2")
- p.add_run(text)
- return p
- def h3(doc, text):
- p = doc.add_paragraph(style="Heading 3")
- p.add_run(text)
- return p
- def page_break(doc):
- p = doc.add_paragraph()
- p.add_run().add_break(WD_BREAK.PAGE)
- def add_toc(doc):
- """插入 TOC 域(Word 打开刷新后生成实际目录)。"""
- p = doc.add_paragraph()
- r = p.add_run()
- f1 = OxmlElement("w:fldChar")
- f1.set(qn("w:fldCharType"), "begin")
- instr = OxmlElement("w:instrText")
- instr.set(qn("xml:space"), "preserve")
- instr.text = r' TOC \o "1-3" \h \z \u '
- f2 = OxmlElement("w:fldChar")
- f2.set(qn("w:fldCharType"), "separate")
- t = OxmlElement("w:t")
- t.text = "(在 Word 中右键“更新域”生成目录)"
- f3 = OxmlElement("w:fldChar")
- f3.set(qn("w:fldCharType"), "end")
- r._element.append(f1)
- r._element.append(instr)
- r._element.append(f2)
- r._element.append(t)
- r2 = p.add_run()
- r2._element.append(f3)
- return p
- def shade(cell, fill=HDR_FILL):
- tc_pr = cell._element.get_or_add_tcPr()
- old = tc_pr.find(qn("w:shd"))
- if old is not None:
- tc_pr.remove(old)
- shd = OxmlElement("w:shd")
- shd.set(qn("w:val"), "clear")
- shd.set(qn("w:color"), "auto")
- shd.set(qn("w:fill"), fill)
- tc_pr.append(shd)
- def cell_text(cell, text, *, bold=False, center=False, size=10.5):
- cell.text = ""
- p = cell.paragraphs[0]
- if center:
- p.alignment = WD_ALIGN_PARAGRAPH.CENTER
- run = p.add_run(str(text))
- set_font(run, size=Pt(size), bold=bold)
- def set_table_borders(table, *, full_width=True):
- tbl_pr = table._element.tblPr
- borders = OxmlElement("w:tblBorders")
- for edge in ("top", "left", "bottom", "right", "insideH", "insideV"):
- e = OxmlElement(f"w:{edge}")
- e.set(qn("w:val"), "single")
- e.set(qn("w:sz"), "4")
- e.set(qn("w:color"), "000000")
- borders.append(e)
- tbl_pr.append(borders)
- tbl_w = tbl_pr.find(qn("w:tblW"))
- if tbl_w is None:
- tbl_w = OxmlElement("w:tblW")
- tbl_pr.append(tbl_w)
- if full_width:
- tbl_w.set(qn("w:w"), "5000")
- tbl_w.set(qn("w:type"), "pct")
- else:
- tbl_w.set(qn("w:w"), "0")
- tbl_w.set(qn("w:type"), "auto")
- def data_table(doc, headers, rows, *, size=10.5, center_cols=(0,)):
- """S1 风格数据表:无边框样式、手动单线边框、表头底纹 D6E3F0 加粗居中、100% 宽。"""
- t = doc.add_table(rows=len(rows) + 1, cols=len(headers))
- set_table_borders(t)
- for i, htxt in enumerate(headers):
- cell_text(t.rows[0].cells[i], htxt, bold=True, center=True, size=size)
- shade(t.rows[0].cells[i])
- for r, row in enumerate(rows, 1):
- for c, val in enumerate(row):
- cell_text(t.rows[r].cells[c], val, center=(c in center_cols), size=size)
- return t
- def kv_table(doc, pairs, *, key_fill=HDR_FILL):
- """封面信息表(左键右值,auto 宽)。"""
- t = doc.add_table(rows=len(pairs), cols=2)
- set_table_borders(t, full_width=False)
- for i, (k, v) in enumerate(pairs):
- cell_text(t.rows[i].cells[0], k, bold=True, center=True)
- cell_text(t.rows[i].cells[1], v, center=True)
- shade(t.rows[i].cells[0], key_fill)
- t.rows[i].cells[0].width = Cm(4.5)
- t.rows[i].cells[1].width = Cm(8.5)
- return t
- def picture(doc, img: Path, *, width_cm=15.0, center=True):
- p = doc.add_paragraph()
- if center:
- p.alignment = WD_ALIGN_PARAGRAPH.CENTER
- run = p.add_run()
- run.add_picture(str(img), width=Cm(width_cm))
- return p
- def caption(doc, text):
- return para(doc, text, size=10)
- def cover_gap(doc, n=3):
- for _ in range(n):
- para(doc, "")
- def version_table(doc, rows, *, bbp_style=False):
- """版本记录表。bbp_style=True 时表头为 日期|姓名|版本|变更说明(S1 BBP 风格)。"""
- headers = ["日期", "姓名", "版本", "变更说明"] if bbp_style else ["日期", "版本", "修订人", "变更说明"]
- data_rows = [(r[0], r[1], r[2], r[3]) for r in rows]
- return data_table(doc, headers, data_rows, center_cols=(0, 1, 2))
- def front_matter(doc, *, version_rows, bbp_style=False):
- """版本记录页 + 目录页。"""
- page_break(doc)
- para(doc, "版本记录", size=16, bold=True)
- version_table(doc, version_rows, bbp_style=bbp_style)
- page_break(doc)
- para(doc, "目录", size=16, bold=True)
- add_toc(doc)
- page_break(doc)
- # ─────────────────────────────────────────────────────────────
- # 版本计划(用户决策:V0.5 变更说明直接写变更内容;九宫格 DDS/UM 保持 V0.1)
- # ─────────────────────────────────────────────────────────────
- HIST_ROWS = [
- ("2026-07-30", "V0.1", AUTHOR, "初版建立"),
- ("2026-07-30", "V0.2", AUTHOR, "对齐项目合同里的技术规范需求与功能要求;统一 REQ/FUNC 编号与版式"),
- ("2026-09-04", "V0.3", AUTHOR, "九宫格含 S9 全场关键指标看板;数据对接服务归入系统集成"),
- ("2026-09-04", "V0.4", AUTHOR, "统一系统名称与文档版式,并修订范围与用词"),
- ]
- V05_DESC = {
- ("ChatBI", "brd"): "修订智能问答需求描述,明确报表与历史为规范目标态;统一 S1 文档版式",
- ("ChatBI", "bbp"): "补充智能问答业务流程图与活动、情形、权限、接口、报表设计表;统一 S1 蓝图版式",
- ("ChatBI", "dds"): "补问问答接口设计、壳表现状与降级处理设计;统一 S1 详设版式",
- ("ChatBI", "um"): "补问浮窗操作步骤、结构化回答说明与界面截图;统一 S1 手册版式",
- ("S9", "brd"): "修订九宫格与 S9 看板需求描述并统一 S1 文档版式",
- ("S9", "bbp"): "补充九宫格与 S9 看板业务流程图及活动、情形、权限、接口、报表设计表;统一 S1 蓝图版式",
- ("运营诊断", "brd"): "修订智慧诊断需求描述并统一 S1 文档版式",
- ("运营诊断", "bbp"): "补充智慧诊断业务流程图及活动、情形、权限、接口、报表设计表;统一 S1 蓝图版式",
- ("运营诊断", "dds"): "补充诊断 API、环节矩阵与七维下钻设计;统一 S1 详设版式",
- ("运营诊断", "um"): "补充诊断闭环操作步骤与界面截图;统一 S1 手册版式",
- ("运营改善", "brd"): "修订改善闭环需求描述并统一 S1 文档版式",
- ("运营改善", "bbp"): "补充改善计划台账入口、改善闭环流程图及设计表;统一 S1 蓝图版式",
- ("运营改善", "dds"): "补充改善计划数据表结构、审批流集成与有效性验证设计;统一 S1 详设版式",
- ("运营改善", "um"): "补充改善建档、审批、验证与台账查询操作说明及界面截图;统一 S1 手册版式",
- ("系统集成", "brd"): "补充第三方标准 API 推数入站(方式丙)需求;统一 S1 文档版式",
- ("系统集成", "bbp"): "补充方式丙推数入站流程、业务动作日志与出站回写队列方案及流程图;统一 S1 蓝图版式",
- ("系统集成", "dds"): "补充方式丙入站接口、入站台账与快照表结构、出站回写设计;统一 S1 详设版式",
- ("系统集成", "um"): "补充数据任务日志、业务动作日志、出站回写队列操作说明与界面截图;统一 S1 手册版式",
- }
- def version_rows(mod_key: str, kind: str):
- if mod_key == "S9" and kind == "dds":
- return [("2026-09-15", "V0.1", AUTHOR, "初版建立(补齐九宫格模块详细设计,含数据库设计与功能处理)")]
- if mod_key == "S9" and kind == "um":
- return [("2026-09-15", "V0.1", AUTHOR, "初版建立(补齐九宫格用户操作手册,含界面截图与操作步骤)")]
- return list(HIST_ROWS) + [("2026-09-15", "V0.5", AUTHOR, V05_DESC[(mod_key, kind)])]
- def doc_version(mod_key: str, kind: str) -> str:
- if mod_key == "S9" and kind in ("dds", "um"):
- return "V0.1"
- return "V0.5"
- # ─────────────────────────────────────────────────────────────
- # 交付清单(文件名、封面短名、文档编号、旧版文件)
- # ─────────────────────────────────────────────────────────────
- DELIVER = {
- "ChatBI": {
- "cover_short": "ChatBI智能报表",
- "doc_no_dds": "CBI-DDS-001", "doc_no_um": "CBI-UM-001",
- "files": {"brd": "ChatBI智能报表业务需求描述-V0.5.docx",
- "bbp": "ChatBI智能报表模块蓝图设计方案-V0.5.docx",
- "dds": "ChatBI智能报表模块详细设计说明书-V0.5.docx",
- "um": "ChatBI智能报表-用户操作手册-V0.5.docx"},
- "old": ["ChatBI智能报表业务需求描述-V0.4.docx", "ChatBI智能报表模块蓝图设计方案-V0.4.docx",
- "ChatBI智能报表模块详细设计说明书-V0.4.docx", "ChatBI智能报表-用户操作手册-V0.4.docx"],
- },
- "S9": {
- "cover_short": "九宫格智慧运营看板",
- "doc_no_dds": "S9-DDS-001", "doc_no_um": "S9-UM-001",
- "files": {"brd": "九宫格智慧运营看板业务需求描述-V0.5.docx",
- "bbp": "九宫格智慧运营看板模块蓝图设计方案-V0.5.docx",
- "dds": "九宫格智慧运营看板模块详细设计说明书-V0.1.docx",
- "um": "九宫格智慧运营看板-用户操作手册-V0.1.docx"},
- "old": ["九宫格智慧运营看板业务需求描述-V0.4.docx", "九宫格智慧运营看板模块蓝图设计方案-V0.4.docx",
- "九宫格智慧运营看板模块详细设计说明书-V0.1.docx", "九宫格智慧运营看板-用户操作手册-V0.1.docx"],
- },
- "运营诊断": {
- "cover_short": "运营诊断",
- "doc_no_dds": "OD-DDS-001", "doc_no_um": "OD-UM-001",
- "files": {"brd": "运营诊断业务需求描述-V0.5.docx",
- "bbp": "运营诊断模块蓝图设计方案-V0.5.docx",
- "dds": "运营诊断模块详细设计说明书-V0.5.docx",
- "um": "运营诊断-用户操作手册-V0.5.docx"},
- "old": ["运营诊断业务需求描述-V0.4.docx", "运营诊断模块蓝图设计方案-V0.4.docx",
- "运营诊断模块详细设计说明书-V0.4.docx", "运营诊断-用户操作手册-V0.4.docx"],
- },
- "运营改善": {
- "cover_short": "运营改善",
- "doc_no_dds": "OI-DDS-001", "doc_no_um": "OI-UM-001",
- "files": {"brd": "运营改善业务需求描述-V0.5.docx",
- "bbp": "运营改善模块蓝图设计方案-V0.5.docx",
- "dds": "运营改善模块详细设计说明书-V0.5.docx",
- "um": "运营改善-用户操作手册-V0.5.docx"},
- "old": ["运营改善业务需求描述-V0.5.docx", "运营改善模块蓝图设计方案-V0.5.docx",
- "运营改善模块详细设计说明书-V0.5.docx", "运营改善-用户操作手册-V0.5.docx"],
- },
- "系统集成": {
- "cover_short": "系统集成",
- "doc_no_dds": "INT-DDS-001", "doc_no_um": "INT-UM-001",
- "files": {"brd": "系统集成业务需求描述-V0.5.docx",
- "bbp": "系统集成模块蓝图设计方案-V0.5.docx",
- "dds": "系统集成模块详细设计说明书-V0.5.docx",
- "um": "系统集成-用户操作手册-V0.5.docx"},
- "old": ["系统集成业务需求描述-V0.5.docx", "系统集成模块蓝图设计方案-V0.5.docx",
- "系统集成模块详细设计说明书-V0.5.docx", "系统集成-用户操作手册-V0.5.docx"],
- },
- }
- # ─────────────────────────────────────────────────────────────
- # 模块级数据(UM 介绍、BBP 总体、DDS 架构/术语/数据库/接口)
- # ─────────────────────────────────────────────────────────────
- MODULE_META = {
- "系统集成": {
- "um_intro": "系统集成模块是 Ai-DOP 平台的数据底座,负责第三方系统(ERP/MES/WMS)的多模式对接采集、清洗标准化、同步监控与出站回写。本手册将指导您如何使用数据源管理、同步配置中心、日志查询与出站回写队列等功能。",
- "bbp_overall_intro": "系统集成模块覆盖从第三方系统接入登记、同步任务配置执行、数据清洗入仓到出站回写的全链路,下图展示了总体业务流程。",
- "bbp_design": "前端:Vue3 + Element Plus,数据对接服务配置与监控页面。后端:Admin.NET + 数据对接服务分层(贴源/标准/明细/指标)+ 出站回写队列;对接方式含数据库直连、HTTP API 拉取与第三方标准 API 推数入站(方式丙:签名鉴权、幂等去重、全量快照+差集、NDJSON 批量、日终对账)。",
- "dds_scope": "本说明书覆盖系统集成模块的第三方系统同步、日志查询、第三方系统事务三个功能的详细设计,含数据对接服务(数据源管理、同步配置中心、数据任务日志、业务动作日志、出站回写队列)与方式丙标准 API 推数入站。",
- "dds_arch": "系统集成采用数据对接服务分层架构:接入层(数据库直连执行器、HTTP API 拉取执行器、方式丙标准 API 推数入站)→ 贴源层 ODS → 标准层 STD → 明细层 DWD → 指标层 DWS;出站侧经 Outbox 幂等待推表统一回写第三方系统。同步任务由调度作业触发,执行结果写入数据任务日志与业务动作日志。",
- "terms": [("MDP", "数据对接服务(Manufacturing Data Platform),负责采集、清洗、分层入仓与回写"),
- ("方式丙", "第三方标准 API 推数入站:对方系统按我方标准 API 主动推送数据,含签名鉴权与幂等"),
- ("ODS/STD/DWD/DWS", "贴源层/标准层/明细层/指标层,数据对接服务分层模型"),
- ("Outbox", "出站回写幂等待推表,统一承载回写第三方系统的事务"),
- ("NDJSON", "逐行 JSON 批量推送格式,每行独立幂等键"),
- ("AccessKey", "方式丙入站授权标识,配合签名头鉴权")],
- "modules_tbl": [("INT-M01", "第三方系统同步", "数据源登记、同步任务配置与触发;方式丙推数入站", "数据对接服务"),
- ("INT-M02", "日志查询", "数据任务日志与业务动作日志的监控追溯", "INT-M01"),
- ("INT-M03", "第三方系统事务", "出站回写队列监控与失败容错", "INT-M01")],
- "db_intro": "系统集成模块数据表归属数据对接服务(mdp_*)与运行保障(ado_mdp_*),覆盖接入配置、入站台账、出站回写与文件导入四类。",
- "db_tables": [("mdp_source", "数据源登记", "连接类型/参数/凭据引用/状态"),
- ("mdp_entity", "源实体登记", "实体编码/来源对象/同步方向"),
- ("mdp_field_mapping", "字段映射", "源字段↔标准字段映射与转换"),
- ("mdp_sync_task", "同步任务业务配置", "task_code/task_type/consumer_modules/config_version"),
- ("mdp_sync_task_step", "任务步骤配置", "步骤顺序/执行器/参数"),
- ("mdp_sync_task_schedule", "任务调度配置", "定时/实时策略与调度作业关联"),
- ("mdp_sync_task_param", "任务参数", "参数键值"),
- ("mdp_sync_task_formula", "任务公式", "清洗转换公式"),
- ("mdp_inbound_grant", "入站对接授权", "access_key/对接编码/启用状态"),
- ("mdp_inbound_request", "入站请求台账", "幂等键/请求哈希/批次/回执/耗时"),
- ("mdp_inbound_envelope", "入站原始信封归档", "原始报文归档(mediumtext)"),
- ("mdp_inbound_snapshot", "全量快照登记", "快照状态 OPEN/DIFF_BLOCKED 等"),
- ("mdp_inbound_conflict", "入站冲突记录", "快照差集冲突明细"),
- ("mdp_field_map", "标准字段映射(入站)", "对外规范字段↔内部字段"),
- ("mdp_outbox", "出站回写 Outbox", "幂等键/报文/状态/重试/错误码"),
- ("mdp_file_import_batch", "文件导入批次", "批次/文件/状态"),
- ("mdp_file_import_row", "文件导入行", "行数据与校验结果"),
- ("mdp_file_import_error", "文件导入错误", "错误行与原因"),
- ("ado_mdp_hot_watch", "热点监听", "热表变更监听配置"),
- ("ado_mdp_rebuild_lock", "重建锁", "分层重建互斥锁")],
- "db_core": ["mdp_sync_task", "mdp_inbound_request", "mdp_outbox"],
- "db_rel": "mdp_sync_task 1—n mdp_sync_task_step/schedule/param/formula(config_version 版本化);mdp_inbound_request 按 (tenant_id, access_key, entity_code, idempotency_key) 唯一幂等;mdp_inbound_snapshot 1—n mdp_inbound_conflict;mdp_outbox 按 idem_key 幂等去重;核心查询均带 tenant_id 索引。",
- "if_list": [("POST", "api/mdp/inbound/{entityCode}", "方式丙·接收推数(签名鉴权+幂等)"),
- ("GET", "api/mdp/inbound/{entityCode}/schema", "方式丙·对外规范字段 JSON Schema"),
- ("POST", "api/mdp/inbound/{entityCode}/snapshots", "方式丙·开启全量快照"),
- ("POST", "api/mdp/inbound/{entityCode}/snapshots/{snapshotId}/commit", "方式丙·提交快照差集"),
- ("POST", "api/mdp/inbound/{entityCode}/bulk", "方式丙·NDJSON 分块批量推送"),
- ("GET", "api/mdp/inbound/{entityCode}/digest", "方式丙·日终对账摘要"),
- ("GET", "api/mdp/inbound/receipts/{syncBatchId}", "方式丙·按批次查回执"),
- ("动态API", "api/MdpSyncTask/* 等", "数据源/同步任务/日志/队列的页面管理接口")],
- "if_detail": "方式丙全部端点类级启用 InboundSignature 签名鉴权(签名串 方法&路径&参数&body 摘要),未开通的对接编码一律拒绝;推数按 (access_key, entity_code, idempotency_key) 幂等去重,重复请求返回原回执;全量快照差集冲突进入 DIFF_BLOCKED,须 force 提交或人工处理;日终对账按 date 输出双方计数摘要。",
- "if_seq": "第三方系统 → 计算签名 → POST api/mdp/inbound/{entityCode} → 鉴权/幂等校验 → 清洗标准化 → 写入贴源/标准层 → 记录入站台账与回执 → 第三方按批次查回执与日终对账。",
- },
- "S9": {
- "um_intro": "九宫格智慧运营看板模块是 Ai-DOP 平台的管理层总览入口,一屏展示 S1~S9 各模块核心 KPI 与红黄绿预警,并可下钻至 S9 全场关键指标看板与智慧诊断。本手册将指导您如何使用九宫格与 S9 全场关键指标看板。",
- "bbp_overall_intro": "九宫格智慧运营看板覆盖从指标主数据、日批计算到总览预警、看板下钻与诊断联动的全链路,下图展示了总体业务流程。",
- "bbp_design": "前端:Vue3 + Element Plus;九宫格首页与动态看板(DynamicModuleDashboard)。后端:Admin.NET + 指标层日批计算(KPI 原子聚合层→维度聚合→看板配置驱动展示);与智慧诊断、ChatBI 联动。",
- "dds_scope": "本说明书覆盖九宫格智慧运营看板(FUNC-S9-005)与 S9 全场关键指标看板(FUNC-S9-004)两个功能的详细设计。",
- "dds_arch": "看板采用配置驱动架构:运营指标主数据(KPI Master)定义口径与阈值 → 指标层日批(原子聚合层→维度值日表)→ 看板页面配置(dashboard_page_config/widget)→ AidopKanban API 聚合输出 → 前端动态看板渲染。九宫格首页布局由 home_module/layout_item 驱动。",
- "terms": [("KPI Master", "运营指标主数据,定义指标编码、公式、层级与红黄绿阈值"),
- ("L1/L2/L3/L4", "指标层级,L1 为管理层核心指标,逐级下钻"),
- ("原子聚合层", "KPI 最小颗粒度日粒度聚合表,存可二次聚合基础量"),
- ("红黄绿", "达标状态:达标绿、预警黄、未达标红"),
- ("动态看板", "按页面配置动态渲染的模块看板(DynamicModuleDashboard)")],
- "modules_tbl": [("S9-M01", "九宫格智慧运营看板", "S1~S9 模块格子总览、红黄绿预警、全屏与下钻", "指标层日批"),
- ("S9-M02", "S9 全场关键指标看板", "全场 L1/L2 指标卡、趋势、筛选与诊断联动", "S9-M01")],
- "db_intro": "九宫格模块数据表归属智慧运营指标体系(ado_smart_ops_*),覆盖指标主数据、日批聚合、看板配置与业务事实四类。",
- "db_tables": [("ado_smart_ops_kpi_master", "运营指标主数据", "指标编码/公式/层级/红黄绿阈值"),
- ("ado_smart_ops_kpi_atomic_day", "KPI 原子聚合层(日)", "日粒度分子/分母/样本数等基础量"),
- ("ado_smart_ops_kpi_dimension_value_day", "KPI 维度值日表", "按维度聚合的日指标值"),
- ("ado_smart_ops_kpi_target_config", "KPI 目标配置", "目标值与生效区间"),
- ("ado_smart_ops_kpi_calc_config", "KPI 计算配置", "计算规则与调度"),
- ("ado_smart_ops_kpi_calc_run_log", "KPI 计算运行日志", "批次/耗时/结果"),
- ("ado_smart_ops_kpi_business_input", "KPI 业务补录", "人工补录指标数据"),
- ("ado_smart_ops_kpi_dimension_config", "KPI 维度配置", "维度定义与取值"),
- ("ado_smart_ops_home_module", "九宫格模块呈现", "模块布局 card_grid/table_list"),
- ("ado_smart_ops_home_layout_item", "九宫格布局项", "格子顺序与展示配置"),
- ("ado_smart_ops_dashboard_page_config", "看板页面配置", "页面结构与筛选项"),
- ("ado_smart_ops_dashboard_widget", "看板部件配置", "指标卡/趋势图等部件"),
- ("ado_smart_ops_business_fact", "业务事实表", "指标计算源事实")],
- "db_core": ["ado_smart_ops_kpi_master", "ado_smart_ops_kpi_atomic_day"],
- "db_rel": "kpi_master 按 (metric_code, tenant_id) 唯一,父子自关联(parent_id)形成 L1~L4 树;kpi_atomic_day 按 (tenant_id, metric_code, stat_date, 维度键) 聚合,向上汇入 dimension_value_day;dashboard_page_config 1—n dashboard_widget;home_module 1—n home_layout_item。",
- "if_list": [("GET", "api/AidopKanban/home-l1", "首页 L1 指标总览"),
- ("GET", "api/AidopKanban/home-grid/{moduleCode}", "九宫格模块格子数据"),
- ("GET", "api/AidopKanban/module-detail", "模块详情看板数据"),
- ("GET", "api/AidopKanban/dashboard-page", "动态看板页面配置与数据"),
- ("GET", "api/AidopKanban/smart-diagnosis/{moduleCode}", "智慧诊断联动入口")],
- "if_detail": "看板接口按租户隔离,指标值来自维度值日表与原子聚合层日批结果;筛选上下文(时间/组织/产品等)在各接口间透传,保证九宫格→看板→诊断口径一致。",
- "if_seq": "日批作业 → 原子聚合层/维度值日表 → 用户打开九宫格 → home-grid 聚合 → 点击格子 → dashboard-page 渲染模块看板 → 未达标项 → smart-diagnosis 联动。",
- },
- "运营诊断": {
- "um_intro": "运营诊断模块是 Ai-DOP 平台的智能分析入口,承接九宫格与看板未达标指标,以订单为主线开展环节级诊断、七维下钻根因溯源,并输出诊断结论转改善闭环。本手册将指导您如何使用智慧诊断功能。",
- "bbp_overall_intro": "运营诊断覆盖从未达标指标接入、环节识别、根因下钻到诊断报告与转改善的全链路,下图展示了总体业务流程。",
- "bbp_design": "前端:Vue3 + Element Plus;智慧诊断页(环节诊断矩阵、目标&现状、主要问题、下钻证据区)。后端:Admin.NET + AidopKanban 诊断 API,基于统一数据抽取能力与指标层/明细层计算;改善任务生成并入 FUNC-S9-006。",
- "dds_scope": "本说明书覆盖智慧诊断(FUNC-S9-006)的详细设计,含环节诊断矩阵、目标&现状、主要问题下钻与转改善入口。",
- "dds_arch": "智慧诊断采用指标驱动的规则诊断架构:指标层日批结果 + 明细层单据数据 → 诊断规则引擎(环节阈值/断点/滞后识别)→ 诊断结论(环节矩阵/目标&现状/主要问题)→ L3/L4 证据下钻 → 改善计划生成(AdoSmartOpsImprovementPlan API)。",
- "terms": [("环节矩阵", "以业务环节(订单/采购/备料/生产/入库/发运等)为行、指标为列的诊断总览"),
- ("七维下钻", "订单、物料、供应商、产线、仓库、时间段、人员七类根因溯源维度"),
- ("目标&现状", "诊断页展示指标目标值与当前实际值的对比区"),
- ("主要问题", "诊断输出的问题清单,可逐条下钻证据并转改善计划")],
- "modules_tbl": [("OD-M01", "智慧诊断", "环节异常识别、七维根因下钻、诊断结论与转改善", "九宫格/看板、指标层")],
- "db_intro": "智慧诊断本身不新增业务表,诊断计算直接读取九宫格指标层(ado_smart_ops_kpi_*)、明细层单据与各模块业务表;诊断产生的改善任务落库于运营改善模块表(ado_smart_ops_improvement_*)。",
- "db_tables": [("(读取)ado_smart_ops_kpi_dimension_value_day", "指标日结果", "诊断输入:达标状态与偏差"),
- ("(读取)ado_smart_ops_kpi_master", "指标主数据", "诊断输入:阈值与口径"),
- ("(写入)ado_smart_ops_improvement_plan", "改善计划", "转改善输出(见运营改善模块)")],
- "db_core": [],
- "db_rel": "诊断侧无独立表结构;读取侧关系见九宫格模块详细设计说明书。",
- "if_list": [("GET", "api/AidopKanban/smart-diagnosis/{moduleCode}", "智慧诊断主页数据(环节矩阵/目标现状/主要问题)"),
- ("GET", "api/AidopKanban/smart-diagnosis/{moduleCode}/evidence", "主要问题下钻证据明细"),
- ("POST", "api/AdoSmartOpsImprovementPlan/createFromDiagnosis", "由诊断主要问题生成改善计划")],
- "if_detail": "诊断接口按模块编码与筛选上下文(期间/组织等)返回环节状态、目标&现状、主要问题列表;evidence 接口按问题与维度返回单据级证据;转改善调用运营改善模块接口并回写改善计划编号。",
- "if_seq": "看板未达标项 → smart-diagnosis 主页 → 主要问题 → evidence 下钻明细 → 确认结论 → createFromDiagnosis 生成改善计划。",
- },
- "运营改善": {
- "um_intro": "运营改善模块是 Ai-DOP 平台的闭环整改入口,承接诊断输出的问题建档,完成审批派单、行动跟踪与有效性验证,并提供改善计划台账集中查询。本手册将指导您如何使用改善计划与效果验证功能。",
- "bbp_overall_intro": "运营改善覆盖从诊断问题建档、审批派单、行动项跟踪到效果量化复盘的全链路,下图展示了总体业务流程。",
- "bbp_design": "前端:Vue3 + Element Plus;智慧诊断页改善闭环区与改善计划台账页。后端:Admin.NET + AdoSmartOpsImprovementPlan API + 平台审批流;效果验证对比基线与当前 KPI 并保留验证证据。",
- "dds_scope": "本说明书覆盖改善计划与效果验证(REQ-S9-007,FUNC 并入 FUNC-S9-006)的详细设计,含诊断闭环建档、审批派单、行动跟踪、有效性验证与改善计划台账。",
- "dds_arch": "运营改善采用计划驱动的闭环架构:诊断主要问题 → 改善计划(问题建档/行动项 JSON/责任人/到期日)→ 平台审批流派单(FlowInstanceId 回写)→ 行动项执行与日志 → 有效性验证(基线/目标/验证值/自动评价)→ 闭环;台账页提供多条件集中查询。",
- "terms": [("改善计划", "由诊断问题建档的整改单,含根因、行动项、责任人与计划完成日"),
- ("行动项", "改善计划内的具体执行事项,可逐项跟踪状态"),
- ("有效性验证", "到期对比改善前后指标,输出验证结论(有效/部分有效/无效)"),
- ("改善计划台账", "全部改善计划的集中查询页,支持多条件筛选")],
- "modules_tbl": [("OI-M01", "改善计划与效果验证", "问题建档、审批派单、行动跟踪、效果复盘与台账查询", "运营诊断、审批流")],
- "db_intro": "运营改善模块数据表为 ado_smart_ops_improvement_* 系列,覆盖计划、行动项、日志、通知与验证五类。",
- "db_tables": [("ado_smart_ops_improvement_plan", "智慧诊断改善计划", "计划单号/问题/根因/行动项/状态/验证结论"),
- ("ado_smart_ops_improvement_action", "改善行动项", "行动项明细/责任人/状态"),
- ("ado_smart_ops_improvement_action_log", "行动项日志", "状态流转与操作留痕"),
- ("ado_smart_ops_improvement_action_notice", "行动项通知", "到期提醒与催办"),
- ("ado_smart_ops_improvement_verify_log", "有效性验证日志", "验证提交与对比证据")],
- "db_core": ["ado_smart_ops_improvement_plan"],
- "db_rel": "improvement_plan 按 (tenant_id, plan_no) 唯一,1—n improvement_action;行动项状态流转写 action_log;验证提交写 verify_log;plan.flow_instance_id 关联平台审批流实例;按 (tenant_id, factory_id, module_code, status) 与 (tenant_id, due_date) 建索引支撑台账筛选。",
- "if_list": [("POST", "api/AdoSmartOpsImprovementPlan/createFromDiagnosis", "由诊断主要问题生成改善计划"),
- ("POST", "api/AdoSmartOpsImprovementPlan/page", "改善计划台账分页查询"),
- ("GET", "api/AdoSmartOpsImprovementPlan/detail", "改善计划详情"),
- ("POST", "api/AdoSmartOpsImprovementPlan/submitApproval", "提交审批派单"),
- ("POST", "api/AdoSmartOpsImprovementPlan/startExecution", "开始执行"),
- ("POST", "api/AdoSmartOpsImprovementPlan/updateActionItem", "更新行动项状态"),
- ("GET", "api/AdoSmartOpsImprovementPlan/verificationDashboard", "有效性验证仪表(基线/当前对比)"),
- ("POST", "api/AdoSmartOpsImprovementPlan/submitVerification", "提交验证结论"),
- ("POST", "api/AdoSmartOpsImprovementPlan/close", "关闭改善计划")],
- "if_detail": "台账分页支持状态/责任人/模块/到期区间筛选;提交审批后写回 flow_instance_id 并进入审批中心待办;验证仪表返回基线值、目标值与当前 KPI 对比,提交验证后允许关闭或继续跟踪。",
- "if_seq": "诊断生成计划 → 保存行动项 → submitApproval 审批派单 → startExecution → updateActionItem 跟踪 → verificationDashboard 对比 → submitVerification → close 闭环。",
- },
- "ChatBI": {
- "um_intro": "ChatBI 智能报表模块是 Ai-DOP 平台的自然语言问数入口,嵌入九宫格与模块看板,以对话方式返回运营指标结论、证据与建议。本手册将指导您如何使用 ChatBI 智能问答。",
- "bbp_overall_intro": "ChatBI 覆盖从看板上下文、自然语言提问、意图解析与指标聚合到结论输出与看板/诊断跳转的链路,下图展示了总体业务流程。",
- "bbp_design": "前端:Vue3 + Element Plus;看板内 ChatBI 浮窗。后端:ChatBIController + ChatBIService,意图解析后按当前模块聚合已发布运营指标作答,DeepSeek 可用时润色,不可用时回退本地模板答案。",
- "dds_scope": "本说明书覆盖 ChatBI 智能问答(FUNC-S9-007)的详细设计;报表与历史(NL2SQL/查询历史)为规范目标态,当前未上线,不在本版设计范围。",
- "dds_arch": "ChatBI 采用轻量问答架构:看板上下文(模块编码/筛选)+ 问题 → 意图解析(指标词匹配)→ 指标聚合(KPI 日表)→ 答案组装(结论/证据/原因/下一步 + 指标卡 + 跳转动作)→ (可选)LLM 润色;全程不落库,服务不可用时回退本地模板。",
- "terms": [("ChatBI 浮窗", "嵌于九宫格与模块看板的问答窗口"),
- ("结构化回答", "结论/证据/可能原因/下一步建议四段式回答,附相关指标卡"),
- ("本地模板回退", "智能服务不可用时由本地模板生成答案(isFallback)"),
- ("目标态", "规范所列 NL2SQL 报表、查询历史与语义模型配置,当前未上线")],
- "modules_tbl": [("CBI-M01", "ChatBI 智能问答", "看板内自然语言问数、结构化回答与跳转联动", "九宫格/看板、指标层")],
- "db_intro": "ChatBI 问答实时聚合指标层数据作答,不写业务表;ado_s9_chatbi_* 为规划期壳表,未接入运行链路。",
- "db_tables": [("(读取)ado_smart_ops_kpi_dimension_value_day", "指标日结果", "问答聚合输入"),
- ("(壳表)ado_s9_chatbi_*", "ChatBI 规划壳表", "查询历史/语义配置目标态,未接入")],
- "db_core": [],
- "db_rel": "无独立表结构;读取侧关系见九宫格模块详细设计说明书。",
- "if_list": [("POST", "api/AidopChatBI/ask", "自然语言问数(问题+模块上下文 → 结构化回答)")],
- "if_detail": "ask 接口入参含 question 与当前模块/筛选上下文;返回结论、证据摘要、可能原因、下一步建议、相关指标卡与跳转动作(看板/诊断);source 标记 local/deepseek,isFallback 标记降级。",
- "if_seq": "看板页打开浮窗 → 提交问题 → ask 聚合作答 → 展示结构化回答与指标卡 → 点击动作跳转看板/诊断。",
- },
- }
- # ─────────────────────────────────────────────────────────────
- # ENRICH:功能级内容(UM 步骤/截图/注意/FAQ;BBP 情形/权限/接口/报表表;DDS 页面/处理)
- # key: (模块, REQ 编号)
- # ─────────────────────────────────────────────────────────────
- ENRICH = {
- ("系统集成", "REQ-S9-001"): {
- "module_code": "INT-M01",
- "menu_path": "左侧菜单 → MDIOP → 数据中台管理 → 数据源管理;同步配置中心",
- "overview": "第三方系统同步用于登记第三方系统(ERP/MES/WMS)接入并配置同步任务,支持数据库直连、HTTP API 拉取与第三方标准 API 推数入站(方式丙),是订单至出库数据链路的入口。",
- "roles_short": "实施工程师、系统管理员",
- "steps_txt": [
- "步骤1:进入“数据源管理”页面,查看已登记数据源列表(名称、类型、连接状态),可按条件筛选。",
- "步骤2:点击“新增”登记数据源:选择接入方式(数据库直连 / HTTP API),填写连接参数与凭据后保存。",
- "步骤3:进入“同步配置中心”页面,查看同步任务列表(任务编码、名称、类型、调度、状态)。",
- "步骤4:新增或编辑同步任务:选择数据源与实体映射,配置定时或实时同步策略后启用。",
- "步骤5:首次启用后在“数据任务日志”核对执行结果;方式丙对接由实施开通 AccessKey 与对接编码后,第三方按标准 API 主动推送,无需页面配置。",
- ],
- "steps_tbl": [("1", "查询数据源", "数据源列表支持多条件筛选,含连接状态"),
- ("2", "新增数据源", "选择直连或 HTTP API,凭据加密保存、不明文回显"),
- ("3", "配置同步任务", "选择实体映射,设定定时或实时策略"),
- ("4", "启用并验证", "启用后首次执行结果见“数据任务日志”"),
- ("5", "方式丙对接", "实施开通授权后由第三方按标准 API 推数")],
- "shots": [("shot_int_sources.png", "数据源管理页面"), ("shot_int_tasks.png", "同步配置中心页面")],
- "notes": ["数据源凭据加密保存,页面不回显明文密钥。",
- "未开通的对接编码推数一律拒绝并记录日志。",
- "任务停用后调度不再触发,已排队批次不受影响。"],
- "faq": [("同步任务没有按预期执行怎么办?", "先在“数据任务日志”查看失败原因,再核对数据源连通性与任务启用状态;方式丙推数失败请核对签名与对接编码授权。")],
- "situations": [("新增第三方系统接入", "实施在数据源管理登记连接方式与凭据,完成连通性验证后交付配置"),
- ("定时/实时同步", "同步配置中心按策略调度执行,结果写数据任务日志"),
- ("方式丙推数入站", "第三方按标准 API 主动推送,签名鉴权、幂等去重、支持快照差集与日终对账")],
- "perm_rows": [("实施工程师", "数据源与同步任务的新增、编辑、启用/停用"),
- ("系统管理员", "全部配置权限与入站授权管理"),
- ("业务用户", "只读消费同步结果,无配置权限")],
- "if_rows": [("数据库直连同步", "定时/实时拉取第三方数据库表", "定时(可配)"),
- ("HTTP API 拉取", "调用第三方接口拉数", "定时/手动"),
- ("标准 API 推数入站", "api/mdp/inbound 方式丙推送", "第三方触发"),
- ("出站回写", "Outbox 队列推送第三方", "业务触发")],
- "rpt_rows": [("同步结果监控", "任务执行成功/失败与耗时", "见“日志查询”功能")],
- "dds_page": ["数据源管理页:筛选区(名称/类型/状态)+ 数据源列表(名称、类型、连接状态、更新时间)+ 新增/编辑弹窗(接入方式、连接参数、凭据)。路由 /aidop/data-platform/sources。",
- "同步配置中心页:任务列表(任务编码、名称、类型、调度、状态)+ 任务编辑(实体映射、步骤、调度策略、参数)。路由 /aidop/data-platform/sync-tasks。"],
- "dds_handle": ("数据源连接参数/实体映射/调度策略", "连接测试→映射校验→任务装配(步骤/调度/参数)→启用触发", "可执行同步任务与首同步结果", "凭据加密;接入方式限直连/HTTP API/方式丙;未开通对接编码拒绝", "源不可达记失败日志并告警"),
- },
- ("系统集成", "REQ-S9-002"): {
- "module_code": "INT-M02",
- "menu_path": "左侧菜单 → MDIOP → 数据中台管理 → 数据任务日志;业务动作日志",
- "overview": "日志查询是集成运行的监控与追溯入口:数据任务日志记录同步批次执行结果,业务动作日志记录中台业务动作的执行明细,支撑运维排障与验收举证。",
- "roles_short": "运维、系统管理员",
- "steps_txt": [
- "步骤1:进入“数据任务日志”页面,按时间范围、任务、状态筛选同步执行记录。",
- "步骤2:点击失败记录,查看错误信息与失败原因摘要。",
- "步骤3:进入“业务动作日志”页面,按时间、动作类型、状态筛选动作级执行明细。",
- "步骤4:按批次号/任务编码在两类日志间关联,定位异常环节后转同步配置中心处置。",
- ],
- "steps_tbl": [("1", "筛选任务日志", "按时间/任务/状态过滤同步批次"),
- ("2", "查看失败详情", "错误码与失败原因摘要可追溯"),
- ("3", "查动作日志", "业务动作级执行明细(含耗时与结果)"),
- ("4", "关联处置", "按批次号关联两类日志并转任务配置处理")],
- "shots": [("shot_int_synclogs.png", "数据任务日志页面"), ("shot_int_actionlogs.png", "业务动作日志页面")],
- "notes": ["日志按租户隔离,仅显示当前租户数据。",
- "失败日志包含错误码与原因摘要,处置后可重新触发任务。",
- "查询无结果显示“暂无数据”,不代表系统异常。"],
- "faq": [("失败后如何重跑?", "在“同步配置中心”重新触发对应任务,或由运维按批次重跑;重跑结果会生成新的日志记录。")],
- "situations": [("日常监控", "运维按日检查失败任务与动作日志,确认同步健康度"),
- ("异常排障", "按批次关联任务日志与动作日志,定位失败环节并处置"),
- ("验收举证", "导出或截图日志记录作为同步执行证据")],
- "perm_rows": [("运维", "日志查询与失败处置"),
- ("系统管理员", "全部日志查询权限")],
- "if_rows": [("任务日志查询 API", "同步批次执行记录查询", "页面查询"),
- ("动作日志查询 API", "业务动作执行明细查询", "页面查询")],
- "rpt_rows": [("同步监控列表", "按时间/状态的任务执行统计视图", "页面查询,可扩展导出")],
- "dds_page": ["数据任务日志页:筛选区(时间/任务/状态)+ 批次列表(任务、开始/结束、状态、耗时、错误摘要)。路由 /aidop/data-platform/sync-logs。",
- "业务动作日志页:筛选区(时间/动作/状态)+ 动作列表(动作类型、批次、状态、耗时、结果摘要)。路由 /aidop/data-platform/action-run-logs。"],
- "dds_handle": ("筛选条件", "按条件查询执行日志→失败提取错误码与摘要→关联批次", "日志列表与失败详情", "租户隔离;敏感凭据不落日志明文", "无日志返回空态"),
- },
- ("系统集成", "REQ-S9-003"): {
- "module_code": "INT-M03",
- "menu_path": "左侧菜单 → MDIOP → 数据中台管理 → 出站回写队列",
- "overview": "第三方系统事务以出站回写队列(Outbox)监控回写第三方系统的事务状态,覆盖待推、成功、失败(死信)全生命周期,支撑业务数据双向流转与传输容错。",
- "roles_short": "运维处理失败;业务触发;管理员配置端点",
- "steps_txt": [
- "步骤1:进入“出站回写队列”页面,查看事务列表(目标源、动作、状态、重试次数、创建时间)。",
- "步骤2:按状态(待推/成功/失败)、目标数据源或动作类型筛选。",
- "步骤3:点击失败事务,查看错误码、错误信息与请求报文摘要。",
- "步骤4:失败事务由系统按退避策略自动重推;长期失败进入死信的,核对目标系统状态后由人工处理。",
- ],
- "steps_tbl": [("1", "查看事务队列", "待推/成功/失败(死信)状态全览"),
- ("2", "筛选定位", "按状态/目标源/动作类型过滤"),
- ("3", "查看失败详情", "错误码、错误信息与报文摘要"),
- ("4", "容错处理", "自动退避重推;死信人工核对处理")],
- "shots": [("shot_int_outbox.png", "出站回写队列页面")],
- "notes": ["回写统一走 Outbox,按幂等键去重,禁止无日志直连外写。",
- "死信事务不会自动重推,须人工核对目标系统状态后处理。",
- "请勿直接修改队列数据表,处置应通过页面或运维工具进行。"],
- "faq": [("待推事务一直不减少怎么办?", "检查目标数据源路由配置与推送作业运行状态;若目标系统不可达,事务会按退避策略延后重推。")],
- "situations": [("业务触发回写", "业务操作完成后写入 Outbox,由推送作业投递第三方"),
- ("失败重试", "推送失败按退避策略自动重推并记录错误码"),
- ("死信处置", "超过重试上限转死信,人工核对后重发或标记处理")],
- "perm_rows": [("运维", "队列查询与失败处置"),
- ("系统管理员", "端点配置与全部队列权限"),
- ("业务用户", "触发回写,无队列操作权限")],
- "if_rows": [("出站推送 API", "Outbox 投递第三方系统", "业务触发+作业轮询"),
- ("回执登记", "第三方接收结果回写队列状态", "推送后同步")],
- "rpt_rows": [("事务成功率统计", "成功/失败/死信数量与趋势", "队列页面统计视图")],
- "dds_page": ["出站回写队列页:状态统计区(待推/成功/死信计数)+ 筛选区(状态/目标源/动作)+ 事务列表(目标源、动作、状态、重试次数、错误码、时间)+ 失败详情抽屉。路由 /aidop/data-platform/outbox。"],
- "dds_handle": ("业务回写请求", "写 Outbox(幂等键)→作业轮询推送→回执更新状态→失败退避重推", "回写事务状态与回执", "幂等键去重;断点续传;死信人工介入", "目标不可达记错误码并延后重推"),
- },
- ("S9", "REQ-S9-005"): {
- "module_code": "S9-M01",
- "menu_path": "左侧菜单 → MDIOP → 智慧运营看板 → 九宫格(登录后首页默认展示)",
- "overview": "九宫格是管理层一屏总览:S1~S9 九个模块格子卡片展示核心 KPI 当前值、目标、偏差与红黄绿状态,未达标格子醒目预警,支持全屏大屏模式与点击下钻。",
- "roles_short": "管理层(只读)、运营专员(筛选下钻)",
- "steps_txt": [
- "步骤1:登录系统后首页即为九宫格(也可从菜单“智慧运营看板 → 九宫格”进入)。",
- "步骤2:浏览 S1~S9 各模块格子指标卡:当前值、目标值、偏差与红黄绿状态一目了然。",
- "步骤3:点击页面右上角“全屏”按钮进入大屏展示模式;点击“退出全屏”或按 ESC 返回。",
- "步骤4:点击任一模块格子,进入对应模块看板查看明细指标。",
- "步骤5:点击格子上的“智慧诊断”按钮,可对未达标指标进入诊断分析。",
- ],
- "steps_tbl": [("1", "打开九宫格", "登录后首页默认展示,菜单亦可进入"),
- ("2", "浏览指标卡", "当前/目标/偏差/红黄绿状态"),
- ("3", "切换全屏", "大屏展示模式,退出全屏按钮返回"),
- ("4", "格子下钻", "进入对应模块看板"),
- ("5", "联动诊断", "未达标指标进入智慧诊断")],
- "shots": [("shot_s9_grid.png", "九宫格首页"), ("shot_s9_fullscreen.png", "九宫格全屏模式")],
- "notes": ["指标口径以运营指标主数据为准,页面不单独定义计算公式。",
- "无数据的格子显示空态占位,不影响其他格子浏览。",
- "全屏模式适合车间/会议室大屏投放。"],
- "faq": [("格子显示红色代表什么?", "表示该模块存在未达标 L1 指标,点击格子进入模块看板或点击“智慧诊断”查看明细与原因。")],
- "situations": [("管理层早会巡览", "一屏查看全场核心指标与预警,定位异常模块"),
- ("异常下钻", "点击红色格子进入模块看板,必要时进入智慧诊断"),
- ("大屏投放", "全屏模式用于现场大屏,定时刷新")],
- "perm_rows": [("管理层", "九宫格只读查看"),
- ("运营专员", "筛选、下钻与诊断联动"),
- ("指标配置(S0)", "指标与布局配置在运营建模侧维护")],
- "if_rows": [("home-grid 接口", "九宫格各模块格子数据", "页面加载/刷新"),
- ("home-l1 接口", "首页 L1 指标总览", "页面加载")],
- "rpt_rows": [("管理层大屏视图", "全场 KPI 即时总览", "九宫格页即时报表")],
- "dds_page": ["九宫格首页:3×3 格子卡片(模块名、L1 指标、当前/目标/偏差、红黄绿状态)+ 全屏按钮 + 智慧诊断入口;空态占位。路由 /dashboard/home(菜单 /aidop/smart-ops/grid)。",
- "全屏模式:隐藏导航的大屏布局,含退出全屏按钮。"],
- "dds_handle": ("筛选上下文", "按模块聚合 L1 指标与达标状态→渲染格子卡片", "九宫格总览与预警", "口径以 KPI Master 为准;租户隔离;无数据显示空态", "日批未产出时展示上期或空态"),
- },
- ("S9", "REQ-S9-004"): {
- "module_code": "S9-M02",
- "menu_path": "左侧菜单 → MDIOP → 智慧运营看板 → S9看板",
- "overview": "S9 全场关键指标看板以动态看板呈现全场 L1/L2 指标卡与趋势图,支持按时间、组织等条件筛选,支持指标下钻与智慧诊断联动,是九宫格的全场关键指标页。",
- "roles_short": "管理层、部门业务人员、运营专员",
- "steps_txt": [
- "步骤1:从菜单“智慧运营看板 → S9看板”进入(或从九宫格 S9 格子点击进入)。",
- "步骤2:查看顶部 L1 指标卡区:当前值、目标值、达成状态(红黄绿)。",
- "步骤3:查看趋势图区,观察指标近周期走势。",
- "步骤4:调整时间、组织等筛选条件,指标卡与趋势图联动刷新。",
- "步骤5:点击未达标指标卡查看下钻指标(L2/L3);点击“智慧诊断”按钮跳转诊断分析。",
- ],
- "steps_tbl": [("1", "打开 S9 看板", "菜单或九宫格 S9 格子进入"),
- ("2", "查看 L1 指标卡", "当前/目标/达成状态"),
- ("3", "查看趋势", "近周期走势对比"),
- ("4", "条件筛选", "时间/组织等条件联动刷新"),
- ("5", "下钻与诊断", "L2/L3 下钻;跳转智慧诊断")],
- "shots": [("shot_s9_board.png", "S9 全场关键指标看板")],
- "notes": ["看板数据来自指标层日批计算(T+1),当日展示截至昨日的结果。",
- "筛选条件变化时,指标卡、趋势图与下钻上下文保持一致。",
- "下钻受数据权限约束,无权限维度不展示明细。"],
- "faq": [("为什么今天上午看不到最新数据?", "指标为每日批处理计算,上午展示的是截至昨日的日批结果;如需确认计算状态请联系运维查看指标计算运行日志。")],
- "situations": [("指标达成跟踪", "按周期查看全场 L1 指标达成与趋势"),
- ("偏差分析", "点击未达标指标查看偏差并跳转诊断"),
- ("自助查询", "按时间/组织/产品筛选观察波动")],
- "perm_rows": [("管理层", "看板只读"),
- ("部门业务人员", "本部门相关指标查看与下钻"),
- ("运营专员", "筛选、下钻与诊断联动")],
- "if_rows": [("dashboard-page 接口", "看板页面配置与数据", "页面加载/筛选刷新"),
- ("module-detail 接口", "模块详情指标数据", "下钻触发"),
- ("smart-diagnosis 接口", "未达标指标诊断联动", "点击触发")],
- "rpt_rows": [("全场指标视图", "L1/L2 指标与趋势", "看板页即时报表,可扩展导出")],
- "dds_page": ["S9 看板页:筛选区(时间/组织等)+ L1 指标卡区(当前/目标/状态)+ 趋势图区 + 下钻卡片区(L2/L3)+ 全屏与智慧诊断按钮。路由 /aidop/smart-ops/s9(动态看板 DynamicModuleDashboard 渲染)。"],
- "dds_handle": ("筛选条件/页面配置", "按页面配置装配部件→聚合指标日结果→渲染卡片与趋势", "全场指标看板视图", "展示口径不得与 KPI Master 冲突;下钻受数据权限约束", "无数据部件空态提示"),
- },
- ("运营诊断", "REQ-S9-006"): {
- "module_code": "OD-M01",
- "menu_path": "左侧菜单 → MDIOP → 智慧诊断(也可从九宫格/看板未达标指标点击进入)",
- "overview": "智慧诊断对未达标指标开展环节级诊断:以订单为主线串联各业务节点,通过诊断闭环卡、目标&现状、主要问题与环节矩阵定位异常,支持按订单、物料、供应商、产线、仓库、时间段、人员七类维度下钻根因,并可一键转改善闭环。",
- "roles_short": "运营专员执行诊断;管理层只读;责任部门配合举证",
- "steps_txt": [
- "步骤1:从九宫格/看板的未达标指标点击进入智慧诊断(或从菜单“智慧诊断”进入),系统带入指标与筛选上下文。",
- "步骤2:查看诊断闭环卡与“目标&现状”区,确认指标目标值与当前实际值的差距。",
- "步骤3:在“主要问题”区点击问题条目,下钻查看 L3/L4 证据明细(订单/物料/供应商等维度)。",
- "步骤4:查看环节矩阵,定位断点、滞后、损耗等异常发生的业务环节。",
- "步骤5:确认诊断结论后,点击“生成改善计划”将问题转入改善闭环(功能编号 FUNC-S9-006)。",
- ],
- "steps_tbl": [("1", "进入诊断", "看板未达标项带入上下文,菜单亦可直接进入"),
- ("2", "查看目标&现状", "目标值与实际值对比,确认差距"),
- ("3", "问题下钻", "按七类维度查看证据明细"),
- ("4", "环节矩阵", "定位异常业务环节"),
- ("5", "转改善", "生成改善计划进入闭环")],
- "shots": [("shot_od_main.png", "智慧诊断主页(诊断闭环与目标&现状)"), ("shot_od_drill.png", "主要问题下钻与环节矩阵")],
- "notes": ["诊断结论以对接数据就绪为前提;第三方数据延迟不计入本系统缺陷。",
- "下钻维度取决于主数据与明细接通程度,未接通维度不展示。",
- "无异常期间诊断页显示良好态或空问题列表,不报错。"],
- "faq": [("诊断页没有数据怎么办?", "确认对应模块已有指标日批结果,且当前筛选期间存在未达标项;两者都满足仍无数据时请联系运维检查诊断作业。")],
- "situations": [("看板下钻诊断", "未达标指标一键带入诊断,保留筛选上下文"),
- ("七维根因溯源", "按订单/物料/供应商/产线/仓库/时间段/人员下钻证据"),
- ("转改善闭环", "主要问题确认后生成改善计划,功能并入 FUNC-S9-006")],
- "perm_rows": [("运营专员", "诊断执行、下钻与转改善"),
- ("管理层", "诊断结论只读"),
- ("责任部门", "证据配合查看")],
- "if_rows": [("smart-diagnosis 接口", "诊断主页数据(环节矩阵/目标现状/主要问题)", "页面加载"),
- ("evidence 接口", "主要问题证据明细", "下钻触发"),
- ("createFromDiagnosis 接口", "生成改善计划", "点击触发")],
- "rpt_rows": [("运营诊断报告摘要", "结论、根因与建议", "页面展示;正式报告导出为后续扩展")],
- "dds_page": ["智慧诊断主页:诊断闭环卡(识别/下钻/结论/转改善四卡)+ 目标&现状区 + 主要问题列表 + 环节矩阵。路由 /aidop/smart-diagnosis。",
- "下钻区:主要问题 → L3/L4 证据明细(维度筛选);转改善入口。"],
- "dds_handle": ("指标上下文/筛选条件", "环节规则识别→目标现状对比→主要问题装配→证据下钻", "诊断结论与问题清单", "结论可追溯订单主线或指标编码;支持七维下钻", "数据未就绪时良好态/空态提示"),
- },
- ("运营改善", "REQ-S9-007"): {
- "module_code": "OI-M01",
- "menu_path": "左侧菜单 → MDIOP → 智慧诊断(改善闭环区);台账查询:MDIOP → 智慧运营看板 → 改善计划台账",
- "overview": "改善计划与效果验证承接诊断输出的问题建档,完成整改派单(平台审批流)、行动项过程跟踪与有效性验证(改善前后指标对比),并提供改善计划台账集中查询全部计划。",
- "roles_short": "运营专员建档与复盘;责任人执行;审批人派单审批;管理层只读",
- "steps_txt": [
- "步骤1:在智慧诊断“主要问题”区点击“生成改善计划”,系统带入问题上下文完成建档。",
- "步骤2:填写根因、行动项、责任人与计划完成日期,保存改善计划。",
- "步骤3:点击“提交审批”,改善单进入审批中心待办,由审批人完成派单审批。",
- "步骤4:审批通过后开始执行,责任人定期更新行动项状态,运营专员过程跟踪。",
- "步骤5:到期打开“有效性验证”,对比基线值与当前 KPI,填写验证结论并提交,确认闭环或继续跟踪。",
- "步骤6:进入“改善计划台账”页,按状态、责任人、模块等条件筛选,集中跟踪全部改善计划。",
- ],
- "steps_tbl": [("1", "问题建档", "由诊断主要问题生成改善计划"),
- ("2", "填写计划", "根因/行动项/责任人/完成日"),
- ("3", "提交审批", "审批中心待办,状态回写"),
- ("4", "执行跟踪", "行动项状态更新与日志"),
- ("5", "效果验证", "基线与当前 KPI 对比,提交结论"),
- ("6", "台账查询", "多条件筛选集中跟踪")],
- "shots": [("shot_od_main.png", "智慧诊断改善闭环区"), ("shot_oi_plans.png", "改善计划台账页面")],
- "notes": ["改善单必须关联诊断问题或指标,保证端到端追溯。",
- "责任人或计划完成日缺失时无法保存(必填校验)。",
- "验证结论保留基线值、目标值与验证值,提交后不可随意篡改。"],
- "faq": [("改善计划台账在哪里?", "左侧菜单 → MDIOP → 智慧运营看板 → 改善计划台账,可按状态、责任人、模块等条件筛选查询。")],
- "situations": [("诊断转改善", "主要问题一键建档,保留诊断上下文"),
- ("审批派单", "提交平台审批流,审批人待办处理"),
- ("效果复盘", "验证仪表对比改善前后指标,量化结论闭环")],
- "perm_rows": [("运营专员", "建档、提交审批、验证与复盘"),
- ("责任人", "行动项执行与状态更新"),
- ("审批人", "派单审批"),
- ("管理层", "台账只读")],
- "if_rows": [("改善计划 API", "建档/台账/详情/状态流转", "页面触发"),
- ("平台审批流", "派单审批待办", "提交触发"),
- ("KPI 对比查询", "验证仪表基线与当前值", "验证触发")],
- "rpt_rows": [("改善任务清单", "全部计划与状态", "台账页查询,可扩展导出"),
- ("成效对比", "改善前后指标对比", "验证仪表视图")],
- "dds_page": ["诊断闭环区:主要问题 → 生成改善计划表单(根因/行动项/责任人/完成日)→ 提交审批 → 有效性验证仪表(基线/当前对比)。",
- "改善计划台账页:筛选区(状态/责任人/模块/到期区间)+ 计划列表(计划单号、问题、责任人、状态、完成日、验证结论)。路由 /aidop/smart-ops/improvement-plans。"],
- "dds_handle": ("诊断问题上下文", "建档→行动项装配→审批派单→执行跟踪→验证对比→闭环", "改善计划全生命周期状态", "必须关联诊断/指标;必填校验;验证证据保留", "无诊断上下文或必填缺失时拒绝保存"),
- },
- ("ChatBI", "REQ-S9-009"): {
- "module_code": "CBI-M01",
- "menu_path": "九宫格 / 模块看板页面右下角“MDIOP CHATBI”浮窗",
- "overview": "ChatBI 智能问答嵌入九宫格与模块看板,用户以自然语言提问运营指标,系统返回结论、证据、可能原因与下一步建议,并展示相关指标卡,可直接跳转看板或智慧诊断。",
- "roles_short": "管理层、运营专员",
- "steps_txt": [
- "步骤1:打开九宫格或任一模块看板页面。",
- "步骤2:点击页面右下角“MDIOP CHATBI”浮窗,打开问答面板。",
- "步骤3:在输入框输入自然语言问题(如“本周 OTD 怎么样”),或点选面板提供的建议问题。",
- "步骤4:查看结构化回答:结论、证据、可能原因、下一步建议,以及相关指标卡。",
- "步骤5:点击回答中的跳转按钮,进入对应看板或智慧诊断继续分析;也可继续追问。",
- ],
- "steps_tbl": [("1", "打开问答浮窗", "九宫格/看板右下角入口"),
- ("2", "提问", "自然语言输入或点选建议问题"),
- ("3", "查看回答", "结论/证据/原因/建议 + 指标卡"),
- ("4", "跳转联动", "一键进入看板或智慧诊断")],
- "shots": [("shot_cb_widget.png", "ChatBI 问答浮窗"), ("shot_cb_answer.png", "ChatBI 结构化回答")],
- "notes": ["问答只解释已发布运营指标,不改写业务单据。",
- "提问与结果受当前租户与数据权限约束。",
- "智能服务不可用时回退本地模板答案,回答中标注来源(local/deepseek)。"],
- "faq": [("回答显示 local 来源是什么意思?", "表示智能服务(DeepSeek)不可用,系统回退本地模板生成答案;结论基于已发布指标计算,仍可参考。")],
- "situations": [("看数问答", "针对当前看板模块提问指标达成与波动"),
- ("追问分析", "按建议问题连续追问,逐步深入"),
- ("跳转闭环", "从回答跳转看板核实或进入诊断分析")],
- "perm_rows": [("管理层", "问答使用"),
- ("运营专员", "问答使用与跳转联动")],
- "if_rows": [("ChatBI ask 接口", "自然语言问数聚合作答", "提问触发")],
- "rpt_rows": [("问答结论与指标卡", "结构化回答内容", "浮窗即时展示")],
- "dds_page": ["ChatBI 浮窗:问答面板(输入框 + 建议问题 + 回答区);回答区为四段式结构(结论/证据/原因/下一步)+ 指标卡 + 跳转按钮。嵌入九宫格与模块看板。"],
- "dds_handle": ("问题文本+模块上下文", "意图解析→指标聚合→答案组装→(可选)LLM 润色", "结构化回答与指标卡", "仅解释已发布指标;租户与数据权限约束;不落库", "服务不可用回退本地模板(isFallback)"),
- },
- }
- # 模块总体流程链(与 _gen_flow_diagrams.OVERALL 一致,用于 BBP 1.2 图后文字)
- OVERALL_FLOW = {
- "系统集成": ["第三方系统(ERP/MES/WMS)", "数据源登记/标准API推数(方式丙)", "同步任务执行与清洗标准化", "贴源/标准/指标层入仓", "业务模块与看板消费", "出站回写第三方系统"],
- "S9": ["运营指标主数据", "指标层日批计算", "九宫格总览(红黄绿预警)", "格子下钻模块看板", "联动智慧诊断"],
- "运营诊断": ["看板未达标指标", "智慧诊断环节识别", "七维下钻根因溯源", "诊断结论与报告", "转改善闭环"],
- "运营改善": ["诊断问题建档", "审批派单到责任人", "行动项执行跟踪", "有效性验证(前后对比)", "复盘闭环与经验固化"],
- "ChatBI": ["看板/九宫格上下文", "自然语言提问", "意图解析与指标聚合", "结论与建议输出", "跳转看板或诊断"],
- }
- def live_features(mod):
- return [f for f in mod["features"] if f.get("impl_status") != "未实现"]
- def flow_img(mod_key, feat=None):
- prefix = FLOW_PREFIX[mod_key]
- if feat is None:
- return FLOWS / f"{prefix}_overall.png"
- return FLOWS / f"{prefix}_{feat['func'].lower().replace('-', '_')}.png"
- def shot_img(name):
- return SHOTS / name
- # ─────────────────────────────────────────────────────────────
- # BRD:业务需求描述(S1 风格)
- # ─────────────────────────────────────────────────────────────
- def write_brd(mod_key: str, mod: dict, out_path: Path):
- doc = new_doc("brd")
- meta = MODULE_META[mod_key]
- ver = doc_version(mod_key, "brd")
- # 封面(S1 BRD:28pt 模块名 / 22pt 文档类型 / 13pt 系统名 + 文档编号表)
- cover_gap(doc, 3)
- para(doc, mod["module_title"], size=28, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- para(doc, "业务需求描述", size=22, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- para(doc, SYSTEM_NAME, size=13, align=WD_ALIGN_PARAGRAPH.CENTER)
- cover_gap(doc, 1)
- kv_table(doc, [("文档编号", mod["doc_no_brd"]), ("版本", ver), ("密级", "内部"),
- ("编制单位", AUTHOR), ("编制日期", TODAY_ISO)])
- front_matter(doc, version_rows=version_rows(mod_key, "brd"))
- # 范围说明
- h2(doc, "范围说明")
- para(doc, f"本文件描述「{mod['module_title']}」业务需求,系统名称为 {SYSTEM_NAME}。")
- para(doc, f"报价范围对齐:{mod['quote_scope']}。")
- para(doc, "需求与功能要求以项目合同里的技术规范对应章节为准,并与报价单、三联对照表一致;不得偏离技术规范已列明的能力边界。")
- para(doc, "需求编号格式 REQ-S9-nnn;与功能编号、测试编号通过三联对照表串联。")
- if mod.get("intro"):
- para(doc, mod["intro"])
- if mod_key == "ChatBI":
- para(doc, "说明:ChatBI 报表与历史(NL2SQL 报表、查询历史、语义模型配置)为技术规范 2.6.4 目标态能力,当前版本未上线,不纳入本期需求范围;上线后另行补充需求与验收。")
- for i, feat in enumerate(live_features(mod), 1):
- h2(doc, f"({CN_NUM[i]}){feat['name']}({feat['req']})")
- h3(doc, "功能说明")
- if feat.get("tech_clause"):
- para(doc, f"本功能对应{feat['tech_clause']}。")
- for t in feat["func_desc"]:
- para(doc, t)
- h3(doc, "业务描述")
- for t in feat["biz_desc"]:
- para(doc, t)
- para(doc, f"对应功能编号:{feat['func']};系统路径:{feat['path']}。", bold=True)
- out_path.parent.mkdir(parents=True, exist_ok=True)
- doc.save(out_path)
- print("BRD", out_path.name)
- # ─────────────────────────────────────────────────────────────
- # BBP:蓝图设计方案(S1 风格)
- # ─────────────────────────────────────────────────────────────
- def write_bbp(mod_key: str, mod: dict, out_path: Path):
- doc = new_doc("bbp")
- meta = MODULE_META[mod_key]
- ver = doc_version(mod_key, "bbp")
- # 封面(S1 BBP:26pt 模块名 / 26pt 文档类型 / 14pt 系统名 / 11pt 版本行)
- cover_gap(doc, 3)
- para(doc, mod["module_title"], size=26, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- para(doc, "蓝图设计方案", size=26, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- para(doc, SYSTEM_NAME, size=14, align=WD_ALIGN_PARAGRAPH.CENTER)
- para(doc, f"版本:{ver} 日期:{TODAY_CN} 作者:{AUTHOR}", size=11, align=WD_ALIGN_PARAGRAPH.CENTER)
- front_matter(doc, version_rows=version_rows(mod_key, "bbp"), bbp_style=True)
- # 1 总体业务方案
- h1(doc, "1 总体业务方案")
- h2(doc, "1.1 目标和宗旨")
- para(doc, f"落实报价范围「{mod['quote_scope']}」,并将项目合同里的技术规范中对应功能要求转化为可配置、可验收的功能方案。")
- if mod.get("intro"):
- para(doc, mod["intro"])
- for t in mod.get("tech_spec", [])[:4]:
- if mod.get("intro") and t == mod["intro"]:
- continue
- para(doc, t)
- h2(doc, "1.2 总体业务流程图")
- para(doc, meta["bbp_overall_intro"])
- img = flow_img(mod_key)
- if img.exists():
- picture(doc, img)
- para(doc, "流程路径:" + " → ".join(OVERALL_FLOW[mod_key]) + "。")
- h2(doc, "1.3 方案设计")
- para(doc, meta["bbp_design"])
- for idx, feat in enumerate(live_features(mod), 2):
- enr = ENRICH[(mod_key, feat["req"])]
- h1(doc, f"{idx} {feat['name']}({feat['func']})")
- h2(doc, f"{idx}.1 目标/宗旨")
- para(doc, feat["goal"])
- if feat.get("tech_clause"):
- para(doc, f"规范追溯:{feat['tech_clause']}。", bold=True)
- h2(doc, f"{idx}.2 业务流程图")
- fimg = flow_img(mod_key, feat)
- if fimg.exists():
- picture(doc, fimg)
- para(doc, "流程路径:" + " → ".join(s[1] for s in feat["flow_steps"]) + "。")
- h2(doc, f"{idx}.3 业务流程说明")
- for t in feat["biz_desc"]:
- para(doc, t)
- data_table(doc, ["编号", "活动名称", "执行角色", "活动描述", "输入", "输出"],
- [(s[0], s[1], s[2], s[3], s[4], s[5]) for s in feat["flow_steps"]], size=10)
- para(doc, "")
- data_table(doc, ["序列号", "业务情形", "描述/方案"],
- [(str(i + 1), a, b) for i, (a, b) in enumerate(enr["situations"])], size=10)
- h2(doc, f"{idx}.4 业务流程规则")
- for t in feat["rules"]:
- para(doc, "• " + t)
- h2(doc, f"{idx}.5 权限管理需求")
- data_table(doc, ["序号", "岗位名称", "对应系统权限"],
- [(str(i + 1), a, b) for i, (a, b) in enumerate(enr["perm_rows"])], size=10)
- para(doc, feat["roles"])
- h2(doc, f"{idx}.6 系统接口集成")
- data_table(doc, ["序号", "接口名称", "接口说明", "频次及触发方式"],
- [(str(i + 1), a, b, c) for i, (a, b, c) in enumerate(enr["if_rows"])], size=10)
- para(doc, feat["interfaces"])
- h2(doc, f"{idx}.7 报表需求")
- data_table(doc, ["序号", "名称", "描述", "方案"],
- [(str(i + 1), a, b, c) for i, (a, b, c) in enumerate(enr["rpt_rows"])], size=10)
- para(doc, feat["reports"])
- para(doc, f"对应需求:{feat['req']};路由:{feat['route']}。", bold=True)
- out_path.parent.mkdir(parents=True, exist_ok=True)
- doc.save(out_path)
- print("BBP", out_path.name)
- # ─────────────────────────────────────────────────────────────
- # DDS:详细设计说明书(S1 风格)
- # ─────────────────────────────────────────────────────────────
- TECH_STACK = [("前端", "Vue 3 + Vite + TypeScript + Element Plus", "3.x", "用户界面与交互"),
- ("后端", ".NET 10 + Admin.NET (Furion + SqlSugar)", "10.0", "业务逻辑与 API 服务"),
- ("数据存储", "MySQL", "8.0", "业务数据与中台数据"),
- ("基础设施", "Docker + Nginx", "—", "容器化部署与反向代理")]
- # 核心表字段结构(DDS 4.3):表名 -> (中文名, [(字段, 类型, 说明)])
- CORE_TABLE_COLS = {
- "mdp_sync_task": ("MDP 同步任务业务配置", [
- ("id", "bigint", "主键"), ("tenant_id", "bigint", "租户"),
- ("task_code", "varchar(100)", "任务编码"), ("task_name", "varchar(200)", "任务名称"),
- ("task_type", "varchar(40)", "任务类型(默认 SERVICE_SYNC)"),
- ("business_domain_code", "varchar(100)", "业务域编码"),
- ("consumer_modules", "varchar(500)", "消费模块清单"),
- ("source_system_code", "varchar(100)", "来源系统编码"),
- ("service_key", "varchar(100)", "服务键"), ("job_code", "varchar(100)", "作业编码"),
- ("schedule_job_id", "varchar(100)", "调度作业 Id"),
- ("status", "int", "状态(1 启用)"), ("owner_role", "varchar(100)", "责任角色"),
- ("config_version", "int", "配置版本"), ("description", "varchar(1000)", "描述"),
- ("create_time", "datetime", "创建时间"), ("update_time", "datetime", "更新时间")]),
- "mdp_inbound_request": ("方式丙入站请求台账", [
- ("id", "bigint", "主键"), ("tenant_id", "bigint", "租户"),
- ("access_key", "varchar(64)", "入站授权标识"),
- ("entity_code", "varchar(100)", "对接实体编码"),
- ("idempotency_key", "varchar(128)", "幂等键"),
- ("request_hash", "varchar(64)", "请求报文哈希"),
- ("sync_batch_id", "varchar(64)", "同步批次号"),
- ("snapshot_id", "varchar(64)", "快照号(全量场景)"),
- ("status", "varchar(16)", "状态(RECEIVED 等)"),
- ("http_status", "int", "响应 HTTP 状态"), ("accepted", "int", "接收条数"),
- ("rejected", "int", "拒绝条数"), ("receipt_json", "mediumtext", "回执报文"),
- ("client_ip", "varchar(64)", "调用方 IP"), ("elapsed_ms", "int", "处理耗时(毫秒)"),
- ("create_time", "datetime", "创建时间"), ("update_time", "datetime", "更新时间")]),
- "mdp_outbox": ("MDP 出站回写 Outbox(幂等待推表)", [
- ("id", "bigint", "主键"), ("tenant_id", "bigint", "租户"),
- ("target_source_code", "varchar(100)", "目标数据源编码"),
- ("action_code", "varchar(100)", "回写动作编码"),
- ("idem_key", "varchar(200)", "幂等键"),
- ("payload_json", "text", "回写报文"),
- ("status", "int", "状态:0 待推 1 成功 2 失败"),
- ("retry_count", "int", "已重试次数"),
- ("next_retry_time", "datetime", "下次可推时间(退避策略)"),
- ("last_error_code", "varchar(64)", "最近错误码"),
- ("response_json", "text", "目标系统回执"), ("error_msg", "varchar(1000)", "错误信息"),
- ("create_time", "datetime", "创建时间"), ("update_time", "datetime", "更新时间")]),
- "ado_smart_ops_kpi_master": ("运营指标主数据(KPI Master)", [
- ("id", "bigint", "主键"),
- ("metric_code", "varchar(50)", "指标编码(S1_L1_001 等)"),
- ("module_code", "varchar(20)", "所属模块 S1~S9"),
- ("metric_level", "int", "层级 1=L1 … 4=L4"),
- ("parent_id", "bigint", "父指标 Id(L1 为空)"),
- ("metric_name", "varchar(200)", "指标名称"),
- ("formula", "text", "计算公式"), ("formula_expr", "varchar(500)", "结构化表达式"),
- ("data_source", "varchar(200)", "数据来源模块"),
- ("direction", "varchar(20)", "优劣方向 higher/lower_is_better"),
- ("yellow_threshold", "decimal", "黄色阈值"), ("red_threshold", "decimal", "红色阈值"),
- ("is_home_page", "bool", "是否可上九宫格首页"),
- ("is_enabled", "bool", "启用"), ("tenant_id", "bigint", "租户")]),
- "ado_smart_ops_kpi_atomic_day": ("KPI 原子聚合层(日)", [
- ("id", "bigint", "主键"), ("tenant_id", "bigint", "租户"),
- ("factory_id", "bigint", "工厂"), ("domain_code", "varchar(50)", "业务对象域"),
- ("metric_code", "varchar(50)", "指标编码"), ("metric_level", "int", "指标层级"),
- ("stat_date", "date", "统计日期"),
- ("customer_code/product_code/order_no 等", "varchar(100)", "客户/产品/订单/产线/供应商/物料/仓库/工单等维度键"),
- ("sum_value", "decimal(18,6)", "可累加值"),
- ("numerator_value", "decimal(18,6)", "比率分子"),
- ("denominator_value", "decimal(18,6)", "比率分母"),
- ("sample_count", "int", "样本数"),
- ("batch_id", "varchar(100)", "MDP 批次"), ("calc_time", "datetime", "计算时间"),
- ("grain", "varchar(20)", "统计粒度(day)")]),
- "ado_smart_ops_improvement_plan": ("智慧诊断改善计划", [
- ("id", "bigint", "主键"), ("tenant_id", "bigint", "租户"),
- ("factory_id", "bigint", "工厂"),
- ("plan_no", "varchar(64)", "计划单号"), ("module_code", "varchar(20)", "模块编码"),
- ("metric_code", "varchar(64)", "诊断根指标编码"),
- ("problem_level", "int", "问题层级"),
- ("problem_name", "varchar(200)", "问题名称"),
- ("problem_severity", "varchar(16)", "严重度 red/yellow"),
- ("target_value", "varchar(64)", "目标值"), ("actual_value", "varchar(64)", "实际值"),
- ("root_cause", "text", "根因分析"), ("action_items_json", "text", "行动项 JSON"),
- ("owner_user_id", "bigint", "责任人"), ("due_date", "datetime", "计划完成日期"),
- ("status", "varchar(32)", "状态(draft 等)"),
- ("flow_instance_id", "bigint", "审批实例 Id"),
- ("verify_result", "varchar(32)", "验证结论"), ("verify_value", "varchar(64)", "验证值"),
- ("auto_verify_result", "varchar(32)", "自动有效性结论"),
- ("auto_verify_time", "datetime", "自动评价时间")]),
- }
- def write_dds(mod_key: str, mod: dict, out_path: Path):
- doc = new_doc("dds")
- meta = MODULE_META[mod_key]
- dl = DELIVER[mod_key]
- ver = doc_version(mod_key, "dds")
- feats = live_features(mod)
- # 封面(S1 DDS:项目信息表 6 行)
- cover_gap(doc, 2)
- para(doc, mod["module_title"], size=26, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- para(doc, "详细设计说明书", size=22, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- para(doc, SYSTEM_NAME, size=14, align=WD_ALIGN_PARAGRAPH.CENTER)
- cover_gap(doc, 1)
- kv_table(doc, [("项目名称", SYSTEM_NAME), ("系统名称", dl["cover_short"]),
- ("文档版本", ver), ("文档状态", "发布"),
- ("编制单位", AUTHOR), ("编制日期", TODAY_ISO)])
- front_matter(doc, version_rows=version_rows(mod_key, "dds"))
- # 1. 文档概述
- h1(doc, "1. 文档概述")
- h2(doc, "1.1 编写目的")
- para(doc, f"本说明书描述{SYSTEM_NAME}「{dl['cover_short']}」的详细设计,包括系统总体设计、功能模块详细设计、数据库设计、接口设计与安全多租户设计,作为开发实现、测试验证与验收的技术依据。")
- h2(doc, "1.2 设计范围")
- para(doc, meta["dds_scope"])
- para(doc, f"报价范围对齐:{mod['quote_scope']}。")
- h2(doc, "1.3 术语和缩略语")
- data_table(doc, ["术语/缩写", "说明"], meta["terms"], center_cols=())
- # 2. 系统总体设计
- h1(doc, "2. 系统总体设计")
- h2(doc, "2.1 系统目标和范围")
- para(doc, f"落实报价范围「{mod['quote_scope']}」。")
- for feat in feats:
- para(doc, f"• {feat['name']}({feat['func']}):{feat['goal']}")
- h2(doc, "2.2 总体架构")
- para(doc, meta["dds_arch"])
- h2(doc, "2.3 技术栈")
- data_table(doc, ["层次", "技术/组件", "版本", "用途"], TECH_STACK, center_cols=(0, 2))
- h2(doc, "2.4 模块划分")
- data_table(doc, ["模块编号", "模块名称", "主要职责", "依赖模块"], meta["modules_tbl"], center_cols=(0,))
- # 3. 功能模块详细设计
- h1(doc, "3. 功能模块详细设计")
- h2(doc, "3.1 功能清单")
- data_table(doc, ["功能编号", "功能名称", "所属模块", "用户角色", "简要说明"],
- [(f["func"], f["name"], ENRICH[(mod_key, f["req"])]["module_code"],
- ENRICH[(mod_key, f["req"])]["roles_short"], f["goal"]) for f in feats],
- size=10, center_cols=(0, 2))
- h2(doc, "3.2 模块详细设计")
- for n, feat in enumerate(feats, 1):
- enr = ENRICH[(mod_key, feat["req"])]
- h3(doc, f"3.2.{n} {feat['name']}({enr['module_code']})")
- kv_table(doc, [("模块编号", enr["module_code"]), ("模块名称", feat["name"]),
- ("模块目标", feat["goal"]), ("对应需求", feat["req"]),
- ("功能编号", feat["func"]), ("系统路由", feat["route"])])
- para(doc, "")
- h3(doc, f"3.2.{n}.1 业务流程")
- para(doc, "流程路径:" + " → ".join(s[1] for s in feat["flow_steps"]) + "。")
- data_table(doc, ["编号", "活动名称", "执行角色", "活动描述", "输入", "输出"],
- [(s[0], s[1], s[2], s[3], s[4], s[5]) for s in feat["flow_steps"]], size=10)
- para(doc, "")
- h3(doc, f"3.2.{n}.2 功能处理")
- hd = enr["dds_handle"]
- data_table(doc, ["功能编号", "输入", "主要处理", "输出", "业务规则", "异常处理"],
- [(feat["func"], hd[0], hd[1], hd[2], hd[3], hd[4])], size=10, center_cols=(0,))
- para(doc, "")
- h3(doc, f"3.2.{n}.3 页面设计")
- for t in enr["dds_page"]:
- para(doc, t)
- h3(doc, f"3.2.{n}.4 设计验证要点")
- for tc in feat["tcs"]:
- para(doc, f"• [{tc[1]}] {tc[3]}:{tc[5]}")
- # 4. 数据库设计
- h1(doc, "4. 数据库设计")
- h2(doc, "4.1 数据库说明")
- para(doc, meta["db_intro"])
- h2(doc, "4.2 数据表清单")
- data_table(doc, ["序号", "表名", "说明", "核心内容"],
- [(str(i + 1), a, b, c) for i, (a, b, c) in enumerate(meta["db_tables"])],
- size=10, center_cols=(0,))
- h2(doc, "4.3 表结构设计")
- if meta["db_core"]:
- for tname in meta["db_core"]:
- cn, cols = CORE_TABLE_COLS[tname]
- para(doc, f"表 {tname}({cn})", bold=True)
- data_table(doc, ["字段", "类型", "说明"], cols, size=10, center_cols=())
- para(doc, "")
- else:
- para(doc, meta["db_rel"])
- h2(doc, "4.4 表关系和索引")
- para(doc, meta["db_rel"])
- # 5. 接口设计
- h1(doc, "5. 接口设计")
- h2(doc, "5.1 接口清单")
- data_table(doc, ["序号", "方式", "接口路径", "说明"],
- [(str(i + 1), a, b, c) for i, (a, b, c) in enumerate(meta["if_list"])],
- size=10, center_cols=(0, 1))
- h2(doc, "5.2 接口详细设计")
- para(doc, meta["if_detail"])
- h2(doc, "5.3 接口时序")
- para(doc, meta["if_seq"])
- # 6. 安全与多租户设计
- h1(doc, "6. 安全与多租户设计")
- para(doc, "认证与鉴权:页面接口经平台 JWT 认证与菜单/按钮权限控制;方式丙入站接口采用 AccessKey + 签名头鉴权,不加裸授权与匿名放行。")
- para(doc, "多租户:全部业务表携带 tenant_id 并启用租户过滤器,跨租户数据不可见;九宫格、诊断、改善与看板接口按当前租户聚合。")
- para(doc, "数据安全:数据源凭据加密保存且不回显;敏感字段不落日志明文;出站回写统一经 Outbox 幂等键去重,防止重复外写。")
- # 7. 附录及变更记录
- h1(doc, "7. 附录及变更记录")
- h2(doc, "7.1 附录清单")
- para(doc, "• 《Ai-DOP第三方对接业务数据详表》:对接编码、数据包与字段映射详表。")
- para(doc, f"• 《{dl['cover_short']}业务需求描述》《{dl['cover_short']}蓝图设计方案》《{dl['cover_short']}-用户操作手册》:配套交付文档。")
- h2(doc, "7.2 变更记录")
- para(doc, "变更记录见本说明书卷首“版本记录”表。")
- h2(doc, "7.3 审批记录")
- data_table(doc, ["角色", "姓名", "签字", "日期"],
- [("编制", "", "", ""), ("审核", "", "", ""), ("批准", "", "", "")], center_cols=(0,))
- out_path.parent.mkdir(parents=True, exist_ok=True)
- doc.save(out_path)
- print("DDS", out_path.name)
- # ─────────────────────────────────────────────────────────────
- # UM:用户操作手册(S1 风格)
- # ─────────────────────────────────────────────────────────────
- def um_label(doc, text):
- """【功能概述】等粗体标签段。"""
- return para(doc, text, bold=True)
- def um_note(doc, text):
- return para(doc, text, size=10)
- def write_um(mod_key: str, mod: dict, out_path: Path):
- doc = new_doc("um")
- meta = MODULE_META[mod_key]
- dl = DELIVER[mod_key]
- ver = doc_version(mod_key, "um")
- feats = live_features(mod)
- vrows = version_rows(mod_key, "um")
- create_date = vrows[0][0]
- # 封面(S1 UM:18pt 系统名 / 24pt 模块短名 / 22pt 手册名 / 11pt 作者日期版本)
- cover_gap(doc, 3)
- para(doc, SYSTEM_NAME, size=18, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- para(doc, dl["cover_short"], size=24, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- para(doc, "用户操作手册", size=22, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- cover_gap(doc, 2)
- para(doc, f"作 者:{AUTHOR}", size=11, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- para(doc, f"创建日期:{create_date}", size=11, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- para(doc, f"修订日期:{TODAY_ISO}", size=11, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- para(doc, f"当前版本:{ver}", size=11, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
- front_matter(doc, version_rows=vrows)
- # 1. 系统登录与首页
- h1(doc, "1. 系统登录与首页")
- para(doc, "本章说明登录系统、首页布局、修改密码与退出系统的通用操作;进入本模块后的功能操作见第 2 章。")
- h2(doc, "1.1 登录系统")
- para(doc, "步骤1:打开浏览器,在地址栏输入系统URL。", bold=True)
- para(doc, "步骤2:输入用户名和密码,点击“登录”按钮进入系统。", bold=True)
- para(doc, "步骤3:如忘记密码,请联系系统管理员重置。", bold=True)
- um_note(doc, "【说明】系统支持Chrome、Edge、Firefox等主流浏览器,推荐使用Chrome最新版本。")
- img = shot_img("shot_login.png")
- if img.exists():
- picture(doc, img)
- caption(doc, "【图1.1 系统登录页面】")
- h2(doc, "1.2 系统首页")
- para(doc, "登录成功后进入系统首页(默认为九宫格智慧运营看板),页面主要包含以下区域:")
- para(doc, " ● 顶部导航栏:显示系统LOGO、当前模块菜单、全屏切换等")
- para(doc, " ● 左侧菜单栏:按模块分组展示功能菜单(MDIOP 分组),点击展开/折叠")
- para(doc, " ● 右侧工作区:显示当前选中功能页面的内容")
- para(doc, " ● 右上角用户区:显示当前登录用户信息,下拉菜单含个人中心、修改密码、退出登录")
- img = shot_img("shot_home.png")
- if img.exists():
- picture(doc, img)
- caption(doc, "【图1.2 系统首页布局】")
- h2(doc, "1.3 修改密码")
- para(doc, "步骤1:点击页面右上角用户头像/用户名区域。", bold=True)
- para(doc, "步骤2:在下拉菜单中选择“个人中心”。", bold=True)
- para(doc, "步骤3:点击“修改密码”标签页。", bold=True)
- para(doc, "步骤4:输入旧密码、新密码并确认,点击“保存”。", bold=True)
- um_note(doc, "【注意】密码长度不少于6位,建议使用字母+数字+特殊字符组合。")
- img = shot_img("shot_password.png")
- if img.exists():
- picture(doc, img)
- caption(doc, "【图1.3 修改密码页面】")
- h2(doc, "1.4 退出系统")
- para(doc, "步骤1:点击右上角用户头像/用户名。", bold=True)
- para(doc, "步骤2:在下拉菜单中选择“退出系统”。", bold=True)
- um_note(doc, "【说明】为保障数据安全,长时间不操作系统将自动退出登录。")
- # 2. 模块操作说明
- h1(doc, "2. 模块操作说明")
- para(doc, meta["um_intro"])
- h2(doc, "2.1 通用操作说明")
- para(doc, "录入窗口中红色星号为必填项,未填时保存会提示,不会生成不完整单据。")
- para(doc, "列表底部显示总条数,可翻页或切换每页条数;操作列按行提供查看或编辑入口。")
- para(doc, "在查询区填写条件后点查询筛选数据,点重置清空条件并回到默认结果。")
- for n, feat in enumerate(feats, 2):
- enr = ENRICH[(mod_key, feat["req"])]
- h2(doc, f"2.{n} {feat['name']}")
- um_label(doc, "【功能概述】")
- para(doc, enr["overview"])
- um_label(doc, "【适用角色】")
- para(doc, enr["roles_short"])
- um_label(doc, "【菜单路径】")
- para(doc, enr["menu_path"])
- um_label(doc, "【操作步骤】")
- for s in enr["steps_txt"]:
- para(doc, s, bold=True)
- para(doc, "")
- data_table(doc, ["步骤", "操作", "说明"], enr["steps_tbl"], size=10, center_cols=(0,))
- para(doc, "")
- for si, (shot, cap) in enumerate(enr["shots"], 1):
- img = shot_img(shot)
- if img.exists():
- picture(doc, img)
- caption(doc, f"【图2.{n}.{si} {cap}】")
- um_label(doc, "【注意事项】")
- for note in enr["notes"]:
- um_note(doc, "【注意】" + note)
- um_label(doc, "【常见问题】")
- for q, a in enr["faq"]:
- para(doc, "Q: " + q, size=10, bold=True)
- para(doc, "A: " + a, size=10)
- out_path.parent.mkdir(parents=True, exist_ok=True)
- doc.save(out_path)
- print("UM ", out_path.name)
- # ─────────────────────────────────────────────────────────────
- # 编排:生成 / 部署
- # ─────────────────────────────────────────────────────────────
- def generate_all(out_dir: Path):
- out_dir.mkdir(parents=True, exist_ok=True)
- for mod_key, mod in MODULES.items():
- files = DELIVER[mod_key]["files"]
- write_brd(mod_key, mod, out_dir / files["brd"])
- write_bbp(mod_key, mod, out_dir / files["bbp"])
- write_dds(mod_key, mod, out_dir / files["dds"])
- write_um(mod_key, mod, out_dir / files["um"])
- def deploy():
- BACKUP.mkdir(parents=True, exist_ok=True)
- for mod_key, dl in DELIVER.items():
- for old in dl["old"]:
- src = PENDING / old
- if src.exists():
- dst = BACKUP / old
- if dst.exists():
- dst.unlink()
- shutil.move(str(src), str(dst))
- print("BAK", old)
- for mod_key, dl in DELIVER.items():
- for kind, fname in dl["files"].items():
- src = OUT / fname
- shutil.copy2(src, PENDING / fname)
- print("DEP", fname)
- def main():
- do_deploy = len(sys.argv) > 1 and sys.argv[1] == "deploy"
- generate_all(OUT)
- if do_deploy:
- deploy()
- print("DONE", "deploy" if do_deploy else "gen")
- if __name__ == "__main__":
- main()
|