_gen_s1style_delivery.py 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338
  1. # -*- coding: utf-8 -*-
  2. """S1 风格四合一交付文档生成器(BRD / BBP / DDS / UM)。
  3. 以 S1 模块四份文档为模板底(复制后清空正文,保留 styles.xml 与页面设置),
  4. 按 S1 实测版式重写全部内容:
  5. - BRD:封面 28/22/13 + 文档编号表;H2 范围说明 + H2(一)功能名(REQ-xxx)+ H3 功能说明/业务描述
  6. - BBP:封面 26/26/14 + 版本行;H1「N 功能名(FUNC-xxx)」+ 7 子节 + 流程图 + 活动/情形/权限/接口/报表五表
  7. - DDS:封面项目信息表;1.文档概述/2.总体设计/3.功能详设/4.数据库/5.接口/6.安全多租户/7.附录
  8. - UM :封面 18/24/22 + 作者日期版本行;1.系统登录与首页 + 2.模块操作说明(步骤表+截图+注意+FAQ)
  9. 数据源:_gen_s9_modules_data.MODULES(功能/流程/规则/角色/接口/报表/TC)+ 本文件 ENRICH(UM步骤、BBP表格行、DDS设计细节)。
  10. 用法:
  11. python _gen_s1style_delivery.py gen # 生成到 doc/_tmp_docx_out/s1style/
  12. python _gen_s1style_delivery.py deploy # 生成并部署到待确认目录(旧版移入 _backup_20260915_pre_s1style)
  13. """
  14. from __future__ import annotations
  15. import shutil
  16. import sys
  17. from pathlib import Path
  18. from docx import Document
  19. from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_BREAK
  20. from docx.oxml import OxmlElement
  21. from docx.oxml.ns import qn
  22. from docx.shared import Cm, Pt, RGBColor
  23. HERE = Path(__file__).resolve().parent
  24. sys.path.insert(0, str(HERE))
  25. from _gen_s9_modules_data import MODULES # noqa: E402
  26. BASE = Path(r"C:\Users\skygu\OneDrive\Projects\AIDOP\项目\项目管理\产互联项目管理\交付文档\Release产互联")
  27. PENDING = BASE / "待确认"
  28. BACKUP = PENDING / "_backup_20260915_pre_s1style"
  29. OUT = HERE / "_tmp_docx_out" / "s1style"
  30. SHOTS = HERE / "_tmp_docx_out" / "shots"
  31. FLOWS = HERE / "_tmp_docx_out" / "flows"
  32. TPL = {
  33. "brd": BASE / "S1产销协同业务需求描述-V0.4.docx",
  34. "bbp": BASE / "S1产销协同模块蓝图设计方案-V2.2.docx",
  35. "dds": BASE / "S1产销协同模块详细设计说明书-V1.2.docx",
  36. "um": BASE / "S1产销协同模块用户操作手册-V1.2.docx",
  37. }
  38. FONT = "微软雅黑"
  39. HDR_FILL = "D6E3F0"
  40. CN_NUM = "零一二三四五六七八九十"
  41. TODAY_ISO = "2026-09-15"
  42. TODAY_CN = "2026年9月15日"
  43. TODAY_SLASH = "2026/09/15"
  44. SYSTEM_NAME = "Ai-DOP智慧运营管理系统"
  45. AUTHOR = "智造易项目组"
  46. FLOW_PREFIX = {"系统集成": "int", "S9": "s9", "运营诊断": "od", "运营改善": "oi", "ChatBI": "cb"}
  47. # ─────────────────────────────────────────────────────────────
  48. # 基础辅助
  49. # ─────────────────────────────────────────────────────────────
  50. def new_doc(kind: str) -> Document:
  51. """复制 S1 模板并清空正文(保留 sectPr),样式/页面设置全部继承 S1。"""
  52. OUT.mkdir(parents=True, exist_ok=True)
  53. tmp = OUT / f"_tpl_{kind}.docx"
  54. shutil.copy2(TPL[kind], tmp)
  55. doc = Document(str(tmp))
  56. body = doc.element.body
  57. for child in list(body):
  58. if child.tag == qn("w:sectPr"):
  59. continue
  60. body.remove(child)
  61. return doc
  62. def set_font(run, *, size=None, bold=None):
  63. run.font.name = FONT
  64. r_pr = run._element.get_or_add_rPr()
  65. r_fonts = r_pr.find(qn("w:rFonts"))
  66. if r_fonts is None:
  67. r_fonts = OxmlElement("w:rFonts")
  68. r_pr.insert(0, r_fonts)
  69. r_fonts.set(qn("w:ascii"), FONT)
  70. r_fonts.set(qn("w:hAnsi"), FONT)
  71. r_fonts.set(qn("w:eastAsia"), FONT)
  72. if size is not None:
  73. run.font.size = size
  74. if bold is not None:
  75. run.bold = bold
  76. def para(doc, text="", *, size=None, bold=False, align=None, style=None, space_after=None):
  77. p = doc.add_paragraph(style=style) if style else doc.add_paragraph()
  78. if align is not None:
  79. p.alignment = align
  80. if space_after is not None:
  81. p.paragraph_format.space_after = Pt(space_after)
  82. if text:
  83. run = p.add_run(text)
  84. set_font(run, size=Pt(size) if size else None, bold=bold)
  85. return p
  86. def h1(doc, text):
  87. p = doc.add_paragraph(style="Heading 1")
  88. p.add_run(text)
  89. return p
  90. def h2(doc, text):
  91. p = doc.add_paragraph(style="Heading 2")
  92. p.add_run(text)
  93. return p
  94. def h3(doc, text):
  95. p = doc.add_paragraph(style="Heading 3")
  96. p.add_run(text)
  97. return p
  98. def page_break(doc):
  99. p = doc.add_paragraph()
  100. p.add_run().add_break(WD_BREAK.PAGE)
  101. def add_toc(doc):
  102. """插入 TOC 域(Word 打开刷新后生成实际目录)。"""
  103. p = doc.add_paragraph()
  104. r = p.add_run()
  105. f1 = OxmlElement("w:fldChar")
  106. f1.set(qn("w:fldCharType"), "begin")
  107. instr = OxmlElement("w:instrText")
  108. instr.set(qn("xml:space"), "preserve")
  109. instr.text = r' TOC \o "1-3" \h \z \u '
  110. f2 = OxmlElement("w:fldChar")
  111. f2.set(qn("w:fldCharType"), "separate")
  112. t = OxmlElement("w:t")
  113. t.text = "(在 Word 中右键“更新域”生成目录)"
  114. f3 = OxmlElement("w:fldChar")
  115. f3.set(qn("w:fldCharType"), "end")
  116. r._element.append(f1)
  117. r._element.append(instr)
  118. r._element.append(f2)
  119. r._element.append(t)
  120. r2 = p.add_run()
  121. r2._element.append(f3)
  122. return p
  123. def shade(cell, fill=HDR_FILL):
  124. tc_pr = cell._element.get_or_add_tcPr()
  125. old = tc_pr.find(qn("w:shd"))
  126. if old is not None:
  127. tc_pr.remove(old)
  128. shd = OxmlElement("w:shd")
  129. shd.set(qn("w:val"), "clear")
  130. shd.set(qn("w:color"), "auto")
  131. shd.set(qn("w:fill"), fill)
  132. tc_pr.append(shd)
  133. def cell_text(cell, text, *, bold=False, center=False, size=10.5):
  134. cell.text = ""
  135. p = cell.paragraphs[0]
  136. if center:
  137. p.alignment = WD_ALIGN_PARAGRAPH.CENTER
  138. run = p.add_run(str(text))
  139. set_font(run, size=Pt(size), bold=bold)
  140. def set_table_borders(table, *, full_width=True):
  141. tbl_pr = table._element.tblPr
  142. borders = OxmlElement("w:tblBorders")
  143. for edge in ("top", "left", "bottom", "right", "insideH", "insideV"):
  144. e = OxmlElement(f"w:{edge}")
  145. e.set(qn("w:val"), "single")
  146. e.set(qn("w:sz"), "4")
  147. e.set(qn("w:color"), "000000")
  148. borders.append(e)
  149. tbl_pr.append(borders)
  150. tbl_w = tbl_pr.find(qn("w:tblW"))
  151. if tbl_w is None:
  152. tbl_w = OxmlElement("w:tblW")
  153. tbl_pr.append(tbl_w)
  154. if full_width:
  155. tbl_w.set(qn("w:w"), "5000")
  156. tbl_w.set(qn("w:type"), "pct")
  157. else:
  158. tbl_w.set(qn("w:w"), "0")
  159. tbl_w.set(qn("w:type"), "auto")
  160. def data_table(doc, headers, rows, *, size=10.5, center_cols=(0,)):
  161. """S1 风格数据表:无边框样式、手动单线边框、表头底纹 D6E3F0 加粗居中、100% 宽。"""
  162. t = doc.add_table(rows=len(rows) + 1, cols=len(headers))
  163. set_table_borders(t)
  164. for i, htxt in enumerate(headers):
  165. cell_text(t.rows[0].cells[i], htxt, bold=True, center=True, size=size)
  166. shade(t.rows[0].cells[i])
  167. for r, row in enumerate(rows, 1):
  168. for c, val in enumerate(row):
  169. cell_text(t.rows[r].cells[c], val, center=(c in center_cols), size=size)
  170. return t
  171. def kv_table(doc, pairs, *, key_fill=HDR_FILL):
  172. """封面信息表(左键右值,auto 宽)。"""
  173. t = doc.add_table(rows=len(pairs), cols=2)
  174. set_table_borders(t, full_width=False)
  175. for i, (k, v) in enumerate(pairs):
  176. cell_text(t.rows[i].cells[0], k, bold=True, center=True)
  177. cell_text(t.rows[i].cells[1], v, center=True)
  178. shade(t.rows[i].cells[0], key_fill)
  179. t.rows[i].cells[0].width = Cm(4.5)
  180. t.rows[i].cells[1].width = Cm(8.5)
  181. return t
  182. def picture(doc, img: Path, *, width_cm=15.0, center=True):
  183. p = doc.add_paragraph()
  184. if center:
  185. p.alignment = WD_ALIGN_PARAGRAPH.CENTER
  186. run = p.add_run()
  187. run.add_picture(str(img), width=Cm(width_cm))
  188. return p
  189. def caption(doc, text):
  190. return para(doc, text, size=10)
  191. def cover_gap(doc, n=3):
  192. for _ in range(n):
  193. para(doc, "")
  194. def version_table(doc, rows, *, bbp_style=False):
  195. """版本记录表。bbp_style=True 时表头为 日期|姓名|版本|变更说明(S1 BBP 风格)。"""
  196. headers = ["日期", "姓名", "版本", "变更说明"] if bbp_style else ["日期", "版本", "修订人", "变更说明"]
  197. data_rows = [(r[0], r[1], r[2], r[3]) for r in rows]
  198. return data_table(doc, headers, data_rows, center_cols=(0, 1, 2))
  199. def front_matter(doc, *, version_rows, bbp_style=False):
  200. """版本记录页 + 目录页。"""
  201. page_break(doc)
  202. para(doc, "版本记录", size=16, bold=True)
  203. version_table(doc, version_rows, bbp_style=bbp_style)
  204. page_break(doc)
  205. para(doc, "目录", size=16, bold=True)
  206. add_toc(doc)
  207. page_break(doc)
  208. # ─────────────────────────────────────────────────────────────
  209. # 版本计划(用户决策:V0.5 变更说明直接写变更内容;九宫格 DDS/UM 保持 V0.1)
  210. # ─────────────────────────────────────────────────────────────
  211. HIST_ROWS = [
  212. ("2026-07-30", "V0.1", AUTHOR, "初版建立"),
  213. ("2026-07-30", "V0.2", AUTHOR, "对齐项目合同里的技术规范需求与功能要求;统一 REQ/FUNC 编号与版式"),
  214. ("2026-09-04", "V0.3", AUTHOR, "九宫格含 S9 全场关键指标看板;数据对接服务归入系统集成"),
  215. ("2026-09-04", "V0.4", AUTHOR, "统一系统名称与文档版式,并修订范围与用词"),
  216. ]
  217. V05_DESC = {
  218. ("ChatBI", "brd"): "修订智能问答需求描述,明确报表与历史为规范目标态;统一 S1 文档版式",
  219. ("ChatBI", "bbp"): "补充智能问答业务流程图与活动、情形、权限、接口、报表设计表;统一 S1 蓝图版式",
  220. ("ChatBI", "dds"): "补问问答接口设计、壳表现状与降级处理设计;统一 S1 详设版式",
  221. ("ChatBI", "um"): "补问浮窗操作步骤、结构化回答说明与界面截图;统一 S1 手册版式",
  222. ("S9", "brd"): "修订九宫格与 S9 看板需求描述并统一 S1 文档版式",
  223. ("S9", "bbp"): "补充九宫格与 S9 看板业务流程图及活动、情形、权限、接口、报表设计表;统一 S1 蓝图版式",
  224. ("运营诊断", "brd"): "修订智慧诊断需求描述并统一 S1 文档版式",
  225. ("运营诊断", "bbp"): "补充智慧诊断业务流程图及活动、情形、权限、接口、报表设计表;统一 S1 蓝图版式",
  226. ("运营诊断", "dds"): "补充诊断 API、环节矩阵与七维下钻设计;统一 S1 详设版式",
  227. ("运营诊断", "um"): "补充诊断闭环操作步骤与界面截图;统一 S1 手册版式",
  228. ("运营改善", "brd"): "修订改善闭环需求描述并统一 S1 文档版式",
  229. ("运营改善", "bbp"): "补充改善计划台账入口、改善闭环流程图及设计表;统一 S1 蓝图版式",
  230. ("运营改善", "dds"): "补充改善计划数据表结构、审批流集成与有效性验证设计;统一 S1 详设版式",
  231. ("运营改善", "um"): "补充改善建档、审批、验证与台账查询操作说明及界面截图;统一 S1 手册版式",
  232. ("系统集成", "brd"): "补充第三方标准 API 推数入站(方式丙)需求;统一 S1 文档版式",
  233. ("系统集成", "bbp"): "补充方式丙推数入站流程、业务动作日志与出站回写队列方案及流程图;统一 S1 蓝图版式",
  234. ("系统集成", "dds"): "补充方式丙入站接口、入站台账与快照表结构、出站回写设计;统一 S1 详设版式",
  235. ("系统集成", "um"): "补充数据任务日志、业务动作日志、出站回写队列操作说明与界面截图;统一 S1 手册版式",
  236. }
  237. def version_rows(mod_key: str, kind: str):
  238. if mod_key == "S9" and kind == "dds":
  239. return [("2026-09-15", "V0.1", AUTHOR, "初版建立(补齐九宫格模块详细设计,含数据库设计与功能处理)")]
  240. if mod_key == "S9" and kind == "um":
  241. return [("2026-09-15", "V0.1", AUTHOR, "初版建立(补齐九宫格用户操作手册,含界面截图与操作步骤)")]
  242. return list(HIST_ROWS) + [("2026-09-15", "V0.5", AUTHOR, V05_DESC[(mod_key, kind)])]
  243. def doc_version(mod_key: str, kind: str) -> str:
  244. if mod_key == "S9" and kind in ("dds", "um"):
  245. return "V0.1"
  246. return "V0.5"
  247. # ─────────────────────────────────────────────────────────────
  248. # 交付清单(文件名、封面短名、文档编号、旧版文件)
  249. # ─────────────────────────────────────────────────────────────
  250. DELIVER = {
  251. "ChatBI": {
  252. "cover_short": "ChatBI智能报表",
  253. "doc_no_dds": "CBI-DDS-001", "doc_no_um": "CBI-UM-001",
  254. "files": {"brd": "ChatBI智能报表业务需求描述-V0.5.docx",
  255. "bbp": "ChatBI智能报表模块蓝图设计方案-V0.5.docx",
  256. "dds": "ChatBI智能报表模块详细设计说明书-V0.5.docx",
  257. "um": "ChatBI智能报表-用户操作手册-V0.5.docx"},
  258. "old": ["ChatBI智能报表业务需求描述-V0.4.docx", "ChatBI智能报表模块蓝图设计方案-V0.4.docx",
  259. "ChatBI智能报表模块详细设计说明书-V0.4.docx", "ChatBI智能报表-用户操作手册-V0.4.docx"],
  260. },
  261. "S9": {
  262. "cover_short": "九宫格智慧运营看板",
  263. "doc_no_dds": "S9-DDS-001", "doc_no_um": "S9-UM-001",
  264. "files": {"brd": "九宫格智慧运营看板业务需求描述-V0.5.docx",
  265. "bbp": "九宫格智慧运营看板模块蓝图设计方案-V0.5.docx",
  266. "dds": "九宫格智慧运营看板模块详细设计说明书-V0.1.docx",
  267. "um": "九宫格智慧运营看板-用户操作手册-V0.1.docx"},
  268. "old": ["九宫格智慧运营看板业务需求描述-V0.4.docx", "九宫格智慧运营看板模块蓝图设计方案-V0.4.docx",
  269. "九宫格智慧运营看板模块详细设计说明书-V0.1.docx", "九宫格智慧运营看板-用户操作手册-V0.1.docx"],
  270. },
  271. "运营诊断": {
  272. "cover_short": "运营诊断",
  273. "doc_no_dds": "OD-DDS-001", "doc_no_um": "OD-UM-001",
  274. "files": {"brd": "运营诊断业务需求描述-V0.5.docx",
  275. "bbp": "运营诊断模块蓝图设计方案-V0.5.docx",
  276. "dds": "运营诊断模块详细设计说明书-V0.5.docx",
  277. "um": "运营诊断-用户操作手册-V0.5.docx"},
  278. "old": ["运营诊断业务需求描述-V0.4.docx", "运营诊断模块蓝图设计方案-V0.4.docx",
  279. "运营诊断模块详细设计说明书-V0.4.docx", "运营诊断-用户操作手册-V0.4.docx"],
  280. },
  281. "运营改善": {
  282. "cover_short": "运营改善",
  283. "doc_no_dds": "OI-DDS-001", "doc_no_um": "OI-UM-001",
  284. "files": {"brd": "运营改善业务需求描述-V0.5.docx",
  285. "bbp": "运营改善模块蓝图设计方案-V0.5.docx",
  286. "dds": "运营改善模块详细设计说明书-V0.5.docx",
  287. "um": "运营改善-用户操作手册-V0.5.docx"},
  288. "old": ["运营改善业务需求描述-V0.5.docx", "运营改善模块蓝图设计方案-V0.5.docx",
  289. "运营改善模块详细设计说明书-V0.5.docx", "运营改善-用户操作手册-V0.5.docx"],
  290. },
  291. "系统集成": {
  292. "cover_short": "系统集成",
  293. "doc_no_dds": "INT-DDS-001", "doc_no_um": "INT-UM-001",
  294. "files": {"brd": "系统集成业务需求描述-V0.5.docx",
  295. "bbp": "系统集成模块蓝图设计方案-V0.5.docx",
  296. "dds": "系统集成模块详细设计说明书-V0.5.docx",
  297. "um": "系统集成-用户操作手册-V0.5.docx"},
  298. "old": ["系统集成业务需求描述-V0.5.docx", "系统集成模块蓝图设计方案-V0.5.docx",
  299. "系统集成模块详细设计说明书-V0.5.docx", "系统集成-用户操作手册-V0.5.docx"],
  300. },
  301. }
  302. # ─────────────────────────────────────────────────────────────
  303. # 模块级数据(UM 介绍、BBP 总体、DDS 架构/术语/数据库/接口)
  304. # ─────────────────────────────────────────────────────────────
  305. MODULE_META = {
  306. "系统集成": {
  307. "um_intro": "系统集成模块是 Ai-DOP 平台的数据底座,负责第三方系统(ERP/MES/WMS)的多模式对接采集、清洗标准化、同步监控与出站回写。本手册将指导您如何使用数据源管理、同步配置中心、日志查询与出站回写队列等功能。",
  308. "bbp_overall_intro": "系统集成模块覆盖从第三方系统接入登记、同步任务配置执行、数据清洗入仓到出站回写的全链路,下图展示了总体业务流程。",
  309. "bbp_design": "前端:Vue3 + Element Plus,数据对接服务配置与监控页面。后端:Admin.NET + 数据对接服务分层(贴源/标准/明细/指标)+ 出站回写队列;对接方式含数据库直连、HTTP API 拉取与第三方标准 API 推数入站(方式丙:签名鉴权、幂等去重、全量快照+差集、NDJSON 批量、日终对账)。",
  310. "dds_scope": "本说明书覆盖系统集成模块的第三方系统同步、日志查询、第三方系统事务三个功能的详细设计,含数据对接服务(数据源管理、同步配置中心、数据任务日志、业务动作日志、出站回写队列)与方式丙标准 API 推数入站。",
  311. "dds_arch": "系统集成采用数据对接服务分层架构:接入层(数据库直连执行器、HTTP API 拉取执行器、方式丙标准 API 推数入站)→ 贴源层 ODS → 标准层 STD → 明细层 DWD → 指标层 DWS;出站侧经 Outbox 幂等待推表统一回写第三方系统。同步任务由调度作业触发,执行结果写入数据任务日志与业务动作日志。",
  312. "terms": [("MDP", "数据对接服务(Manufacturing Data Platform),负责采集、清洗、分层入仓与回写"),
  313. ("方式丙", "第三方标准 API 推数入站:对方系统按我方标准 API 主动推送数据,含签名鉴权与幂等"),
  314. ("ODS/STD/DWD/DWS", "贴源层/标准层/明细层/指标层,数据对接服务分层模型"),
  315. ("Outbox", "出站回写幂等待推表,统一承载回写第三方系统的事务"),
  316. ("NDJSON", "逐行 JSON 批量推送格式,每行独立幂等键"),
  317. ("AccessKey", "方式丙入站授权标识,配合签名头鉴权")],
  318. "modules_tbl": [("INT-M01", "第三方系统同步", "数据源登记、同步任务配置与触发;方式丙推数入站", "数据对接服务"),
  319. ("INT-M02", "日志查询", "数据任务日志与业务动作日志的监控追溯", "INT-M01"),
  320. ("INT-M03", "第三方系统事务", "出站回写队列监控与失败容错", "INT-M01")],
  321. "db_intro": "系统集成模块数据表归属数据对接服务(mdp_*)与运行保障(ado_mdp_*),覆盖接入配置、入站台账、出站回写与文件导入四类。",
  322. "db_tables": [("mdp_source", "数据源登记", "连接类型/参数/凭据引用/状态"),
  323. ("mdp_entity", "源实体登记", "实体编码/来源对象/同步方向"),
  324. ("mdp_field_mapping", "字段映射", "源字段↔标准字段映射与转换"),
  325. ("mdp_sync_task", "同步任务业务配置", "task_code/task_type/consumer_modules/config_version"),
  326. ("mdp_sync_task_step", "任务步骤配置", "步骤顺序/执行器/参数"),
  327. ("mdp_sync_task_schedule", "任务调度配置", "定时/实时策略与调度作业关联"),
  328. ("mdp_sync_task_param", "任务参数", "参数键值"),
  329. ("mdp_sync_task_formula", "任务公式", "清洗转换公式"),
  330. ("mdp_inbound_grant", "入站对接授权", "access_key/对接编码/启用状态"),
  331. ("mdp_inbound_request", "入站请求台账", "幂等键/请求哈希/批次/回执/耗时"),
  332. ("mdp_inbound_envelope", "入站原始信封归档", "原始报文归档(mediumtext)"),
  333. ("mdp_inbound_snapshot", "全量快照登记", "快照状态 OPEN/DIFF_BLOCKED 等"),
  334. ("mdp_inbound_conflict", "入站冲突记录", "快照差集冲突明细"),
  335. ("mdp_field_map", "标准字段映射(入站)", "对外规范字段↔内部字段"),
  336. ("mdp_outbox", "出站回写 Outbox", "幂等键/报文/状态/重试/错误码"),
  337. ("mdp_file_import_batch", "文件导入批次", "批次/文件/状态"),
  338. ("mdp_file_import_row", "文件导入行", "行数据与校验结果"),
  339. ("mdp_file_import_error", "文件导入错误", "错误行与原因"),
  340. ("ado_mdp_hot_watch", "热点监听", "热表变更监听配置"),
  341. ("ado_mdp_rebuild_lock", "重建锁", "分层重建互斥锁")],
  342. "db_core": ["mdp_sync_task", "mdp_inbound_request", "mdp_outbox"],
  343. "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 索引。",
  344. "if_list": [("POST", "api/mdp/inbound/{entityCode}", "方式丙·接收推数(签名鉴权+幂等)"),
  345. ("GET", "api/mdp/inbound/{entityCode}/schema", "方式丙·对外规范字段 JSON Schema"),
  346. ("POST", "api/mdp/inbound/{entityCode}/snapshots", "方式丙·开启全量快照"),
  347. ("POST", "api/mdp/inbound/{entityCode}/snapshots/{snapshotId}/commit", "方式丙·提交快照差集"),
  348. ("POST", "api/mdp/inbound/{entityCode}/bulk", "方式丙·NDJSON 分块批量推送"),
  349. ("GET", "api/mdp/inbound/{entityCode}/digest", "方式丙·日终对账摘要"),
  350. ("GET", "api/mdp/inbound/receipts/{syncBatchId}", "方式丙·按批次查回执"),
  351. ("动态API", "api/MdpSyncTask/* 等", "数据源/同步任务/日志/队列的页面管理接口")],
  352. "if_detail": "方式丙全部端点类级启用 InboundSignature 签名鉴权(签名串 方法&路径&参数&body 摘要),未开通的对接编码一律拒绝;推数按 (access_key, entity_code, idempotency_key) 幂等去重,重复请求返回原回执;全量快照差集冲突进入 DIFF_BLOCKED,须 force 提交或人工处理;日终对账按 date 输出双方计数摘要。",
  353. "if_seq": "第三方系统 → 计算签名 → POST api/mdp/inbound/{entityCode} → 鉴权/幂等校验 → 清洗标准化 → 写入贴源/标准层 → 记录入站台账与回执 → 第三方按批次查回执与日终对账。",
  354. },
  355. "S9": {
  356. "um_intro": "九宫格智慧运营看板模块是 Ai-DOP 平台的管理层总览入口,一屏展示 S1~S9 各模块核心 KPI 与红黄绿预警,并可下钻至 S9 全场关键指标看板与智慧诊断。本手册将指导您如何使用九宫格与 S9 全场关键指标看板。",
  357. "bbp_overall_intro": "九宫格智慧运营看板覆盖从指标主数据、日批计算到总览预警、看板下钻与诊断联动的全链路,下图展示了总体业务流程。",
  358. "bbp_design": "前端:Vue3 + Element Plus;九宫格首页与动态看板(DynamicModuleDashboard)。后端:Admin.NET + 指标层日批计算(KPI 原子聚合层→维度聚合→看板配置驱动展示);与智慧诊断、ChatBI 联动。",
  359. "dds_scope": "本说明书覆盖九宫格智慧运营看板(FUNC-S9-005)与 S9 全场关键指标看板(FUNC-S9-004)两个功能的详细设计。",
  360. "dds_arch": "看板采用配置驱动架构:运营指标主数据(KPI Master)定义口径与阈值 → 指标层日批(原子聚合层→维度值日表)→ 看板页面配置(dashboard_page_config/widget)→ AidopKanban API 聚合输出 → 前端动态看板渲染。九宫格首页布局由 home_module/layout_item 驱动。",
  361. "terms": [("KPI Master", "运营指标主数据,定义指标编码、公式、层级与红黄绿阈值"),
  362. ("L1/L2/L3/L4", "指标层级,L1 为管理层核心指标,逐级下钻"),
  363. ("原子聚合层", "KPI 最小颗粒度日粒度聚合表,存可二次聚合基础量"),
  364. ("红黄绿", "达标状态:达标绿、预警黄、未达标红"),
  365. ("动态看板", "按页面配置动态渲染的模块看板(DynamicModuleDashboard)")],
  366. "modules_tbl": [("S9-M01", "九宫格智慧运营看板", "S1~S9 模块格子总览、红黄绿预警、全屏与下钻", "指标层日批"),
  367. ("S9-M02", "S9 全场关键指标看板", "全场 L1/L2 指标卡、趋势、筛选与诊断联动", "S9-M01")],
  368. "db_intro": "九宫格模块数据表归属智慧运营指标体系(ado_smart_ops_*),覆盖指标主数据、日批聚合、看板配置与业务事实四类。",
  369. "db_tables": [("ado_smart_ops_kpi_master", "运营指标主数据", "指标编码/公式/层级/红黄绿阈值"),
  370. ("ado_smart_ops_kpi_atomic_day", "KPI 原子聚合层(日)", "日粒度分子/分母/样本数等基础量"),
  371. ("ado_smart_ops_kpi_dimension_value_day", "KPI 维度值日表", "按维度聚合的日指标值"),
  372. ("ado_smart_ops_kpi_target_config", "KPI 目标配置", "目标值与生效区间"),
  373. ("ado_smart_ops_kpi_calc_config", "KPI 计算配置", "计算规则与调度"),
  374. ("ado_smart_ops_kpi_calc_run_log", "KPI 计算运行日志", "批次/耗时/结果"),
  375. ("ado_smart_ops_kpi_business_input", "KPI 业务补录", "人工补录指标数据"),
  376. ("ado_smart_ops_kpi_dimension_config", "KPI 维度配置", "维度定义与取值"),
  377. ("ado_smart_ops_home_module", "九宫格模块呈现", "模块布局 card_grid/table_list"),
  378. ("ado_smart_ops_home_layout_item", "九宫格布局项", "格子顺序与展示配置"),
  379. ("ado_smart_ops_dashboard_page_config", "看板页面配置", "页面结构与筛选项"),
  380. ("ado_smart_ops_dashboard_widget", "看板部件配置", "指标卡/趋势图等部件"),
  381. ("ado_smart_ops_business_fact", "业务事实表", "指标计算源事实")],
  382. "db_core": ["ado_smart_ops_kpi_master", "ado_smart_ops_kpi_atomic_day"],
  383. "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。",
  384. "if_list": [("GET", "api/AidopKanban/home-l1", "首页 L1 指标总览"),
  385. ("GET", "api/AidopKanban/home-grid/{moduleCode}", "九宫格模块格子数据"),
  386. ("GET", "api/AidopKanban/module-detail", "模块详情看板数据"),
  387. ("GET", "api/AidopKanban/dashboard-page", "动态看板页面配置与数据"),
  388. ("GET", "api/AidopKanban/smart-diagnosis/{moduleCode}", "智慧诊断联动入口")],
  389. "if_detail": "看板接口按租户隔离,指标值来自维度值日表与原子聚合层日批结果;筛选上下文(时间/组织/产品等)在各接口间透传,保证九宫格→看板→诊断口径一致。",
  390. "if_seq": "日批作业 → 原子聚合层/维度值日表 → 用户打开九宫格 → home-grid 聚合 → 点击格子 → dashboard-page 渲染模块看板 → 未达标项 → smart-diagnosis 联动。",
  391. },
  392. "运营诊断": {
  393. "um_intro": "运营诊断模块是 Ai-DOP 平台的智能分析入口,承接九宫格与看板未达标指标,以订单为主线开展环节级诊断、七维下钻根因溯源,并输出诊断结论转改善闭环。本手册将指导您如何使用智慧诊断功能。",
  394. "bbp_overall_intro": "运营诊断覆盖从未达标指标接入、环节识别、根因下钻到诊断报告与转改善的全链路,下图展示了总体业务流程。",
  395. "bbp_design": "前端:Vue3 + Element Plus;智慧诊断页(环节诊断矩阵、目标&现状、主要问题、下钻证据区)。后端:Admin.NET + AidopKanban 诊断 API,基于统一数据抽取能力与指标层/明细层计算;改善任务生成并入 FUNC-S9-006。",
  396. "dds_scope": "本说明书覆盖智慧诊断(FUNC-S9-006)的详细设计,含环节诊断矩阵、目标&现状、主要问题下钻与转改善入口。",
  397. "dds_arch": "智慧诊断采用指标驱动的规则诊断架构:指标层日批结果 + 明细层单据数据 → 诊断规则引擎(环节阈值/断点/滞后识别)→ 诊断结论(环节矩阵/目标&现状/主要问题)→ L3/L4 证据下钻 → 改善计划生成(AdoSmartOpsImprovementPlan API)。",
  398. "terms": [("环节矩阵", "以业务环节(订单/采购/备料/生产/入库/发运等)为行、指标为列的诊断总览"),
  399. ("七维下钻", "订单、物料、供应商、产线、仓库、时间段、人员七类根因溯源维度"),
  400. ("目标&现状", "诊断页展示指标目标值与当前实际值的对比区"),
  401. ("主要问题", "诊断输出的问题清单,可逐条下钻证据并转改善计划")],
  402. "modules_tbl": [("OD-M01", "智慧诊断", "环节异常识别、七维根因下钻、诊断结论与转改善", "九宫格/看板、指标层")],
  403. "db_intro": "智慧诊断本身不新增业务表,诊断计算直接读取九宫格指标层(ado_smart_ops_kpi_*)、明细层单据与各模块业务表;诊断产生的改善任务落库于运营改善模块表(ado_smart_ops_improvement_*)。",
  404. "db_tables": [("(读取)ado_smart_ops_kpi_dimension_value_day", "指标日结果", "诊断输入:达标状态与偏差"),
  405. ("(读取)ado_smart_ops_kpi_master", "指标主数据", "诊断输入:阈值与口径"),
  406. ("(写入)ado_smart_ops_improvement_plan", "改善计划", "转改善输出(见运营改善模块)")],
  407. "db_core": [],
  408. "db_rel": "诊断侧无独立表结构;读取侧关系见九宫格模块详细设计说明书。",
  409. "if_list": [("GET", "api/AidopKanban/smart-diagnosis/{moduleCode}", "智慧诊断主页数据(环节矩阵/目标现状/主要问题)"),
  410. ("GET", "api/AidopKanban/smart-diagnosis/{moduleCode}/evidence", "主要问题下钻证据明细"),
  411. ("POST", "api/AdoSmartOpsImprovementPlan/createFromDiagnosis", "由诊断主要问题生成改善计划")],
  412. "if_detail": "诊断接口按模块编码与筛选上下文(期间/组织等)返回环节状态、目标&现状、主要问题列表;evidence 接口按问题与维度返回单据级证据;转改善调用运营改善模块接口并回写改善计划编号。",
  413. "if_seq": "看板未达标项 → smart-diagnosis 主页 → 主要问题 → evidence 下钻明细 → 确认结论 → createFromDiagnosis 生成改善计划。",
  414. },
  415. "运营改善": {
  416. "um_intro": "运营改善模块是 Ai-DOP 平台的闭环整改入口,承接诊断输出的问题建档,完成审批派单、行动跟踪与有效性验证,并提供改善计划台账集中查询。本手册将指导您如何使用改善计划与效果验证功能。",
  417. "bbp_overall_intro": "运营改善覆盖从诊断问题建档、审批派单、行动项跟踪到效果量化复盘的全链路,下图展示了总体业务流程。",
  418. "bbp_design": "前端:Vue3 + Element Plus;智慧诊断页改善闭环区与改善计划台账页。后端:Admin.NET + AdoSmartOpsImprovementPlan API + 平台审批流;效果验证对比基线与当前 KPI 并保留验证证据。",
  419. "dds_scope": "本说明书覆盖改善计划与效果验证(REQ-S9-007,FUNC 并入 FUNC-S9-006)的详细设计,含诊断闭环建档、审批派单、行动跟踪、有效性验证与改善计划台账。",
  420. "dds_arch": "运营改善采用计划驱动的闭环架构:诊断主要问题 → 改善计划(问题建档/行动项 JSON/责任人/到期日)→ 平台审批流派单(FlowInstanceId 回写)→ 行动项执行与日志 → 有效性验证(基线/目标/验证值/自动评价)→ 闭环;台账页提供多条件集中查询。",
  421. "terms": [("改善计划", "由诊断问题建档的整改单,含根因、行动项、责任人与计划完成日"),
  422. ("行动项", "改善计划内的具体执行事项,可逐项跟踪状态"),
  423. ("有效性验证", "到期对比改善前后指标,输出验证结论(有效/部分有效/无效)"),
  424. ("改善计划台账", "全部改善计划的集中查询页,支持多条件筛选")],
  425. "modules_tbl": [("OI-M01", "改善计划与效果验证", "问题建档、审批派单、行动跟踪、效果复盘与台账查询", "运营诊断、审批流")],
  426. "db_intro": "运营改善模块数据表为 ado_smart_ops_improvement_* 系列,覆盖计划、行动项、日志、通知与验证五类。",
  427. "db_tables": [("ado_smart_ops_improvement_plan", "智慧诊断改善计划", "计划单号/问题/根因/行动项/状态/验证结论"),
  428. ("ado_smart_ops_improvement_action", "改善行动项", "行动项明细/责任人/状态"),
  429. ("ado_smart_ops_improvement_action_log", "行动项日志", "状态流转与操作留痕"),
  430. ("ado_smart_ops_improvement_action_notice", "行动项通知", "到期提醒与催办"),
  431. ("ado_smart_ops_improvement_verify_log", "有效性验证日志", "验证提交与对比证据")],
  432. "db_core": ["ado_smart_ops_improvement_plan"],
  433. "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) 建索引支撑台账筛选。",
  434. "if_list": [("POST", "api/AdoSmartOpsImprovementPlan/createFromDiagnosis", "由诊断主要问题生成改善计划"),
  435. ("POST", "api/AdoSmartOpsImprovementPlan/page", "改善计划台账分页查询"),
  436. ("GET", "api/AdoSmartOpsImprovementPlan/detail", "改善计划详情"),
  437. ("POST", "api/AdoSmartOpsImprovementPlan/submitApproval", "提交审批派单"),
  438. ("POST", "api/AdoSmartOpsImprovementPlan/startExecution", "开始执行"),
  439. ("POST", "api/AdoSmartOpsImprovementPlan/updateActionItem", "更新行动项状态"),
  440. ("GET", "api/AdoSmartOpsImprovementPlan/verificationDashboard", "有效性验证仪表(基线/当前对比)"),
  441. ("POST", "api/AdoSmartOpsImprovementPlan/submitVerification", "提交验证结论"),
  442. ("POST", "api/AdoSmartOpsImprovementPlan/close", "关闭改善计划")],
  443. "if_detail": "台账分页支持状态/责任人/模块/到期区间筛选;提交审批后写回 flow_instance_id 并进入审批中心待办;验证仪表返回基线值、目标值与当前 KPI 对比,提交验证后允许关闭或继续跟踪。",
  444. "if_seq": "诊断生成计划 → 保存行动项 → submitApproval 审批派单 → startExecution → updateActionItem 跟踪 → verificationDashboard 对比 → submitVerification → close 闭环。",
  445. },
  446. "ChatBI": {
  447. "um_intro": "ChatBI 智能报表模块是 Ai-DOP 平台的自然语言问数入口,嵌入九宫格与模块看板,以对话方式返回运营指标结论、证据与建议。本手册将指导您如何使用 ChatBI 智能问答。",
  448. "bbp_overall_intro": "ChatBI 覆盖从看板上下文、自然语言提问、意图解析与指标聚合到结论输出与看板/诊断跳转的链路,下图展示了总体业务流程。",
  449. "bbp_design": "前端:Vue3 + Element Plus;看板内 ChatBI 浮窗。后端:ChatBIController + ChatBIService,意图解析后按当前模块聚合已发布运营指标作答,DeepSeek 可用时润色,不可用时回退本地模板答案。",
  450. "dds_scope": "本说明书覆盖 ChatBI 智能问答(FUNC-S9-007)的详细设计;报表与历史(NL2SQL/查询历史)为规范目标态,当前未上线,不在本版设计范围。",
  451. "dds_arch": "ChatBI 采用轻量问答架构:看板上下文(模块编码/筛选)+ 问题 → 意图解析(指标词匹配)→ 指标聚合(KPI 日表)→ 答案组装(结论/证据/原因/下一步 + 指标卡 + 跳转动作)→ (可选)LLM 润色;全程不落库,服务不可用时回退本地模板。",
  452. "terms": [("ChatBI 浮窗", "嵌于九宫格与模块看板的问答窗口"),
  453. ("结构化回答", "结论/证据/可能原因/下一步建议四段式回答,附相关指标卡"),
  454. ("本地模板回退", "智能服务不可用时由本地模板生成答案(isFallback)"),
  455. ("目标态", "规范所列 NL2SQL 报表、查询历史与语义模型配置,当前未上线")],
  456. "modules_tbl": [("CBI-M01", "ChatBI 智能问答", "看板内自然语言问数、结构化回答与跳转联动", "九宫格/看板、指标层")],
  457. "db_intro": "ChatBI 问答实时聚合指标层数据作答,不写业务表;ado_s9_chatbi_* 为规划期壳表,未接入运行链路。",
  458. "db_tables": [("(读取)ado_smart_ops_kpi_dimension_value_day", "指标日结果", "问答聚合输入"),
  459. ("(壳表)ado_s9_chatbi_*", "ChatBI 规划壳表", "查询历史/语义配置目标态,未接入")],
  460. "db_core": [],
  461. "db_rel": "无独立表结构;读取侧关系见九宫格模块详细设计说明书。",
  462. "if_list": [("POST", "api/AidopChatBI/ask", "自然语言问数(问题+模块上下文 → 结构化回答)")],
  463. "if_detail": "ask 接口入参含 question 与当前模块/筛选上下文;返回结论、证据摘要、可能原因、下一步建议、相关指标卡与跳转动作(看板/诊断);source 标记 local/deepseek,isFallback 标记降级。",
  464. "if_seq": "看板页打开浮窗 → 提交问题 → ask 聚合作答 → 展示结构化回答与指标卡 → 点击动作跳转看板/诊断。",
  465. },
  466. }
  467. # ─────────────────────────────────────────────────────────────
  468. # ENRICH:功能级内容(UM 步骤/截图/注意/FAQ;BBP 情形/权限/接口/报表表;DDS 页面/处理)
  469. # key: (模块, REQ 编号)
  470. # ─────────────────────────────────────────────────────────────
  471. ENRICH = {
  472. ("系统集成", "REQ-S9-001"): {
  473. "module_code": "INT-M01",
  474. "menu_path": "左侧菜单 → MDIOP → 数据中台管理 → 数据源管理;同步配置中心",
  475. "overview": "第三方系统同步用于登记第三方系统(ERP/MES/WMS)接入并配置同步任务,支持数据库直连、HTTP API 拉取与第三方标准 API 推数入站(方式丙),是订单至出库数据链路的入口。",
  476. "roles_short": "实施工程师、系统管理员",
  477. "steps_txt": [
  478. "步骤1:进入“数据源管理”页面,查看已登记数据源列表(名称、类型、连接状态),可按条件筛选。",
  479. "步骤2:点击“新增”登记数据源:选择接入方式(数据库直连 / HTTP API),填写连接参数与凭据后保存。",
  480. "步骤3:进入“同步配置中心”页面,查看同步任务列表(任务编码、名称、类型、调度、状态)。",
  481. "步骤4:新增或编辑同步任务:选择数据源与实体映射,配置定时或实时同步策略后启用。",
  482. "步骤5:首次启用后在“数据任务日志”核对执行结果;方式丙对接由实施开通 AccessKey 与对接编码后,第三方按标准 API 主动推送,无需页面配置。",
  483. ],
  484. "steps_tbl": [("1", "查询数据源", "数据源列表支持多条件筛选,含连接状态"),
  485. ("2", "新增数据源", "选择直连或 HTTP API,凭据加密保存、不明文回显"),
  486. ("3", "配置同步任务", "选择实体映射,设定定时或实时策略"),
  487. ("4", "启用并验证", "启用后首次执行结果见“数据任务日志”"),
  488. ("5", "方式丙对接", "实施开通授权后由第三方按标准 API 推数")],
  489. "shots": [("shot_int_sources.png", "数据源管理页面"), ("shot_int_tasks.png", "同步配置中心页面")],
  490. "notes": ["数据源凭据加密保存,页面不回显明文密钥。",
  491. "未开通的对接编码推数一律拒绝并记录日志。",
  492. "任务停用后调度不再触发,已排队批次不受影响。"],
  493. "faq": [("同步任务没有按预期执行怎么办?", "先在“数据任务日志”查看失败原因,再核对数据源连通性与任务启用状态;方式丙推数失败请核对签名与对接编码授权。")],
  494. "situations": [("新增第三方系统接入", "实施在数据源管理登记连接方式与凭据,完成连通性验证后交付配置"),
  495. ("定时/实时同步", "同步配置中心按策略调度执行,结果写数据任务日志"),
  496. ("方式丙推数入站", "第三方按标准 API 主动推送,签名鉴权、幂等去重、支持快照差集与日终对账")],
  497. "perm_rows": [("实施工程师", "数据源与同步任务的新增、编辑、启用/停用"),
  498. ("系统管理员", "全部配置权限与入站授权管理"),
  499. ("业务用户", "只读消费同步结果,无配置权限")],
  500. "if_rows": [("数据库直连同步", "定时/实时拉取第三方数据库表", "定时(可配)"),
  501. ("HTTP API 拉取", "调用第三方接口拉数", "定时/手动"),
  502. ("标准 API 推数入站", "api/mdp/inbound 方式丙推送", "第三方触发"),
  503. ("出站回写", "Outbox 队列推送第三方", "业务触发")],
  504. "rpt_rows": [("同步结果监控", "任务执行成功/失败与耗时", "见“日志查询”功能")],
  505. "dds_page": ["数据源管理页:筛选区(名称/类型/状态)+ 数据源列表(名称、类型、连接状态、更新时间)+ 新增/编辑弹窗(接入方式、连接参数、凭据)。路由 /aidop/data-platform/sources。",
  506. "同步配置中心页:任务列表(任务编码、名称、类型、调度、状态)+ 任务编辑(实体映射、步骤、调度策略、参数)。路由 /aidop/data-platform/sync-tasks。"],
  507. "dds_handle": ("数据源连接参数/实体映射/调度策略", "连接测试→映射校验→任务装配(步骤/调度/参数)→启用触发", "可执行同步任务与首同步结果", "凭据加密;接入方式限直连/HTTP API/方式丙;未开通对接编码拒绝", "源不可达记失败日志并告警"),
  508. },
  509. ("系统集成", "REQ-S9-002"): {
  510. "module_code": "INT-M02",
  511. "menu_path": "左侧菜单 → MDIOP → 数据中台管理 → 数据任务日志;业务动作日志",
  512. "overview": "日志查询是集成运行的监控与追溯入口:数据任务日志记录同步批次执行结果,业务动作日志记录中台业务动作的执行明细,支撑运维排障与验收举证。",
  513. "roles_short": "运维、系统管理员",
  514. "steps_txt": [
  515. "步骤1:进入“数据任务日志”页面,按时间范围、任务、状态筛选同步执行记录。",
  516. "步骤2:点击失败记录,查看错误信息与失败原因摘要。",
  517. "步骤3:进入“业务动作日志”页面,按时间、动作类型、状态筛选动作级执行明细。",
  518. "步骤4:按批次号/任务编码在两类日志间关联,定位异常环节后转同步配置中心处置。",
  519. ],
  520. "steps_tbl": [("1", "筛选任务日志", "按时间/任务/状态过滤同步批次"),
  521. ("2", "查看失败详情", "错误码与失败原因摘要可追溯"),
  522. ("3", "查动作日志", "业务动作级执行明细(含耗时与结果)"),
  523. ("4", "关联处置", "按批次号关联两类日志并转任务配置处理")],
  524. "shots": [("shot_int_synclogs.png", "数据任务日志页面"), ("shot_int_actionlogs.png", "业务动作日志页面")],
  525. "notes": ["日志按租户隔离,仅显示当前租户数据。",
  526. "失败日志包含错误码与原因摘要,处置后可重新触发任务。",
  527. "查询无结果显示“暂无数据”,不代表系统异常。"],
  528. "faq": [("失败后如何重跑?", "在“同步配置中心”重新触发对应任务,或由运维按批次重跑;重跑结果会生成新的日志记录。")],
  529. "situations": [("日常监控", "运维按日检查失败任务与动作日志,确认同步健康度"),
  530. ("异常排障", "按批次关联任务日志与动作日志,定位失败环节并处置"),
  531. ("验收举证", "导出或截图日志记录作为同步执行证据")],
  532. "perm_rows": [("运维", "日志查询与失败处置"),
  533. ("系统管理员", "全部日志查询权限")],
  534. "if_rows": [("任务日志查询 API", "同步批次执行记录查询", "页面查询"),
  535. ("动作日志查询 API", "业务动作执行明细查询", "页面查询")],
  536. "rpt_rows": [("同步监控列表", "按时间/状态的任务执行统计视图", "页面查询,可扩展导出")],
  537. "dds_page": ["数据任务日志页:筛选区(时间/任务/状态)+ 批次列表(任务、开始/结束、状态、耗时、错误摘要)。路由 /aidop/data-platform/sync-logs。",
  538. "业务动作日志页:筛选区(时间/动作/状态)+ 动作列表(动作类型、批次、状态、耗时、结果摘要)。路由 /aidop/data-platform/action-run-logs。"],
  539. "dds_handle": ("筛选条件", "按条件查询执行日志→失败提取错误码与摘要→关联批次", "日志列表与失败详情", "租户隔离;敏感凭据不落日志明文", "无日志返回空态"),
  540. },
  541. ("系统集成", "REQ-S9-003"): {
  542. "module_code": "INT-M03",
  543. "menu_path": "左侧菜单 → MDIOP → 数据中台管理 → 出站回写队列",
  544. "overview": "第三方系统事务以出站回写队列(Outbox)监控回写第三方系统的事务状态,覆盖待推、成功、失败(死信)全生命周期,支撑业务数据双向流转与传输容错。",
  545. "roles_short": "运维处理失败;业务触发;管理员配置端点",
  546. "steps_txt": [
  547. "步骤1:进入“出站回写队列”页面,查看事务列表(目标源、动作、状态、重试次数、创建时间)。",
  548. "步骤2:按状态(待推/成功/失败)、目标数据源或动作类型筛选。",
  549. "步骤3:点击失败事务,查看错误码、错误信息与请求报文摘要。",
  550. "步骤4:失败事务由系统按退避策略自动重推;长期失败进入死信的,核对目标系统状态后由人工处理。",
  551. ],
  552. "steps_tbl": [("1", "查看事务队列", "待推/成功/失败(死信)状态全览"),
  553. ("2", "筛选定位", "按状态/目标源/动作类型过滤"),
  554. ("3", "查看失败详情", "错误码、错误信息与报文摘要"),
  555. ("4", "容错处理", "自动退避重推;死信人工核对处理")],
  556. "shots": [("shot_int_outbox.png", "出站回写队列页面")],
  557. "notes": ["回写统一走 Outbox,按幂等键去重,禁止无日志直连外写。",
  558. "死信事务不会自动重推,须人工核对目标系统状态后处理。",
  559. "请勿直接修改队列数据表,处置应通过页面或运维工具进行。"],
  560. "faq": [("待推事务一直不减少怎么办?", "检查目标数据源路由配置与推送作业运行状态;若目标系统不可达,事务会按退避策略延后重推。")],
  561. "situations": [("业务触发回写", "业务操作完成后写入 Outbox,由推送作业投递第三方"),
  562. ("失败重试", "推送失败按退避策略自动重推并记录错误码"),
  563. ("死信处置", "超过重试上限转死信,人工核对后重发或标记处理")],
  564. "perm_rows": [("运维", "队列查询与失败处置"),
  565. ("系统管理员", "端点配置与全部队列权限"),
  566. ("业务用户", "触发回写,无队列操作权限")],
  567. "if_rows": [("出站推送 API", "Outbox 投递第三方系统", "业务触发+作业轮询"),
  568. ("回执登记", "第三方接收结果回写队列状态", "推送后同步")],
  569. "rpt_rows": [("事务成功率统计", "成功/失败/死信数量与趋势", "队列页面统计视图")],
  570. "dds_page": ["出站回写队列页:状态统计区(待推/成功/死信计数)+ 筛选区(状态/目标源/动作)+ 事务列表(目标源、动作、状态、重试次数、错误码、时间)+ 失败详情抽屉。路由 /aidop/data-platform/outbox。"],
  571. "dds_handle": ("业务回写请求", "写 Outbox(幂等键)→作业轮询推送→回执更新状态→失败退避重推", "回写事务状态与回执", "幂等键去重;断点续传;死信人工介入", "目标不可达记错误码并延后重推"),
  572. },
  573. ("S9", "REQ-S9-005"): {
  574. "module_code": "S9-M01",
  575. "menu_path": "左侧菜单 → MDIOP → 智慧运营看板 → 九宫格(登录后首页默认展示)",
  576. "overview": "九宫格是管理层一屏总览:S1~S9 九个模块格子卡片展示核心 KPI 当前值、目标、偏差与红黄绿状态,未达标格子醒目预警,支持全屏大屏模式与点击下钻。",
  577. "roles_short": "管理层(只读)、运营专员(筛选下钻)",
  578. "steps_txt": [
  579. "步骤1:登录系统后首页即为九宫格(也可从菜单“智慧运营看板 → 九宫格”进入)。",
  580. "步骤2:浏览 S1~S9 各模块格子指标卡:当前值、目标值、偏差与红黄绿状态一目了然。",
  581. "步骤3:点击页面右上角“全屏”按钮进入大屏展示模式;点击“退出全屏”或按 ESC 返回。",
  582. "步骤4:点击任一模块格子,进入对应模块看板查看明细指标。",
  583. "步骤5:点击格子上的“智慧诊断”按钮,可对未达标指标进入诊断分析。",
  584. ],
  585. "steps_tbl": [("1", "打开九宫格", "登录后首页默认展示,菜单亦可进入"),
  586. ("2", "浏览指标卡", "当前/目标/偏差/红黄绿状态"),
  587. ("3", "切换全屏", "大屏展示模式,退出全屏按钮返回"),
  588. ("4", "格子下钻", "进入对应模块看板"),
  589. ("5", "联动诊断", "未达标指标进入智慧诊断")],
  590. "shots": [("shot_s9_grid.png", "九宫格首页"), ("shot_s9_fullscreen.png", "九宫格全屏模式")],
  591. "notes": ["指标口径以运营指标主数据为准,页面不单独定义计算公式。",
  592. "无数据的格子显示空态占位,不影响其他格子浏览。",
  593. "全屏模式适合车间/会议室大屏投放。"],
  594. "faq": [("格子显示红色代表什么?", "表示该模块存在未达标 L1 指标,点击格子进入模块看板或点击“智慧诊断”查看明细与原因。")],
  595. "situations": [("管理层早会巡览", "一屏查看全场核心指标与预警,定位异常模块"),
  596. ("异常下钻", "点击红色格子进入模块看板,必要时进入智慧诊断"),
  597. ("大屏投放", "全屏模式用于现场大屏,定时刷新")],
  598. "perm_rows": [("管理层", "九宫格只读查看"),
  599. ("运营专员", "筛选、下钻与诊断联动"),
  600. ("指标配置(S0)", "指标与布局配置在运营建模侧维护")],
  601. "if_rows": [("home-grid 接口", "九宫格各模块格子数据", "页面加载/刷新"),
  602. ("home-l1 接口", "首页 L1 指标总览", "页面加载")],
  603. "rpt_rows": [("管理层大屏视图", "全场 KPI 即时总览", "九宫格页即时报表")],
  604. "dds_page": ["九宫格首页:3×3 格子卡片(模块名、L1 指标、当前/目标/偏差、红黄绿状态)+ 全屏按钮 + 智慧诊断入口;空态占位。路由 /dashboard/home(菜单 /aidop/smart-ops/grid)。",
  605. "全屏模式:隐藏导航的大屏布局,含退出全屏按钮。"],
  606. "dds_handle": ("筛选上下文", "按模块聚合 L1 指标与达标状态→渲染格子卡片", "九宫格总览与预警", "口径以 KPI Master 为准;租户隔离;无数据显示空态", "日批未产出时展示上期或空态"),
  607. },
  608. ("S9", "REQ-S9-004"): {
  609. "module_code": "S9-M02",
  610. "menu_path": "左侧菜单 → MDIOP → 智慧运营看板 → S9看板",
  611. "overview": "S9 全场关键指标看板以动态看板呈现全场 L1/L2 指标卡与趋势图,支持按时间、组织等条件筛选,支持指标下钻与智慧诊断联动,是九宫格的全场关键指标页。",
  612. "roles_short": "管理层、部门业务人员、运营专员",
  613. "steps_txt": [
  614. "步骤1:从菜单“智慧运营看板 → S9看板”进入(或从九宫格 S9 格子点击进入)。",
  615. "步骤2:查看顶部 L1 指标卡区:当前值、目标值、达成状态(红黄绿)。",
  616. "步骤3:查看趋势图区,观察指标近周期走势。",
  617. "步骤4:调整时间、组织等筛选条件,指标卡与趋势图联动刷新。",
  618. "步骤5:点击未达标指标卡查看下钻指标(L2/L3);点击“智慧诊断”按钮跳转诊断分析。",
  619. ],
  620. "steps_tbl": [("1", "打开 S9 看板", "菜单或九宫格 S9 格子进入"),
  621. ("2", "查看 L1 指标卡", "当前/目标/达成状态"),
  622. ("3", "查看趋势", "近周期走势对比"),
  623. ("4", "条件筛选", "时间/组织等条件联动刷新"),
  624. ("5", "下钻与诊断", "L2/L3 下钻;跳转智慧诊断")],
  625. "shots": [("shot_s9_board.png", "S9 全场关键指标看板")],
  626. "notes": ["看板数据来自指标层日批计算(T+1),当日展示截至昨日的结果。",
  627. "筛选条件变化时,指标卡、趋势图与下钻上下文保持一致。",
  628. "下钻受数据权限约束,无权限维度不展示明细。"],
  629. "faq": [("为什么今天上午看不到最新数据?", "指标为每日批处理计算,上午展示的是截至昨日的日批结果;如需确认计算状态请联系运维查看指标计算运行日志。")],
  630. "situations": [("指标达成跟踪", "按周期查看全场 L1 指标达成与趋势"),
  631. ("偏差分析", "点击未达标指标查看偏差并跳转诊断"),
  632. ("自助查询", "按时间/组织/产品筛选观察波动")],
  633. "perm_rows": [("管理层", "看板只读"),
  634. ("部门业务人员", "本部门相关指标查看与下钻"),
  635. ("运营专员", "筛选、下钻与诊断联动")],
  636. "if_rows": [("dashboard-page 接口", "看板页面配置与数据", "页面加载/筛选刷新"),
  637. ("module-detail 接口", "模块详情指标数据", "下钻触发"),
  638. ("smart-diagnosis 接口", "未达标指标诊断联动", "点击触发")],
  639. "rpt_rows": [("全场指标视图", "L1/L2 指标与趋势", "看板页即时报表,可扩展导出")],
  640. "dds_page": ["S9 看板页:筛选区(时间/组织等)+ L1 指标卡区(当前/目标/状态)+ 趋势图区 + 下钻卡片区(L2/L3)+ 全屏与智慧诊断按钮。路由 /aidop/smart-ops/s9(动态看板 DynamicModuleDashboard 渲染)。"],
  641. "dds_handle": ("筛选条件/页面配置", "按页面配置装配部件→聚合指标日结果→渲染卡片与趋势", "全场指标看板视图", "展示口径不得与 KPI Master 冲突;下钻受数据权限约束", "无数据部件空态提示"),
  642. },
  643. ("运营诊断", "REQ-S9-006"): {
  644. "module_code": "OD-M01",
  645. "menu_path": "左侧菜单 → MDIOP → 智慧诊断(也可从九宫格/看板未达标指标点击进入)",
  646. "overview": "智慧诊断对未达标指标开展环节级诊断:以订单为主线串联各业务节点,通过诊断闭环卡、目标&现状、主要问题与环节矩阵定位异常,支持按订单、物料、供应商、产线、仓库、时间段、人员七类维度下钻根因,并可一键转改善闭环。",
  647. "roles_short": "运营专员执行诊断;管理层只读;责任部门配合举证",
  648. "steps_txt": [
  649. "步骤1:从九宫格/看板的未达标指标点击进入智慧诊断(或从菜单“智慧诊断”进入),系统带入指标与筛选上下文。",
  650. "步骤2:查看诊断闭环卡与“目标&现状”区,确认指标目标值与当前实际值的差距。",
  651. "步骤3:在“主要问题”区点击问题条目,下钻查看 L3/L4 证据明细(订单/物料/供应商等维度)。",
  652. "步骤4:查看环节矩阵,定位断点、滞后、损耗等异常发生的业务环节。",
  653. "步骤5:确认诊断结论后,点击“生成改善计划”将问题转入改善闭环(功能编号 FUNC-S9-006)。",
  654. ],
  655. "steps_tbl": [("1", "进入诊断", "看板未达标项带入上下文,菜单亦可直接进入"),
  656. ("2", "查看目标&现状", "目标值与实际值对比,确认差距"),
  657. ("3", "问题下钻", "按七类维度查看证据明细"),
  658. ("4", "环节矩阵", "定位异常业务环节"),
  659. ("5", "转改善", "生成改善计划进入闭环")],
  660. "shots": [("shot_od_main.png", "智慧诊断主页(诊断闭环与目标&现状)"), ("shot_od_drill.png", "主要问题下钻与环节矩阵")],
  661. "notes": ["诊断结论以对接数据就绪为前提;第三方数据延迟不计入本系统缺陷。",
  662. "下钻维度取决于主数据与明细接通程度,未接通维度不展示。",
  663. "无异常期间诊断页显示良好态或空问题列表,不报错。"],
  664. "faq": [("诊断页没有数据怎么办?", "确认对应模块已有指标日批结果,且当前筛选期间存在未达标项;两者都满足仍无数据时请联系运维检查诊断作业。")],
  665. "situations": [("看板下钻诊断", "未达标指标一键带入诊断,保留筛选上下文"),
  666. ("七维根因溯源", "按订单/物料/供应商/产线/仓库/时间段/人员下钻证据"),
  667. ("转改善闭环", "主要问题确认后生成改善计划,功能并入 FUNC-S9-006")],
  668. "perm_rows": [("运营专员", "诊断执行、下钻与转改善"),
  669. ("管理层", "诊断结论只读"),
  670. ("责任部门", "证据配合查看")],
  671. "if_rows": [("smart-diagnosis 接口", "诊断主页数据(环节矩阵/目标现状/主要问题)", "页面加载"),
  672. ("evidence 接口", "主要问题证据明细", "下钻触发"),
  673. ("createFromDiagnosis 接口", "生成改善计划", "点击触发")],
  674. "rpt_rows": [("运营诊断报告摘要", "结论、根因与建议", "页面展示;正式报告导出为后续扩展")],
  675. "dds_page": ["智慧诊断主页:诊断闭环卡(识别/下钻/结论/转改善四卡)+ 目标&现状区 + 主要问题列表 + 环节矩阵。路由 /aidop/smart-diagnosis。",
  676. "下钻区:主要问题 → L3/L4 证据明细(维度筛选);转改善入口。"],
  677. "dds_handle": ("指标上下文/筛选条件", "环节规则识别→目标现状对比→主要问题装配→证据下钻", "诊断结论与问题清单", "结论可追溯订单主线或指标编码;支持七维下钻", "数据未就绪时良好态/空态提示"),
  678. },
  679. ("运营改善", "REQ-S9-007"): {
  680. "module_code": "OI-M01",
  681. "menu_path": "左侧菜单 → MDIOP → 智慧诊断(改善闭环区);台账查询:MDIOP → 智慧运营看板 → 改善计划台账",
  682. "overview": "改善计划与效果验证承接诊断输出的问题建档,完成整改派单(平台审批流)、行动项过程跟踪与有效性验证(改善前后指标对比),并提供改善计划台账集中查询全部计划。",
  683. "roles_short": "运营专员建档与复盘;责任人执行;审批人派单审批;管理层只读",
  684. "steps_txt": [
  685. "步骤1:在智慧诊断“主要问题”区点击“生成改善计划”,系统带入问题上下文完成建档。",
  686. "步骤2:填写根因、行动项、责任人与计划完成日期,保存改善计划。",
  687. "步骤3:点击“提交审批”,改善单进入审批中心待办,由审批人完成派单审批。",
  688. "步骤4:审批通过后开始执行,责任人定期更新行动项状态,运营专员过程跟踪。",
  689. "步骤5:到期打开“有效性验证”,对比基线值与当前 KPI,填写验证结论并提交,确认闭环或继续跟踪。",
  690. "步骤6:进入“改善计划台账”页,按状态、责任人、模块等条件筛选,集中跟踪全部改善计划。",
  691. ],
  692. "steps_tbl": [("1", "问题建档", "由诊断主要问题生成改善计划"),
  693. ("2", "填写计划", "根因/行动项/责任人/完成日"),
  694. ("3", "提交审批", "审批中心待办,状态回写"),
  695. ("4", "执行跟踪", "行动项状态更新与日志"),
  696. ("5", "效果验证", "基线与当前 KPI 对比,提交结论"),
  697. ("6", "台账查询", "多条件筛选集中跟踪")],
  698. "shots": [("shot_od_main.png", "智慧诊断改善闭环区"), ("shot_oi_plans.png", "改善计划台账页面")],
  699. "notes": ["改善单必须关联诊断问题或指标,保证端到端追溯。",
  700. "责任人或计划完成日缺失时无法保存(必填校验)。",
  701. "验证结论保留基线值、目标值与验证值,提交后不可随意篡改。"],
  702. "faq": [("改善计划台账在哪里?", "左侧菜单 → MDIOP → 智慧运营看板 → 改善计划台账,可按状态、责任人、模块等条件筛选查询。")],
  703. "situations": [("诊断转改善", "主要问题一键建档,保留诊断上下文"),
  704. ("审批派单", "提交平台审批流,审批人待办处理"),
  705. ("效果复盘", "验证仪表对比改善前后指标,量化结论闭环")],
  706. "perm_rows": [("运营专员", "建档、提交审批、验证与复盘"),
  707. ("责任人", "行动项执行与状态更新"),
  708. ("审批人", "派单审批"),
  709. ("管理层", "台账只读")],
  710. "if_rows": [("改善计划 API", "建档/台账/详情/状态流转", "页面触发"),
  711. ("平台审批流", "派单审批待办", "提交触发"),
  712. ("KPI 对比查询", "验证仪表基线与当前值", "验证触发")],
  713. "rpt_rows": [("改善任务清单", "全部计划与状态", "台账页查询,可扩展导出"),
  714. ("成效对比", "改善前后指标对比", "验证仪表视图")],
  715. "dds_page": ["诊断闭环区:主要问题 → 生成改善计划表单(根因/行动项/责任人/完成日)→ 提交审批 → 有效性验证仪表(基线/当前对比)。",
  716. "改善计划台账页:筛选区(状态/责任人/模块/到期区间)+ 计划列表(计划单号、问题、责任人、状态、完成日、验证结论)。路由 /aidop/smart-ops/improvement-plans。"],
  717. "dds_handle": ("诊断问题上下文", "建档→行动项装配→审批派单→执行跟踪→验证对比→闭环", "改善计划全生命周期状态", "必须关联诊断/指标;必填校验;验证证据保留", "无诊断上下文或必填缺失时拒绝保存"),
  718. },
  719. ("ChatBI", "REQ-S9-009"): {
  720. "module_code": "CBI-M01",
  721. "menu_path": "九宫格 / 模块看板页面右下角“MDIOP CHATBI”浮窗",
  722. "overview": "ChatBI 智能问答嵌入九宫格与模块看板,用户以自然语言提问运营指标,系统返回结论、证据、可能原因与下一步建议,并展示相关指标卡,可直接跳转看板或智慧诊断。",
  723. "roles_short": "管理层、运营专员",
  724. "steps_txt": [
  725. "步骤1:打开九宫格或任一模块看板页面。",
  726. "步骤2:点击页面右下角“MDIOP CHATBI”浮窗,打开问答面板。",
  727. "步骤3:在输入框输入自然语言问题(如“本周 OTD 怎么样”),或点选面板提供的建议问题。",
  728. "步骤4:查看结构化回答:结论、证据、可能原因、下一步建议,以及相关指标卡。",
  729. "步骤5:点击回答中的跳转按钮,进入对应看板或智慧诊断继续分析;也可继续追问。",
  730. ],
  731. "steps_tbl": [("1", "打开问答浮窗", "九宫格/看板右下角入口"),
  732. ("2", "提问", "自然语言输入或点选建议问题"),
  733. ("3", "查看回答", "结论/证据/原因/建议 + 指标卡"),
  734. ("4", "跳转联动", "一键进入看板或智慧诊断")],
  735. "shots": [("shot_cb_widget.png", "ChatBI 问答浮窗"), ("shot_cb_answer.png", "ChatBI 结构化回答")],
  736. "notes": ["问答只解释已发布运营指标,不改写业务单据。",
  737. "提问与结果受当前租户与数据权限约束。",
  738. "智能服务不可用时回退本地模板答案,回答中标注来源(local/deepseek)。"],
  739. "faq": [("回答显示 local 来源是什么意思?", "表示智能服务(DeepSeek)不可用,系统回退本地模板生成答案;结论基于已发布指标计算,仍可参考。")],
  740. "situations": [("看数问答", "针对当前看板模块提问指标达成与波动"),
  741. ("追问分析", "按建议问题连续追问,逐步深入"),
  742. ("跳转闭环", "从回答跳转看板核实或进入诊断分析")],
  743. "perm_rows": [("管理层", "问答使用"),
  744. ("运营专员", "问答使用与跳转联动")],
  745. "if_rows": [("ChatBI ask 接口", "自然语言问数聚合作答", "提问触发")],
  746. "rpt_rows": [("问答结论与指标卡", "结构化回答内容", "浮窗即时展示")],
  747. "dds_page": ["ChatBI 浮窗:问答面板(输入框 + 建议问题 + 回答区);回答区为四段式结构(结论/证据/原因/下一步)+ 指标卡 + 跳转按钮。嵌入九宫格与模块看板。"],
  748. "dds_handle": ("问题文本+模块上下文", "意图解析→指标聚合→答案组装→(可选)LLM 润色", "结构化回答与指标卡", "仅解释已发布指标;租户与数据权限约束;不落库", "服务不可用回退本地模板(isFallback)"),
  749. },
  750. }
  751. # 模块总体流程链(与 _gen_flow_diagrams.OVERALL 一致,用于 BBP 1.2 图后文字)
  752. OVERALL_FLOW = {
  753. "系统集成": ["第三方系统(ERP/MES/WMS)", "数据源登记/标准API推数(方式丙)", "同步任务执行与清洗标准化", "贴源/标准/指标层入仓", "业务模块与看板消费", "出站回写第三方系统"],
  754. "S9": ["运营指标主数据", "指标层日批计算", "九宫格总览(红黄绿预警)", "格子下钻模块看板", "联动智慧诊断"],
  755. "运营诊断": ["看板未达标指标", "智慧诊断环节识别", "七维下钻根因溯源", "诊断结论与报告", "转改善闭环"],
  756. "运营改善": ["诊断问题建档", "审批派单到责任人", "行动项执行跟踪", "有效性验证(前后对比)", "复盘闭环与经验固化"],
  757. "ChatBI": ["看板/九宫格上下文", "自然语言提问", "意图解析与指标聚合", "结论与建议输出", "跳转看板或诊断"],
  758. }
  759. def live_features(mod):
  760. return [f for f in mod["features"] if f.get("impl_status") != "未实现"]
  761. def flow_img(mod_key, feat=None):
  762. prefix = FLOW_PREFIX[mod_key]
  763. if feat is None:
  764. return FLOWS / f"{prefix}_overall.png"
  765. return FLOWS / f"{prefix}_{feat['func'].lower().replace('-', '_')}.png"
  766. def shot_img(name):
  767. return SHOTS / name
  768. # ─────────────────────────────────────────────────────────────
  769. # BRD:业务需求描述(S1 风格)
  770. # ─────────────────────────────────────────────────────────────
  771. def write_brd(mod_key: str, mod: dict, out_path: Path):
  772. doc = new_doc("brd")
  773. meta = MODULE_META[mod_key]
  774. ver = doc_version(mod_key, "brd")
  775. # 封面(S1 BRD:28pt 模块名 / 22pt 文档类型 / 13pt 系统名 + 文档编号表)
  776. cover_gap(doc, 3)
  777. para(doc, mod["module_title"], size=28, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  778. para(doc, "业务需求描述", size=22, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  779. para(doc, SYSTEM_NAME, size=13, align=WD_ALIGN_PARAGRAPH.CENTER)
  780. cover_gap(doc, 1)
  781. kv_table(doc, [("文档编号", mod["doc_no_brd"]), ("版本", ver), ("密级", "内部"),
  782. ("编制单位", AUTHOR), ("编制日期", TODAY_ISO)])
  783. front_matter(doc, version_rows=version_rows(mod_key, "brd"))
  784. # 范围说明
  785. h2(doc, "范围说明")
  786. para(doc, f"本文件描述「{mod['module_title']}」业务需求,系统名称为 {SYSTEM_NAME}。")
  787. para(doc, f"报价范围对齐:{mod['quote_scope']}。")
  788. para(doc, "需求与功能要求以项目合同里的技术规范对应章节为准,并与报价单、三联对照表一致;不得偏离技术规范已列明的能力边界。")
  789. para(doc, "需求编号格式 REQ-S9-nnn;与功能编号、测试编号通过三联对照表串联。")
  790. if mod.get("intro"):
  791. para(doc, mod["intro"])
  792. if mod_key == "ChatBI":
  793. para(doc, "说明:ChatBI 报表与历史(NL2SQL 报表、查询历史、语义模型配置)为技术规范 2.6.4 目标态能力,当前版本未上线,不纳入本期需求范围;上线后另行补充需求与验收。")
  794. for i, feat in enumerate(live_features(mod), 1):
  795. h2(doc, f"({CN_NUM[i]}){feat['name']}({feat['req']})")
  796. h3(doc, "功能说明")
  797. if feat.get("tech_clause"):
  798. para(doc, f"本功能对应{feat['tech_clause']}。")
  799. for t in feat["func_desc"]:
  800. para(doc, t)
  801. h3(doc, "业务描述")
  802. for t in feat["biz_desc"]:
  803. para(doc, t)
  804. para(doc, f"对应功能编号:{feat['func']};系统路径:{feat['path']}。", bold=True)
  805. out_path.parent.mkdir(parents=True, exist_ok=True)
  806. doc.save(out_path)
  807. print("BRD", out_path.name)
  808. # ─────────────────────────────────────────────────────────────
  809. # BBP:蓝图设计方案(S1 风格)
  810. # ─────────────────────────────────────────────────────────────
  811. def write_bbp(mod_key: str, mod: dict, out_path: Path):
  812. doc = new_doc("bbp")
  813. meta = MODULE_META[mod_key]
  814. ver = doc_version(mod_key, "bbp")
  815. # 封面(S1 BBP:26pt 模块名 / 26pt 文档类型 / 14pt 系统名 / 11pt 版本行)
  816. cover_gap(doc, 3)
  817. para(doc, mod["module_title"], size=26, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  818. para(doc, "蓝图设计方案", size=26, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  819. para(doc, SYSTEM_NAME, size=14, align=WD_ALIGN_PARAGRAPH.CENTER)
  820. para(doc, f"版本:{ver} 日期:{TODAY_CN} 作者:{AUTHOR}", size=11, align=WD_ALIGN_PARAGRAPH.CENTER)
  821. front_matter(doc, version_rows=version_rows(mod_key, "bbp"), bbp_style=True)
  822. # 1 总体业务方案
  823. h1(doc, "1 总体业务方案")
  824. h2(doc, "1.1 目标和宗旨")
  825. para(doc, f"落实报价范围「{mod['quote_scope']}」,并将项目合同里的技术规范中对应功能要求转化为可配置、可验收的功能方案。")
  826. if mod.get("intro"):
  827. para(doc, mod["intro"])
  828. for t in mod.get("tech_spec", [])[:4]:
  829. if mod.get("intro") and t == mod["intro"]:
  830. continue
  831. para(doc, t)
  832. h2(doc, "1.2 总体业务流程图")
  833. para(doc, meta["bbp_overall_intro"])
  834. img = flow_img(mod_key)
  835. if img.exists():
  836. picture(doc, img)
  837. para(doc, "流程路径:" + " → ".join(OVERALL_FLOW[mod_key]) + "。")
  838. h2(doc, "1.3 方案设计")
  839. para(doc, meta["bbp_design"])
  840. for idx, feat in enumerate(live_features(mod), 2):
  841. enr = ENRICH[(mod_key, feat["req"])]
  842. h1(doc, f"{idx} {feat['name']}({feat['func']})")
  843. h2(doc, f"{idx}.1 目标/宗旨")
  844. para(doc, feat["goal"])
  845. if feat.get("tech_clause"):
  846. para(doc, f"规范追溯:{feat['tech_clause']}。", bold=True)
  847. h2(doc, f"{idx}.2 业务流程图")
  848. fimg = flow_img(mod_key, feat)
  849. if fimg.exists():
  850. picture(doc, fimg)
  851. para(doc, "流程路径:" + " → ".join(s[1] for s in feat["flow_steps"]) + "。")
  852. h2(doc, f"{idx}.3 业务流程说明")
  853. for t in feat["biz_desc"]:
  854. para(doc, t)
  855. data_table(doc, ["编号", "活动名称", "执行角色", "活动描述", "输入", "输出"],
  856. [(s[0], s[1], s[2], s[3], s[4], s[5]) for s in feat["flow_steps"]], size=10)
  857. para(doc, "")
  858. data_table(doc, ["序列号", "业务情形", "描述/方案"],
  859. [(str(i + 1), a, b) for i, (a, b) in enumerate(enr["situations"])], size=10)
  860. h2(doc, f"{idx}.4 业务流程规则")
  861. for t in feat["rules"]:
  862. para(doc, "• " + t)
  863. h2(doc, f"{idx}.5 权限管理需求")
  864. data_table(doc, ["序号", "岗位名称", "对应系统权限"],
  865. [(str(i + 1), a, b) for i, (a, b) in enumerate(enr["perm_rows"])], size=10)
  866. para(doc, feat["roles"])
  867. h2(doc, f"{idx}.6 系统接口集成")
  868. data_table(doc, ["序号", "接口名称", "接口说明", "频次及触发方式"],
  869. [(str(i + 1), a, b, c) for i, (a, b, c) in enumerate(enr["if_rows"])], size=10)
  870. para(doc, feat["interfaces"])
  871. h2(doc, f"{idx}.7 报表需求")
  872. data_table(doc, ["序号", "名称", "描述", "方案"],
  873. [(str(i + 1), a, b, c) for i, (a, b, c) in enumerate(enr["rpt_rows"])], size=10)
  874. para(doc, feat["reports"])
  875. para(doc, f"对应需求:{feat['req']};路由:{feat['route']}。", bold=True)
  876. out_path.parent.mkdir(parents=True, exist_ok=True)
  877. doc.save(out_path)
  878. print("BBP", out_path.name)
  879. # ─────────────────────────────────────────────────────────────
  880. # DDS:详细设计说明书(S1 风格)
  881. # ─────────────────────────────────────────────────────────────
  882. TECH_STACK = [("前端", "Vue 3 + Vite + TypeScript + Element Plus", "3.x", "用户界面与交互"),
  883. ("后端", ".NET 10 + Admin.NET (Furion + SqlSugar)", "10.0", "业务逻辑与 API 服务"),
  884. ("数据存储", "MySQL", "8.0", "业务数据与中台数据"),
  885. ("基础设施", "Docker + Nginx", "—", "容器化部署与反向代理")]
  886. # 核心表字段结构(DDS 4.3):表名 -> (中文名, [(字段, 类型, 说明)])
  887. CORE_TABLE_COLS = {
  888. "mdp_sync_task": ("MDP 同步任务业务配置", [
  889. ("id", "bigint", "主键"), ("tenant_id", "bigint", "租户"),
  890. ("task_code", "varchar(100)", "任务编码"), ("task_name", "varchar(200)", "任务名称"),
  891. ("task_type", "varchar(40)", "任务类型(默认 SERVICE_SYNC)"),
  892. ("business_domain_code", "varchar(100)", "业务域编码"),
  893. ("consumer_modules", "varchar(500)", "消费模块清单"),
  894. ("source_system_code", "varchar(100)", "来源系统编码"),
  895. ("service_key", "varchar(100)", "服务键"), ("job_code", "varchar(100)", "作业编码"),
  896. ("schedule_job_id", "varchar(100)", "调度作业 Id"),
  897. ("status", "int", "状态(1 启用)"), ("owner_role", "varchar(100)", "责任角色"),
  898. ("config_version", "int", "配置版本"), ("description", "varchar(1000)", "描述"),
  899. ("create_time", "datetime", "创建时间"), ("update_time", "datetime", "更新时间")]),
  900. "mdp_inbound_request": ("方式丙入站请求台账", [
  901. ("id", "bigint", "主键"), ("tenant_id", "bigint", "租户"),
  902. ("access_key", "varchar(64)", "入站授权标识"),
  903. ("entity_code", "varchar(100)", "对接实体编码"),
  904. ("idempotency_key", "varchar(128)", "幂等键"),
  905. ("request_hash", "varchar(64)", "请求报文哈希"),
  906. ("sync_batch_id", "varchar(64)", "同步批次号"),
  907. ("snapshot_id", "varchar(64)", "快照号(全量场景)"),
  908. ("status", "varchar(16)", "状态(RECEIVED 等)"),
  909. ("http_status", "int", "响应 HTTP 状态"), ("accepted", "int", "接收条数"),
  910. ("rejected", "int", "拒绝条数"), ("receipt_json", "mediumtext", "回执报文"),
  911. ("client_ip", "varchar(64)", "调用方 IP"), ("elapsed_ms", "int", "处理耗时(毫秒)"),
  912. ("create_time", "datetime", "创建时间"), ("update_time", "datetime", "更新时间")]),
  913. "mdp_outbox": ("MDP 出站回写 Outbox(幂等待推表)", [
  914. ("id", "bigint", "主键"), ("tenant_id", "bigint", "租户"),
  915. ("target_source_code", "varchar(100)", "目标数据源编码"),
  916. ("action_code", "varchar(100)", "回写动作编码"),
  917. ("idem_key", "varchar(200)", "幂等键"),
  918. ("payload_json", "text", "回写报文"),
  919. ("status", "int", "状态:0 待推 1 成功 2 失败"),
  920. ("retry_count", "int", "已重试次数"),
  921. ("next_retry_time", "datetime", "下次可推时间(退避策略)"),
  922. ("last_error_code", "varchar(64)", "最近错误码"),
  923. ("response_json", "text", "目标系统回执"), ("error_msg", "varchar(1000)", "错误信息"),
  924. ("create_time", "datetime", "创建时间"), ("update_time", "datetime", "更新时间")]),
  925. "ado_smart_ops_kpi_master": ("运营指标主数据(KPI Master)", [
  926. ("id", "bigint", "主键"),
  927. ("metric_code", "varchar(50)", "指标编码(S1_L1_001 等)"),
  928. ("module_code", "varchar(20)", "所属模块 S1~S9"),
  929. ("metric_level", "int", "层级 1=L1 … 4=L4"),
  930. ("parent_id", "bigint", "父指标 Id(L1 为空)"),
  931. ("metric_name", "varchar(200)", "指标名称"),
  932. ("formula", "text", "计算公式"), ("formula_expr", "varchar(500)", "结构化表达式"),
  933. ("data_source", "varchar(200)", "数据来源模块"),
  934. ("direction", "varchar(20)", "优劣方向 higher/lower_is_better"),
  935. ("yellow_threshold", "decimal", "黄色阈值"), ("red_threshold", "decimal", "红色阈值"),
  936. ("is_home_page", "bool", "是否可上九宫格首页"),
  937. ("is_enabled", "bool", "启用"), ("tenant_id", "bigint", "租户")]),
  938. "ado_smart_ops_kpi_atomic_day": ("KPI 原子聚合层(日)", [
  939. ("id", "bigint", "主键"), ("tenant_id", "bigint", "租户"),
  940. ("factory_id", "bigint", "工厂"), ("domain_code", "varchar(50)", "业务对象域"),
  941. ("metric_code", "varchar(50)", "指标编码"), ("metric_level", "int", "指标层级"),
  942. ("stat_date", "date", "统计日期"),
  943. ("customer_code/product_code/order_no 等", "varchar(100)", "客户/产品/订单/产线/供应商/物料/仓库/工单等维度键"),
  944. ("sum_value", "decimal(18,6)", "可累加值"),
  945. ("numerator_value", "decimal(18,6)", "比率分子"),
  946. ("denominator_value", "decimal(18,6)", "比率分母"),
  947. ("sample_count", "int", "样本数"),
  948. ("batch_id", "varchar(100)", "MDP 批次"), ("calc_time", "datetime", "计算时间"),
  949. ("grain", "varchar(20)", "统计粒度(day)")]),
  950. "ado_smart_ops_improvement_plan": ("智慧诊断改善计划", [
  951. ("id", "bigint", "主键"), ("tenant_id", "bigint", "租户"),
  952. ("factory_id", "bigint", "工厂"),
  953. ("plan_no", "varchar(64)", "计划单号"), ("module_code", "varchar(20)", "模块编码"),
  954. ("metric_code", "varchar(64)", "诊断根指标编码"),
  955. ("problem_level", "int", "问题层级"),
  956. ("problem_name", "varchar(200)", "问题名称"),
  957. ("problem_severity", "varchar(16)", "严重度 red/yellow"),
  958. ("target_value", "varchar(64)", "目标值"), ("actual_value", "varchar(64)", "实际值"),
  959. ("root_cause", "text", "根因分析"), ("action_items_json", "text", "行动项 JSON"),
  960. ("owner_user_id", "bigint", "责任人"), ("due_date", "datetime", "计划完成日期"),
  961. ("status", "varchar(32)", "状态(draft 等)"),
  962. ("flow_instance_id", "bigint", "审批实例 Id"),
  963. ("verify_result", "varchar(32)", "验证结论"), ("verify_value", "varchar(64)", "验证值"),
  964. ("auto_verify_result", "varchar(32)", "自动有效性结论"),
  965. ("auto_verify_time", "datetime", "自动评价时间")]),
  966. }
  967. def write_dds(mod_key: str, mod: dict, out_path: Path):
  968. doc = new_doc("dds")
  969. meta = MODULE_META[mod_key]
  970. dl = DELIVER[mod_key]
  971. ver = doc_version(mod_key, "dds")
  972. feats = live_features(mod)
  973. # 封面(S1 DDS:项目信息表 6 行)
  974. cover_gap(doc, 2)
  975. para(doc, mod["module_title"], size=26, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  976. para(doc, "详细设计说明书", size=22, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  977. para(doc, SYSTEM_NAME, size=14, align=WD_ALIGN_PARAGRAPH.CENTER)
  978. cover_gap(doc, 1)
  979. kv_table(doc, [("项目名称", SYSTEM_NAME), ("系统名称", dl["cover_short"]),
  980. ("文档版本", ver), ("文档状态", "发布"),
  981. ("编制单位", AUTHOR), ("编制日期", TODAY_ISO)])
  982. front_matter(doc, version_rows=version_rows(mod_key, "dds"))
  983. # 1. 文档概述
  984. h1(doc, "1. 文档概述")
  985. h2(doc, "1.1 编写目的")
  986. para(doc, f"本说明书描述{SYSTEM_NAME}「{dl['cover_short']}」的详细设计,包括系统总体设计、功能模块详细设计、数据库设计、接口设计与安全多租户设计,作为开发实现、测试验证与验收的技术依据。")
  987. h2(doc, "1.2 设计范围")
  988. para(doc, meta["dds_scope"])
  989. para(doc, f"报价范围对齐:{mod['quote_scope']}。")
  990. h2(doc, "1.3 术语和缩略语")
  991. data_table(doc, ["术语/缩写", "说明"], meta["terms"], center_cols=())
  992. # 2. 系统总体设计
  993. h1(doc, "2. 系统总体设计")
  994. h2(doc, "2.1 系统目标和范围")
  995. para(doc, f"落实报价范围「{mod['quote_scope']}」。")
  996. for feat in feats:
  997. para(doc, f"• {feat['name']}({feat['func']}):{feat['goal']}")
  998. h2(doc, "2.2 总体架构")
  999. para(doc, meta["dds_arch"])
  1000. h2(doc, "2.3 技术栈")
  1001. data_table(doc, ["层次", "技术/组件", "版本", "用途"], TECH_STACK, center_cols=(0, 2))
  1002. h2(doc, "2.4 模块划分")
  1003. data_table(doc, ["模块编号", "模块名称", "主要职责", "依赖模块"], meta["modules_tbl"], center_cols=(0,))
  1004. # 3. 功能模块详细设计
  1005. h1(doc, "3. 功能模块详细设计")
  1006. h2(doc, "3.1 功能清单")
  1007. data_table(doc, ["功能编号", "功能名称", "所属模块", "用户角色", "简要说明"],
  1008. [(f["func"], f["name"], ENRICH[(mod_key, f["req"])]["module_code"],
  1009. ENRICH[(mod_key, f["req"])]["roles_short"], f["goal"]) for f in feats],
  1010. size=10, center_cols=(0, 2))
  1011. h2(doc, "3.2 模块详细设计")
  1012. for n, feat in enumerate(feats, 1):
  1013. enr = ENRICH[(mod_key, feat["req"])]
  1014. h3(doc, f"3.2.{n} {feat['name']}({enr['module_code']})")
  1015. kv_table(doc, [("模块编号", enr["module_code"]), ("模块名称", feat["name"]),
  1016. ("模块目标", feat["goal"]), ("对应需求", feat["req"]),
  1017. ("功能编号", feat["func"]), ("系统路由", feat["route"])])
  1018. para(doc, "")
  1019. h3(doc, f"3.2.{n}.1 业务流程")
  1020. para(doc, "流程路径:" + " → ".join(s[1] for s in feat["flow_steps"]) + "。")
  1021. data_table(doc, ["编号", "活动名称", "执行角色", "活动描述", "输入", "输出"],
  1022. [(s[0], s[1], s[2], s[3], s[4], s[5]) for s in feat["flow_steps"]], size=10)
  1023. para(doc, "")
  1024. h3(doc, f"3.2.{n}.2 功能处理")
  1025. hd = enr["dds_handle"]
  1026. data_table(doc, ["功能编号", "输入", "主要处理", "输出", "业务规则", "异常处理"],
  1027. [(feat["func"], hd[0], hd[1], hd[2], hd[3], hd[4])], size=10, center_cols=(0,))
  1028. para(doc, "")
  1029. h3(doc, f"3.2.{n}.3 页面设计")
  1030. for t in enr["dds_page"]:
  1031. para(doc, t)
  1032. h3(doc, f"3.2.{n}.4 设计验证要点")
  1033. for tc in feat["tcs"]:
  1034. para(doc, f"• [{tc[1]}] {tc[3]}:{tc[5]}")
  1035. # 4. 数据库设计
  1036. h1(doc, "4. 数据库设计")
  1037. h2(doc, "4.1 数据库说明")
  1038. para(doc, meta["db_intro"])
  1039. h2(doc, "4.2 数据表清单")
  1040. data_table(doc, ["序号", "表名", "说明", "核心内容"],
  1041. [(str(i + 1), a, b, c) for i, (a, b, c) in enumerate(meta["db_tables"])],
  1042. size=10, center_cols=(0,))
  1043. h2(doc, "4.3 表结构设计")
  1044. if meta["db_core"]:
  1045. for tname in meta["db_core"]:
  1046. cn, cols = CORE_TABLE_COLS[tname]
  1047. para(doc, f"表 {tname}({cn})", bold=True)
  1048. data_table(doc, ["字段", "类型", "说明"], cols, size=10, center_cols=())
  1049. para(doc, "")
  1050. else:
  1051. para(doc, meta["db_rel"])
  1052. h2(doc, "4.4 表关系和索引")
  1053. para(doc, meta["db_rel"])
  1054. # 5. 接口设计
  1055. h1(doc, "5. 接口设计")
  1056. h2(doc, "5.1 接口清单")
  1057. data_table(doc, ["序号", "方式", "接口路径", "说明"],
  1058. [(str(i + 1), a, b, c) for i, (a, b, c) in enumerate(meta["if_list"])],
  1059. size=10, center_cols=(0, 1))
  1060. h2(doc, "5.2 接口详细设计")
  1061. para(doc, meta["if_detail"])
  1062. h2(doc, "5.3 接口时序")
  1063. para(doc, meta["if_seq"])
  1064. # 6. 安全与多租户设计
  1065. h1(doc, "6. 安全与多租户设计")
  1066. para(doc, "认证与鉴权:页面接口经平台 JWT 认证与菜单/按钮权限控制;方式丙入站接口采用 AccessKey + 签名头鉴权,不加裸授权与匿名放行。")
  1067. para(doc, "多租户:全部业务表携带 tenant_id 并启用租户过滤器,跨租户数据不可见;九宫格、诊断、改善与看板接口按当前租户聚合。")
  1068. para(doc, "数据安全:数据源凭据加密保存且不回显;敏感字段不落日志明文;出站回写统一经 Outbox 幂等键去重,防止重复外写。")
  1069. # 7. 附录及变更记录
  1070. h1(doc, "7. 附录及变更记录")
  1071. h2(doc, "7.1 附录清单")
  1072. para(doc, "• 《Ai-DOP第三方对接业务数据详表》:对接编码、数据包与字段映射详表。")
  1073. para(doc, f"• 《{dl['cover_short']}业务需求描述》《{dl['cover_short']}蓝图设计方案》《{dl['cover_short']}-用户操作手册》:配套交付文档。")
  1074. h2(doc, "7.2 变更记录")
  1075. para(doc, "变更记录见本说明书卷首“版本记录”表。")
  1076. h2(doc, "7.3 审批记录")
  1077. data_table(doc, ["角色", "姓名", "签字", "日期"],
  1078. [("编制", "", "", ""), ("审核", "", "", ""), ("批准", "", "", "")], center_cols=(0,))
  1079. out_path.parent.mkdir(parents=True, exist_ok=True)
  1080. doc.save(out_path)
  1081. print("DDS", out_path.name)
  1082. # ─────────────────────────────────────────────────────────────
  1083. # UM:用户操作手册(S1 风格)
  1084. # ─────────────────────────────────────────────────────────────
  1085. def um_label(doc, text):
  1086. """【功能概述】等粗体标签段。"""
  1087. return para(doc, text, bold=True)
  1088. def um_note(doc, text):
  1089. return para(doc, text, size=10)
  1090. def write_um(mod_key: str, mod: dict, out_path: Path):
  1091. doc = new_doc("um")
  1092. meta = MODULE_META[mod_key]
  1093. dl = DELIVER[mod_key]
  1094. ver = doc_version(mod_key, "um")
  1095. feats = live_features(mod)
  1096. vrows = version_rows(mod_key, "um")
  1097. create_date = vrows[0][0]
  1098. # 封面(S1 UM:18pt 系统名 / 24pt 模块短名 / 22pt 手册名 / 11pt 作者日期版本)
  1099. cover_gap(doc, 3)
  1100. para(doc, SYSTEM_NAME, size=18, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  1101. para(doc, dl["cover_short"], size=24, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  1102. para(doc, "用户操作手册", size=22, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  1103. cover_gap(doc, 2)
  1104. para(doc, f"作 者:{AUTHOR}", size=11, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  1105. para(doc, f"创建日期:{create_date}", size=11, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  1106. para(doc, f"修订日期:{TODAY_ISO}", size=11, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  1107. para(doc, f"当前版本:{ver}", size=11, bold=True, align=WD_ALIGN_PARAGRAPH.CENTER)
  1108. front_matter(doc, version_rows=vrows)
  1109. # 1. 系统登录与首页
  1110. h1(doc, "1. 系统登录与首页")
  1111. para(doc, "本章说明登录系统、首页布局、修改密码与退出系统的通用操作;进入本模块后的功能操作见第 2 章。")
  1112. h2(doc, "1.1 登录系统")
  1113. para(doc, "步骤1:打开浏览器,在地址栏输入系统URL。", bold=True)
  1114. para(doc, "步骤2:输入用户名和密码,点击“登录”按钮进入系统。", bold=True)
  1115. para(doc, "步骤3:如忘记密码,请联系系统管理员重置。", bold=True)
  1116. um_note(doc, "【说明】系统支持Chrome、Edge、Firefox等主流浏览器,推荐使用Chrome最新版本。")
  1117. img = shot_img("shot_login.png")
  1118. if img.exists():
  1119. picture(doc, img)
  1120. caption(doc, "【图1.1 系统登录页面】")
  1121. h2(doc, "1.2 系统首页")
  1122. para(doc, "登录成功后进入系统首页(默认为九宫格智慧运营看板),页面主要包含以下区域:")
  1123. para(doc, " ● 顶部导航栏:显示系统LOGO、当前模块菜单、全屏切换等")
  1124. para(doc, " ● 左侧菜单栏:按模块分组展示功能菜单(MDIOP 分组),点击展开/折叠")
  1125. para(doc, " ● 右侧工作区:显示当前选中功能页面的内容")
  1126. para(doc, " ● 右上角用户区:显示当前登录用户信息,下拉菜单含个人中心、修改密码、退出登录")
  1127. img = shot_img("shot_home.png")
  1128. if img.exists():
  1129. picture(doc, img)
  1130. caption(doc, "【图1.2 系统首页布局】")
  1131. h2(doc, "1.3 修改密码")
  1132. para(doc, "步骤1:点击页面右上角用户头像/用户名区域。", bold=True)
  1133. para(doc, "步骤2:在下拉菜单中选择“个人中心”。", bold=True)
  1134. para(doc, "步骤3:点击“修改密码”标签页。", bold=True)
  1135. para(doc, "步骤4:输入旧密码、新密码并确认,点击“保存”。", bold=True)
  1136. um_note(doc, "【注意】密码长度不少于6位,建议使用字母+数字+特殊字符组合。")
  1137. img = shot_img("shot_password.png")
  1138. if img.exists():
  1139. picture(doc, img)
  1140. caption(doc, "【图1.3 修改密码页面】")
  1141. h2(doc, "1.4 退出系统")
  1142. para(doc, "步骤1:点击右上角用户头像/用户名。", bold=True)
  1143. para(doc, "步骤2:在下拉菜单中选择“退出系统”。", bold=True)
  1144. um_note(doc, "【说明】为保障数据安全,长时间不操作系统将自动退出登录。")
  1145. # 2. 模块操作说明
  1146. h1(doc, "2. 模块操作说明")
  1147. para(doc, meta["um_intro"])
  1148. h2(doc, "2.1 通用操作说明")
  1149. para(doc, "录入窗口中红色星号为必填项,未填时保存会提示,不会生成不完整单据。")
  1150. para(doc, "列表底部显示总条数,可翻页或切换每页条数;操作列按行提供查看或编辑入口。")
  1151. para(doc, "在查询区填写条件后点查询筛选数据,点重置清空条件并回到默认结果。")
  1152. for n, feat in enumerate(feats, 2):
  1153. enr = ENRICH[(mod_key, feat["req"])]
  1154. h2(doc, f"2.{n} {feat['name']}")
  1155. um_label(doc, "【功能概述】")
  1156. para(doc, enr["overview"])
  1157. um_label(doc, "【适用角色】")
  1158. para(doc, enr["roles_short"])
  1159. um_label(doc, "【菜单路径】")
  1160. para(doc, enr["menu_path"])
  1161. um_label(doc, "【操作步骤】")
  1162. for s in enr["steps_txt"]:
  1163. para(doc, s, bold=True)
  1164. para(doc, "")
  1165. data_table(doc, ["步骤", "操作", "说明"], enr["steps_tbl"], size=10, center_cols=(0,))
  1166. para(doc, "")
  1167. for si, (shot, cap) in enumerate(enr["shots"], 1):
  1168. img = shot_img(shot)
  1169. if img.exists():
  1170. picture(doc, img)
  1171. caption(doc, f"【图2.{n}.{si} {cap}】")
  1172. um_label(doc, "【注意事项】")
  1173. for note in enr["notes"]:
  1174. um_note(doc, "【注意】" + note)
  1175. um_label(doc, "【常见问题】")
  1176. for q, a in enr["faq"]:
  1177. para(doc, "Q: " + q, size=10, bold=True)
  1178. para(doc, "A: " + a, size=10)
  1179. out_path.parent.mkdir(parents=True, exist_ok=True)
  1180. doc.save(out_path)
  1181. print("UM ", out_path.name)
  1182. # ─────────────────────────────────────────────────────────────
  1183. # 编排:生成 / 部署
  1184. # ─────────────────────────────────────────────────────────────
  1185. def generate_all(out_dir: Path):
  1186. out_dir.mkdir(parents=True, exist_ok=True)
  1187. for mod_key, mod in MODULES.items():
  1188. files = DELIVER[mod_key]["files"]
  1189. write_brd(mod_key, mod, out_dir / files["brd"])
  1190. write_bbp(mod_key, mod, out_dir / files["bbp"])
  1191. write_dds(mod_key, mod, out_dir / files["dds"])
  1192. write_um(mod_key, mod, out_dir / files["um"])
  1193. def deploy():
  1194. BACKUP.mkdir(parents=True, exist_ok=True)
  1195. for mod_key, dl in DELIVER.items():
  1196. for old in dl["old"]:
  1197. src = PENDING / old
  1198. if src.exists():
  1199. dst = BACKUP / old
  1200. if dst.exists():
  1201. dst.unlink()
  1202. shutil.move(str(src), str(dst))
  1203. print("BAK", old)
  1204. for mod_key, dl in DELIVER.items():
  1205. for kind, fname in dl["files"].items():
  1206. src = OUT / fname
  1207. shutil.copy2(src, PENDING / fname)
  1208. print("DEP", fname)
  1209. def main():
  1210. do_deploy = len(sys.argv) > 1 and sys.argv[1] == "deploy"
  1211. generate_all(OUT)
  1212. if do_deploy:
  1213. deploy()
  1214. print("DONE", "deploy" if do_deploy else "gen")
  1215. if __name__ == "__main__":
  1216. main()