generate_detail_design_docs.js 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182
  1. /**
  2. * 生成 S1-S4 模块详细设计说明书 (DOCX)
  3. * 基于模板:软件系统详细设计说明书模板.docx
  4. * 输出文件:
  5. * - 【S1产销协同模块详细设计说明书】软件系统详细设计说明书模板.docx
  6. * - 【S2制造协同模块详细设计说明书】软件系统详细设计说明书模板.docx
  7. * - 【S3供应协同模块详细设计说明书】软件系统详细设计说明书模板.docx
  8. * - 【S4采购执行模块详细设计说明书】软件系统详细设计说明书模板.docx
  9. */
  10. const fs = require('fs');
  11. const path = require('path');
  12. const {
  13. Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
  14. HeadingLevel, AlignmentType, BorderStyle, WidthType, ShadingType,
  15. convertInchesToTwip, PageBreak, TabStopType, TabStopPosition,
  16. TableOfContents
  17. } = require('docx');
  18. // ═══════════════════════════════════════════════════
  19. // 通用样式与辅助函数
  20. // ═══════════════════════════════════════════════════
  21. const FONT = '微软雅黑';
  22. const FONT_BODY = '宋体';
  23. const thinBorder = {
  24. top: { style: BorderStyle.SINGLE, size: 1 },
  25. bottom: { style: BorderStyle.SINGLE, size: 1 },
  26. left: { style: BorderStyle.SINGLE, size: 1 },
  27. right: { style: BorderStyle.SINGLE, size: 1 },
  28. };
  29. const headerShading = { fill: '1F3864', type: ShadingType.CLEAR };
  30. const lightShading = { fill: 'D6E4F0', type: ShadingType.CLEAR };
  31. function p(text, opts = {}) {
  32. return new Paragraph({
  33. children: [new TextRun({ text, size: 21, font: FONT_BODY, ...opts })],
  34. spacing: { after: 120, line: 360 },
  35. });
  36. }
  37. function bp(text) { return p(text, { bold: true, font: FONT }); }
  38. function empty() { return new Paragraph({ spacing: { after: 80 }, children: [] }); }
  39. function pageBreak() { return new Paragraph({ children: [new PageBreak()] }); }
  40. function note(text) {
  41. return new Paragraph({
  42. children: [new TextRun({ text, size: 20, font: FONT_BODY, italics: true, color: '666666' })],
  43. spacing: { after: 80, line: 320 },
  44. });
  45. }
  46. function h1(text) {
  47. return new Paragraph({
  48. children: [new TextRun({ text, bold: true, size: 32, font: FONT })],
  49. heading: HeadingLevel.HEADING_1,
  50. spacing: { before: 400, after: 200 },
  51. });
  52. }
  53. function h2(text) {
  54. return new Paragraph({
  55. children: [new TextRun({ text, bold: true, size: 28, font: FONT })],
  56. heading: HeadingLevel.HEADING_2,
  57. spacing: { before: 300, after: 150 },
  58. });
  59. }
  60. function h3(text) {
  61. return new Paragraph({
  62. children: [new TextRun({ text, bold: true, size: 24, font: FONT })],
  63. heading: HeadingLevel.HEADING_3,
  64. spacing: { before: 200, after: 100 },
  65. });
  66. }
  67. function bullet(text, indent = 0) {
  68. return new Paragraph({
  69. children: [new TextRun({ text: ` ${text}`, size: 21, font: FONT_BODY })],
  70. spacing: { after: 60, line: 340 },
  71. indent: { left: 300 + indent * 400 },
  72. });
  73. }
  74. // Table helpers
  75. function hdrCell(text, w = 1800) {
  76. return new TableCell({
  77. children: [new Paragraph({ children: [new TextRun({ text, bold: true, size: 20, font: FONT, color: 'FFFFFF' })], alignment: AlignmentType.CENTER })],
  78. width: { size: w, type: WidthType.DXA }, borders: thinBorder, shading: headerShading,
  79. });
  80. }
  81. function tc(text, w = 1800, opts = {}) {
  82. const align = opts.center ? AlignmentType.CENTER : AlignmentType.LEFT;
  83. const bold = opts.bold || false;
  84. return new TableCell({
  85. children: [new Paragraph({ children: [new TextRun({ text: String(text ?? ''), size: 20, font: FONT_BODY, bold })], alignment: align })],
  86. width: { size: w, type: WidthType.DXA }, borders: thinBorder, shading: opts.shading || undefined,
  87. });
  88. }
  89. function kvCell(key, val, kW = 2000, vW = 7000) {
  90. return new TableRow({
  91. children: [
  92. tc(key, kW, { bold: true, shading: lightShading }),
  93. tc(val, vW),
  94. ],
  95. });
  96. }
  97. function table(headers, rows, widths) {
  98. return new Table({
  99. rows: [
  100. new TableRow({ children: headers.map((h, i) => hdrCell(h, widths ? widths[i] : 1800)), tableHeader: true }),
  101. ...rows.map(r => new TableRow({ children: r.map((c, i) => tc(c, widths ? widths[i] : 1800)) })),
  102. ],
  103. width: { size: 100, type: WidthType.PERCENTAGE },
  104. });
  105. }
  106. // TOC
  107. function buildTOC() {
  108. return [
  109. new TableOfContents('目录', { headingStyleRange: '1-3', hyperlink: true }),
  110. new Paragraph({
  111. children: [new TextRun({ text: '(如目录未显示,请在 Word 中右键此处 → 更新域)', size: 18, font: FONT, italics: true, color: '888888' })],
  112. spacing: { before: 40, after: 200 },
  113. }),
  114. ];
  115. }
  116. // Info table (2-col key-value)
  117. function infoTable(rows) {
  118. return new Table({
  119. rows: rows.map(([k, v]) => kvCell(k, v)),
  120. width: { size: 100, type: WidthType.PERCENTAGE },
  121. });
  122. }
  123. // ═══════════════════════════════════════════════════
  124. // 封面生成
  125. // ═══════════════════════════════════════════════════
  126. function buildCover(moduleCode, moduleName, docTitle) {
  127. const sections = [];
  128. sections.push(empty(), empty(), empty(), empty());
  129. // 标题行1:模块名
  130. sections.push(new Paragraph({
  131. children: [new TextRun({ text: `${moduleCode} ${moduleName}`, bold: true, size: 52, font: FONT, color: '1F4E79' })],
  132. alignment: AlignmentType.CENTER, spacing: { after: 100 },
  133. }));
  134. // 标题行2:文档类型
  135. sections.push(new Paragraph({
  136. children: [new TextRun({ text: docTitle, bold: true, size: 44, font: FONT, color: '1F4E79' })],
  137. alignment: AlignmentType.CENTER, spacing: { after: 300 },
  138. }));
  139. // 标题行3:系统名
  140. sections.push(new Paragraph({
  141. children: [new TextRun({ text: 'Ai-DOP智慧运营管理系统', size: 26, font: FONT, color: '333333' })],
  142. alignment: AlignmentType.CENTER, spacing: { after: 800 },
  143. }));
  144. // 信息表
  145. sections.push(infoTable([
  146. ['项目名称', 'Ai-DOP智慧运营管理系统'],
  147. ['系统名称', `${moduleCode} ${moduleName}`],
  148. ['文档版本', 'V1.0'],
  149. ['文档状态', '编制中'],
  150. ['编制单位', '智造易项目组'],
  151. ['编制日期', '2026-07-30'],
  152. ]));
  153. return sections;
  154. }
  155. // ═══════════════════════════════════════════════════
  156. // 模块数据定义
  157. // ═══════════════════════════════════════════════════
  158. // ── S1 产销协同 ──
  159. const S1 = {
  160. moduleCode: 'S1',
  161. moduleName: '产销协同',
  162. systemGoal: 'S1产销协同模块是Ai-DOP平台订单履约链路的起点,承担"从订单到交付"的产销协同管理职能。指导销售订单从接收→评审→排产→采购→生产→发运的全流程在线化协同,通过KPI指标体系监控产销协同健康度,驱动业务流程持续改善。',
  163. architecture: 'S1模块采用前后端分离架构,前端基于Vue 3 + Element Plus,后端基于.NET + Admin.NET框架,数据层采用MySQL + 数据中台分层架构(STG贴源层→STD标准层→DWD宽表层→KPI指标层)。',
  164. techStack: [
  165. ['前端', 'Vue 3 + Vite + TypeScript + Element Plus', '3.x', '用户界面与交互'],
  166. ['后端', '.NET 10 + Admin.NET + SqlSugar ORM', '10.0', '业务逻辑与API服务'],
  167. ['数据存储', 'MySQL 8.0', '8.0', '业务数据与中台数据'],
  168. ['基础设施', 'Docker + Nginx', '—', '容器化部署与反向代理'],
  169. ],
  170. modules: [
  171. ['S1-M01', '产品设计管理', '产品设计BOM和工艺路线的在线录入与维护', 'S0物料主数据'],
  172. ['S1-M02', '合同评审管理', '客户合同的多级审批与KPI考核', 'S0客户管理'],
  173. ['S1-M03', '订单评审管理', '销售订单的CRUD、交期评估与确认', 'S0物料/客户'],
  174. ['S1-M04', '订单交付管理', '8Tab全景追踪,从订单到发运全链路可视化', 'S1-M03, S2, S3, S4'],
  175. ['S1-M05', '订单发货管理', '发货计划、ASN发货、计划联动的在线管理', 'S1-M03'],
  176. ['S1-M06', '工单下达', '生产工单的物料齐套检查、MRP同步与逐单下达', 'S1-M03, S2'],
  177. ['S1-M07', '计划联动看板', '多源数据联动整合与手动刷新', 'S1-M03, S1-M05'],
  178. ['S1-M08', '需求明细核验', 'BOM需求展开与核验结果的在线查看', 'S1-M03'],
  179. ['S1-M09', '产销协同看板', 'L1/L2/L3/L4多层级KPI可视化监控', '全部S1模块'],
  180. ],
  181. funcList: [
  182. ['FUNC-S1-001', '产品设计管理', 'S1-M01', '设计员/计划工程师', '产品设计BOM和工艺路线的在线录入与维护'],
  183. ['FUNC-S1-002', '合同评审管理', 'S1-M02', '商务人员/审批人', '客户合同的多级审批流程管理'],
  184. ['FUNC-S1-003', '订单评审管理', 'S1-M03', '销售/计划员', '销售订单的在线录入、交期评估与确认'],
  185. ['FUNC-S1-004', '订单交付管理', 'S1-M04', '计划员/物流', '8Tab全景追踪全链路履约状态'],
  186. ['FUNC-S1-005', '订单发货管理', 'S1-M05', '物流/仓管', '发货单和ASN发货的在线管理'],
  187. ['FUNC-S1-006', '工单下达', 'S1-M06', '计划员/调度', '生产工单的物料齐套检查与逐单下达'],
  188. ['FUNC-S1-007', '计划联动看板', 'S1-M07', '计划工程师', '多源数据联动整合与手动刷新'],
  189. ['FUNC-S1-008', '需求明细核验', 'S1-M08', '计划工程师', 'BOM需求展开与核验结果查看'],
  190. ['FUNC-S1-009', '产销协同看板', 'S1-M09', '管理层/计划员', 'L1-L4多层级KPI可视化监控'],
  191. ],
  192. funcDetail: [
  193. {
  194. id: 'S1-M01', name: '产品设计管理', goal: '实现产品设计任务的在线管理,涵盖BOM和工艺路线的录入与维护', role: '设计员',
  195. precondition: '用户已登录,具有设计员权限;物料主数据已同步',
  196. flow: '产品设计新建 → BOM子表录入 → 工艺子表录入 → 保存生效',
  197. processes: [
  198. ['FUNC-S1-001', '产品设计任务管理', '产品需求信息', '新建/编辑/查询/删除设计任务;BOM子表增删行;工艺子表增删行', '产品设计记录', '物料编码、任务名称、计划完成日期为必填;BOM子表至少保留一行;采用直接保存模式无审批流', '保存失败时提示必填字段;物料编码不存在时远程搜索无结果'],
  199. ],
  200. pages: [
  201. ['/aidop/s1/order-mgmt/product-design', '列表页+详情抽屉', '新建/编辑/删除/搜索', '必填字段校验;物料编码唯一性', '设计员(编辑), 计划工程师(查看)'],
  202. ],
  203. verify: [
  204. ['1', '新建产品设计任务并保存', '任务正常创建,列表显示新记录'],
  205. ['2', 'BOM子表新增行并保存', 'BOM子表数据正确保存'],
  206. ['3', '工艺子表产线下拉框搜索', '下拉框正确显示产线列表'],
  207. ],
  208. },
  209. {
  210. id: 'S1-M03', name: '订单评审管理', goal: '实现销售订单的在线录入、交期评估与确认', role: '销售/计划员',
  211. precondition: '用户已登录;物料和客户主数据已同步',
  212. flow: '订单信息录入 → 订单评审(交期评估) → 交期确认 → 如需变更则发起变更审批流',
  213. processes: [
  214. ['FUNC-S1-003', '订单管理', '销售需求/订单信息', '订单列表查询/新建/编辑/删除;订单评审执行;交期确认;订单变更申请', '已确认订单', '订单编号自动生成全局唯一;主流程无审批流;变更场景触发审批流;closed字段默认0', '订单号重复时自动生成新号;交期确认接口失败时提示错误'],
  215. ],
  216. pages: [
  217. ['/aidop/s1/order-mgmt/order', '订单列表页+详情抽屉', '查询/新建/编辑/删除/评审/确认/变更', '客户、物料、数量、交期必填', '销售(编辑), 计划员(评审/确认)'],
  218. ],
  219. verify: [
  220. ['1', '新建销售订单', '订单正常创建,编号自动生成'],
  221. ['2', '执行订单评审', '交期评估结果正确返回'],
  222. ['3', '发起订单变更', '变更审批流正常触发'],
  223. ],
  224. },
  225. {
  226. id: 'S1-M04', name: '订单交付管理', goal: '以订单行为粒度集中展示交付状态,实现全链路履约追踪', role: '计划员/物流',
  227. precondition: '订单已评审确认;数据中台宽表数据已同步',
  228. flow: '交付列表筛选查询 → 点击订单行 → 8Tab全景追踪(订单信息→评审→排程→物料需求→采购→备料→生产→入库发运)',
  229. processes: [
  230. ['FUNC-S1-004', '订单交付追踪', '筛选条件', '交付列表查询;8Tab详情查看;交付状态跟踪', '交付状态数据', '数据来源dwd_ship_trans宽表;只取最新批次;跨模块Tab渐进就绪', '宽表数据未同步时显示空状态'],
  231. ],
  232. pages: [
  233. ['/aidop/s1/order-mgmt/orderDelivery', '交付列表+8Tab详情页', '筛选查询/点击查看详情', '—', '计划员/物流/销售(查看)'],
  234. ],
  235. verify: [
  236. ['1', '查看交付列表', '列表正确展示交付状态'],
  237. ['2', '点击订单行进入详情', '8Tab正确加载对应数据'],
  238. ],
  239. },
  240. {
  241. id: 'S1-M05', name: '订单发货管理', goal: '实现发货单和ASN发货的在线管理,与销售订单联动', role: '物流/仓管',
  242. precondition: '订单已确认;销售订单数据已存在',
  243. flow: '发货计划制定 → 发货单新建 → 选择销售单号 → 填写发货明细 → 保存 → MDP数据同步',
  244. processes: [
  245. ['FUNC-S1-005', '发货单管理', '销售订单/发货信息', '发货单列表查询/新建/编辑/删除;ASN发货录入;明细行管理', '发货单/ASN记录', '发货单号SH+日期+流水号;已发货不可删除;销售单号下拉远程搜索', '重复发货提示;已发货删除拦截'],
  246. ],
  247. pages: [
  248. ['/aidop/s1/order-mgmt/asnShipper', '发货单列表+表单', '新建/编辑/删除/搜索', '销售单号、客户、物料必填', '物流/仓管(编辑), 计划员(查看)'],
  249. ],
  250. verify: [
  251. ['1', '新建发货单并关联销售单号', '发货单创建成功,关联正确'],
  252. ['2', 'ASN发货录入', 'ASN记录正确保存'],
  253. ],
  254. },
  255. {
  256. id: 'S1-M06', name: '工单下达', goal: '管理生产工单的下达,是产销协同到制造执行的衔接环节', role: '计划员/调度',
  257. precondition: '订单已评审确认;物料需求计划已生成',
  258. flow: '工单列表 → 物料齐套检查 → 生成物料需求(MRP) → 逐行点击工单下达 → 确认下达 → MES可见',
  259. processes: [
  260. ['FUNC-S1-006', '工单下达管理', '工单列表', '工单列表查询;物料齐套检查;生成物料需求;逐单下达', '已下达工单', '工单状态待下达→已下达;防重复下达;逐单操作非批量', '已下达工单重复下达拦截;齐套检查失败提示'],
  261. ],
  262. pages: [
  263. ['/aidop/s1/workorder-mgmt/dispatch', '工单列表页+下达表单', '查询/齐套检查/物料需求/逐行下达', '开工日期、生产批号必填', '计划员/调度(操作)'],
  264. ],
  265. verify: [
  266. ['1', '执行物料齐套检查', '齐套状态正确更新'],
  267. ['2', '逐行点击工单下达', '工单状态变更为已下达'],
  268. ],
  269. },
  270. {
  271. id: 'S1-M02', name: '合同评审管理', goal: '实现客户合同的在线评审管理,通过审批流管控多级审核', role: '商务人员/审批人',
  272. precondition: '审批流已配置发布;用户具有相应权限',
  273. flow: '合同录入 → 合同评审列表 → 提交审批 → 多级审批流转 → 审核通过/驳回 → KPI计算',
  274. processes: [
  275. ['FUNC-S1-002', '合同评审管理', '合同信息', '合同评审列表查询/新建/编辑;提交审批流;审批流操作', '审批结果', '审批流类型CONTRACT_REVIEW;KPI自动计算;节点耗时单独统计', '审批流未配置时提示;审批人不存在时提示'],
  276. ],
  277. pages: [
  278. ['/aidop/s1/order-mgmt/contract-review', '合同评审列表+表单', '查询/新建/编辑/提交审批', '合同编号、客户、签订日期必填', '商务(编辑), 审批人(审核)'],
  279. ],
  280. verify: [
  281. ['1', '新建合同评审并提交审批', '审批流正常启动'],
  282. ['2', '审批人审批通过', '合同状态更新为已通过'],
  283. ],
  284. },
  285. {
  286. id: 'S1-M07', name: '计划联动看板', goal: '实现销售订单、发货计划、ASN发货等业务数据的联动整合', role: '计划工程师',
  287. precondition: 'MDP作业已配置;业务数据已存在',
  288. flow: '查看联动列表 → 点击手动刷新 → MDP执行全量同步转换 → STG→STD→DWD→KPI链路 → 返回最新联动结果',
  289. processes: [
  290. ['FUNC-S1-007', '计划联动刷新', '刷新请求', '查看联动列表;手动触发全量同步转换;查看联动结果', '最新联动数据', '作业编码S1_MDP_SYNC_TRANSFORM;批次格式S1_MDP_FULL_yyyyMMddHHmmss', 'MDP作业执行失败时记录日志'],
  291. ],
  292. pages: [
  293. ['/aidop/s1/SalesKanBan/linkage-plan', '联动列表+刷新按钮', '查看/手动刷新', '—', '计划工程师(操作)'],
  294. ],
  295. verify: [
  296. ['1', '点击手动刷新按钮', 'MDP作业正常触发执行'],
  297. ['2', '查看刷新后联动结果', '联动数据正确更新'],
  298. ],
  299. },
  300. {
  301. id: 'S1-M09', name: '产销协同看板', goal: '为管理层和业务人员提供S1模块核心KPI可视化看板', role: '管理层/计划员',
  302. precondition: 'KPI数据已通过MDP计算写入',
  303. flow: '进入看板 → L1核心指标卡片 → 趋势图表 → 客户筛选 → 指标下钻L2→L3→L4',
  304. processes: [
  305. ['FUNC-S1-009', '产销协同看板', 'KPI数据', 'L1-L4指标展示;客户维度筛选;指标下钻;趋势分析', '可视化看板', 'DynamicModuleDashboard组件;module-code=S1;L1 4项核心指标', 'KPI数据未计算时显示空状态'],
  306. ],
  307. pages: [
  308. ['/aidop/kanban/s1', '看板主页', '查看/筛选/下钻', '—', '管理层(全部), 计划员(查看)'],
  309. ],
  310. verify: [
  311. ['1', '查看L1核心指标卡片', '4项核心指标正确显示'],
  312. ['2', '客户维度筛选', '看板数据按客户正确过滤'],
  313. ],
  314. },
  315. ],
  316. dbTables: [
  317. ['crm_seorder', '销售订单表', '存储销售订单主数据', 'S1-M03'],
  318. ['crm_seorderentry', '销售订单明细表', '存储订单行明细数据', 'S1-M03'],
  319. ['crm_seorder_change', '订单变更表', '存储订单变更申请记录', 'S1-M03'],
  320. ['ado_contract_review', '合同评审表', '存储合同评审数据', 'S1-M02'],
  321. ['ado_product_design', '产品设计表', '存储产品设计任务数据', 'S1-M01'],
  322. ['ShippingPlan', '发货计划表', '存储发货计划数据', 'S1-M05'],
  323. ['ASNBOLShipper', 'ASN发货表', '存储ASN发货记录', 'S1-M05'],
  324. ['LinkagePlan', '计划联动表', '存储计划联动数据', 'S1-M07'],
  325. ['WorkOrdMaster', '工单主表', '存储生产工单主数据', 'S1-M06'],
  326. ['mdp_stg_so', '销售贴源表', 'S1销售域贴源层数据', '数据中台'],
  327. ['mdp_std_so', '销售标准表', 'S1销售域标准层数据', '数据中台'],
  328. ['dwd_ship_trans', '发运宽表', 'S1交付发运主题宽表', '数据中台'],
  329. ['dwd_requirement_examine_detail', '需求核验宽表', 'S1需求核验主题宽表', '数据中台'],
  330. ['ado_s9_kpi_value_l1_day', 'L1指标表', 'S1 L1层KPI日指标值', '数据中台'],
  331. ['ado_s9_kpi_value_l2_day', 'L2指标表', 'S1 L2层KPI日指标值', '数据中台'],
  332. ],
  333. apiList: [
  334. ['API-S1-001', '订单列表查询', '入站', 'REST', 'JWT Token', 'S1-M03'],
  335. ['API-S1-002', '订单评审/交期确认', '入站', 'REST', 'JWT Token', 'S1-M03'],
  336. ['API-S1-003', '订单交付列表', '入站', 'REST', 'JWT Token', 'S1-M04'],
  337. ['API-S1-004', '订单交付详情(8Tab)', '入站', 'REST', 'JWT Token', 'S1-M04'],
  338. ['API-S1-005', '发货单CRUD', '入站', 'REST', 'JWT Token', 'S1-M05'],
  339. ['API-S1-006', '工单下达列表/操作', '入站', 'REST', 'JWT Token', 'S1-M06'],
  340. ['API-S1-007', '计划联动手动刷新', '入站', 'REST', 'JWT Token', 'S1-M07'],
  341. ['API-S1-008', '需求核验列表', '入站', 'REST', 'JWT Token', 'S1-M08'],
  342. ['API-S1-009', '看板聚合数据', '入站', 'REST', 'JWT Token', 'S1-M09'],
  343. ['API-S1-010', 'MDP数据同步(外部)', '出站', 'MDP', '—', '数据中台'],
  344. ],
  345. };
  346. // ── S2 制造协同 ──
  347. const S2 = {
  348. moduleCode: 'S2',
  349. moduleName: '制造协同',
  350. systemGoal: 'S2制造协同模块承接S1工单下达后的生产排程与执行管理,实现从"排程优化"到"日计划执行"的制造协同闭环。核心能力包括基于产能约束的智能排程、可执行日计划的生成与跟踪、产线日历管理、以及工单执行进度的全程可视化监控。',
  351. architecture: 'S2模块采用前后端分离架构,前端基于Vue 3 + Element Plus,后端基于.NET + Admin.NET框架,排程引擎采用独立计算服务,数据层采用MySQL存储。',
  352. techStack: [
  353. ['前端', 'Vue 3 + Vite + TypeScript + Element Plus', '3.x', '用户界面与交互'],
  354. ['后端', '.NET 10 + Admin.NET + SqlSugar ORM', '10.0', '业务逻辑与排程API'],
  355. ['数据存储', 'MySQL 8.0', '8.0', '排程数据与执行数据'],
  356. ['基础设施', 'Docker + Nginx', '—', '容器化部署与反向代理'],
  357. ],
  358. modules: [
  359. ['S2-M01', '生产排程', '基于产能约束的工单排程计算与结果管理', 'S1工单下达, S0产线/BOM'],
  360. ['S2-M02', '排产异常记录', '排程过程中产生的异常信息记录与查询', 'S2-M01'],
  361. ['S2-M03', '可执行日计划', '排程结果转化为每日可执行计划', 'S2-M01'],
  362. ['S2-M04', '产线日历管理', '产线工作日历、休息时间、节假日管理', 'S0产线管理'],
  363. ['S2-M05', '产线加班管理', '产线加班时间配置与管理', 'S0产线管理'],
  364. ['S2-M06', '工单执行追踪', '工单执行进度、物料明细、工序明细的跟踪', 'S2-M01, S2-M03'],
  365. ['S2-M07', '制造协同看板', 'S2模块KPI可视化监控', '全部S2模块'],
  366. ],
  367. funcList: [
  368. ['FUNC-S2-001', '生产排程', 'S2-M01', '计划员/调度', '基于产能约束的工单排程计算'],
  369. ['FUNC-S2-002', '排产异常记录', 'S2-M02', '计划员/调度', '排程异常信息记录与查询'],
  370. ['FUNC-S2-003', '可执行日计划', 'S2-M03', '计划员/调度', '排程结果转化为每日可执行计划'],
  371. ['FUNC-S2-004', '产线工作日历管理', 'S2-M04', '计划员', '产线工作日历的维护管理'],
  372. ['FUNC-S2-005', '产线休息时间管理', 'S2-M04', '计划员', '产线休息时间的配置管理'],
  373. ['FUNC-S2-006', '产线节假日管理', 'S2-M04', '计划员', '产线节假日的维护管理'],
  374. ['FUNC-S2-007', '产线加班管理', 'S2-M05', '计划员', '产线加班时间的配置管理'],
  375. ['FUNC-S2-008', '工单执行进度看板', 'S2-M06', '管理层/调度', '工单执行进度的可视化监控'],
  376. ['FUNC-S2-009', 'S2制造协同看板(KPI)', 'S2-M07', '管理层', 'S2模块KPI指标可视化'],
  377. ['FUNC-S2-010', '工单执行追踪', 'S2-M06', '调度', '工单执行过程的详细追踪'],
  378. ['FUNC-S2-011', '工单物料明细', 'S2-M06', '调度', '工单物料消耗明细查询'],
  379. ['FUNC-S2-012', '工单工序明细', 'S2-M06', '调度', '工单工序执行明细查询'],
  380. ],
  381. funcDetail: [
  382. {
  383. id: 'S2-M01', name: '生产排程', goal: '基于产能约束、物料齐套、优先级等条件,对已下达工单进行智能排程计算', role: '计划员/调度',
  384. precondition: '工单已下达;产线产能数据已配置;工作日历已设置',
  385. flow: '排程列表 → 选择排程条件 → 触发排程计算 → 查看排程结果 → 排程结果写入ScheduleResultOpMaster',
  386. processes: [
  387. ['FUNC-S2-001', '生产排程计算', '工单列表/排程条件', '排程列表查询;排程参数设置;触发排程计算;查看排程结果甘特图', '排程结果(ScheduleResultOpMaster)', '排程优先级ASC排序;考虑产能/物料/交期约束;排程结果写入ScheduleResultOpMaster', '排程计算超时;产能不足提示'],
  388. ],
  389. pages: [
  390. ['/aidop/s2/production-scheduling/work-order-scheduling', '排程列表+甘特图', '查询/排程/查看结果', '排程参数必选', '计划员/调度(操作)'],
  391. ],
  392. verify: [
  393. ['1', '触发排程计算', '排程结果正确生成'],
  394. ['2', '查看甘特图', '工单排程可视化展示正确'],
  395. ],
  396. },
  397. {
  398. id: 'S2-M03', name: '可执行日计划', goal: '将排程结果转化为每日可执行的生产计划,指导车间生产执行', role: '计划员/调度',
  399. precondition: '排程已执行;排程结果已生成',
  400. flow: '日计划列表 → 按PlanDate排序 → 查看每日任务 → 查看模具分配/产能信息',
  401. processes: [
  402. ['FUNC-S2-003', '可执行日计划查看', '排程结果', '日计划列表查询;按日期筛选;查看模具分配数量', '日计划数据', '按PlanDate排序;MoldAllocationCount字段显示模具分配数', '无排程数据时显示空列表'],
  403. ],
  404. pages: [
  405. ['/aidop/s2/operation-plan/executable-daily-plan', '日计划列表', '查询/筛选', '—', '计划员/调度(查看)'],
  406. ],
  407. verify: [
  408. ['1', '查看日计划列表', '按日期正确展示日计划'],
  409. ['2', '查看模具分配', 'MoldAllocationCount正确显示'],
  410. ],
  411. },
  412. {
  413. id: 'S2-M04', name: '产线日历管理', goal: '管理产线的工作日历、休息时间和节假日,为排程提供产能约束基础数据', role: '计划员',
  414. precondition: '产线主数据已配置',
  415. flow: '日历配置 → 休息时间设置 → 节假日维护 → 排程引用',
  416. processes: [
  417. ['FUNC-S2-004', '工作日历', '产线/日期', '工作日历CRUD;休息时间配置;节假日配置', '日历配置', '日历与产线关联;休息时间支持多时段', '产线未选择时提示'],
  418. ],
  419. pages: [
  420. ['/aidop/s2/operation-plan/line-work-calendar', '日历列表', '查询/新增/编辑/删除', '产线、日期必填', '计划员(编辑)'],
  421. ],
  422. verify: [
  423. ['1', '新增工作日历', '日历正确创建'],
  424. ['2', '设置休息时间', '休息时间正确保存'],
  425. ],
  426. },
  427. {
  428. id: 'S2-M06', name: '工单执行追踪', goal: '跟踪工单从下达到完成的执行全过程,包括物料消耗和工序进度', role: '调度',
  429. precondition: '工单已下达;排程已完成',
  430. flow: '工单列表 → 查看工单执行状态 → 查看物料明细 → 查看工序明细',
  431. processes: [
  432. ['FUNC-S2-010', '工单执行追踪', '工单号', '工单执行状态查询;物料明细查看;工序明细查看', '执行状态数据', '工单状态W/S/R/P流转;物料明细关联WorkOrdDetail', '工单不存在时提示'],
  433. ],
  434. pages: [
  435. ['/aidop/production/work-order-trace', '工单追踪列表', '查询/查看详情', '—', '调度(查看)'],
  436. ],
  437. verify: [
  438. ['1', '查看工单执行状态', '状态正确显示'],
  439. ['2', '查看物料明细', '物料消耗数据正确'],
  440. ],
  441. },
  442. {
  443. id: 'S2-M07', name: '制造协同看板', goal: '为管理层提供S2模块核心KPI可视化监控', role: '管理层',
  444. precondition: 'KPI数据已计算写入',
  445. flow: '进入看板 → L1核心指标 → 趋势分析 → 指标下钻',
  446. processes: [
  447. ['FUNC-S2-009', '制造协同看板', 'KPI数据', 'L1-L2指标展示;趋势分析', '可视化看板', 'module-code=S2', 'KPI数据未计算时显示空状态'],
  448. ],
  449. pages: [
  450. ['/aidop/kanban/s2', '看板主页', '查看/筛选', '—', '管理层(全部)'],
  451. ],
  452. verify: [
  453. ['1', '查看S2看板', 'KPI指标正确显示'],
  454. ],
  455. },
  456. ],
  457. dbTables: [
  458. ['WorkOrdMaster', '工单主表', '存储生产工单主数据', 'S2-M01'],
  459. ['WorkOrdDetail', '工单明细表', '存储工单物料明细', 'S2-M06'],
  460. ['ScheduleResultOpMaster', '排程结果主表', '存储排程计算结果', 'S2-M01'],
  461. ['ScheduleExceptionMaster', '排程异常表', '存储排程异常记录', 'S2-M02'],
  462. ['PeriodSequenceDet', '周期排程明细表', '存储排程周期明细', 'S2-M01'],
  463. ['LineMaster', '产线主表', '存储产线基础数据', 'S2-M04'],
  464. ['ShopCalendarWorkCtr', '工作日历表', '存储产线工作日历', 'S2-M04'],
  465. ['LineOvertime', '产线加班表', '存储产线加班配置', 'S2-M05'],
  466. ['HolidayMaster', '节假日表', '存储节假日配置', 'S2-M04'],
  467. ['QualityLineRestDetail', '产线休息时间表', '存储产线休息时间明细', 'S2-M04'],
  468. ['ado_s9_kpi_value_l1_day', 'L1指标表', 'S2 L1层KPI日指标值', '数据中台'],
  469. ['ado_s9_kpi_value_l2_day', 'L2指标表', 'S2 L2层KPI日指标值', '数据中台'],
  470. ],
  471. apiList: [
  472. ['API-S2-001', '排程计算', '入站', 'REST', 'JWT Token', 'S2-M01'],
  473. ['API-S2-002', '排程结果查询', '入站', 'REST', 'JWT Token', 'S2-M01'],
  474. ['API-S2-003', '可执行日计划查询', '入站', 'REST', 'JWT Token', 'S2-M03'],
  475. ['API-S2-004', '工作日历CRUD', '入站', 'REST', 'JWT Token', 'S2-M04'],
  476. ['API-S2-005', '工单执行追踪', '入站', 'REST', 'JWT Token', 'S2-M06'],
  477. ['API-S2-006', '制造协同看板', '入站', 'REST', 'JWT Token', 'S2-M07'],
  478. ],
  479. };
  480. // ── S3 供应协同 ──
  481. const S3 = {
  482. moduleCode: 'S3',
  483. moduleName: '供应协同',
  484. systemGoal: 'S3供应协同模块承接S2排程后的物料需求,实现从"物料需求计划"到"采购订单执行"的供应协同闭环。核心能力包括物料需求计划(MRP)的生成与管理、物料交货计划的制定与跟踪、采购申请与采购订单的全流程管理、委外加工订单与工序外协订单的管理,以及供应协同KPI的实时监控。',
  485. architecture: 'S3模块采用前后端分离架构,前端基于Vue 3 + Element Plus,后端基于.NET + Admin.NET框架,数据层采用MySQL + 数据中台分层架构(S3试点已打通STG→STD→DWD→KPI全链路)。',
  486. techStack: [
  487. ['前端', 'Vue 3 + Vite + TypeScript + Element Plus', '3.x', '用户界面与交互'],
  488. ['后端', '.NET 10 + Admin.NET + SqlSugar ORM', '10.0', '业务逻辑与MRP计算'],
  489. ['数据存储', 'MySQL 8.0', '8.0', '供应数据与中台数据'],
  490. ['基础设施', 'Docker + Nginx + MDP调度', '—', '容器化部署与数据同步'],
  491. ],
  492. modules: [
  493. ['S3-M01', '物料需求计划', 'MRP计算与物料需求计划的生成管理', 'S2排程结果, S0 BOM'],
  494. ['S3-M02', '物料交货计划', '供应商交货计划的制定与跟踪', 'S3-M01'],
  495. ['S3-M03', '交货单异常记录', '交货异常情况的记录与跟踪', 'S3-M02'],
  496. ['S3-M04', '物料采购申请', '采购申请的生成与审批管理', 'S3-M01'],
  497. ['S3-M05', '要货令', '向供应商发出的要货指令管理', 'S3-M04'],
  498. ['S3-M06', '物料采购订单', '采购订单的全流程管理', 'S3-M04, S3-M05'],
  499. ['S3-M07', '委外加工订单', '委外加工订单的创建与管理', 'S3-M04'],
  500. ['S3-M08', '工序外协订单', '工序外协订单的创建与管理', 'S3-M04'],
  501. ['S3-M09', '供应协同看板', 'S3模块KPI可视化监控', '全部S3模块'],
  502. ['S3-M10', '工单物料齐套看板', '工单物料齐套状态的可视化监控', 'S3-M01, S2-M01'],
  503. ['S3-M11', 'MDP运行监控', '数据中台作业运行状态监控', '数据中台'],
  504. ],
  505. funcList: [
  506. ['FUNC-S3-001', '物料需求计划', 'S3-M01', '计划员', 'MRP计算与物料需求计划管理'],
  507. ['FUNC-S3-002', '物料交货计划', 'S3-M02', '采购员/计划员', '供应商交货计划的制定与跟踪'],
  508. ['FUNC-S3-003', '交货单异常记录', 'S3-M03', '采购员', '交货异常记录与跟踪'],
  509. ['FUNC-S3-004', '物料采购申请', 'S3-M04', '计划员', '采购申请的生成与审批'],
  510. ['FUNC-S3-005', '要货令', 'S3-M05', '采购员', '向供应商发出的要货指令'],
  511. ['FUNC-S3-006', '物料采购订单', 'S3-M06', '采购员', '采购订单的全流程管理'],
  512. ['FUNC-S3-007', '委外加工订单', 'S3-M07', '采购员', '委外加工订单管理'],
  513. ['FUNC-S3-008', '工序外协订单', 'S3-M08', '采购员', '工序外协订单管理'],
  514. ['FUNC-S3-009', '供应协同看板', 'S3-M09', '管理层', 'S3 KPI可视化监控'],
  515. ['FUNC-S3-010', '工单物料齐套看板', 'S3-M10', '调度/计划员', '工单物料齐套状态监控'],
  516. ['FUNC-S3-011', 'MDP运行监控', 'S3-M11', '系统管理员', '数据中台作业运行状态'],
  517. ['FUNC-S3-012', '委外采购明细', 'S3-M07', '采购员', '委外采购明细查询'],
  518. ],
  519. funcDetail: [
  520. {
  521. id: 'S3-M01', name: '物料需求计划', goal: '基于排程结果和BOM展开,计算物料需求计划(MRP)', role: '计划员',
  522. precondition: '排程已完成;BOM数据已维护',
  523. flow: '需求计划列表 → 触发MRP计算 → 查看需求结果 → 生成采购申请',
  524. processes: [
  525. ['FUNC-S3-001', '物料需求计划', '排程结果/BOM', 'MRP计算触发;需求列表查询;需求结果查看', '物料需求计划', 'MRP幂等生成;基于BOM展开计算需求数量', 'MRP计算超时;BOM数据缺失提示'],
  526. ],
  527. pages: [
  528. ['/aidop/s3/material-plan/demand-schedule', '需求计划列表', '查询/触发MRP', '—', '计划员(操作)'],
  529. ],
  530. verify: [
  531. ['1', '触发MRP计算', '需求计划正确生成'],
  532. ['2', '查看需求明细', '物料需求数量和日期正确'],
  533. ],
  534. },
  535. {
  536. id: 'S3-M02', name: '物料交货计划', goal: '制定供应商物料交货计划,跟踪交货执行状态', role: '采购员/计划员',
  537. precondition: '物料需求计划已生成;供应商已维护',
  538. flow: '交货计划列表 → 制定交货计划 → 分配供应商 → 跟踪交货状态',
  539. processes: [
  540. ['FUNC-S3-002', '物料交货计划', '物料需求/供应商', '交货计划制定;交货状态跟踪;批量操作', '交货计划', '交货计划与采购申请关联;支持批量制定', '供应商不存在时提示'],
  541. ],
  542. pages: [
  543. ['/aidop/s3/material-plan/delivery-schedule', '交货计划列表', '查询/新增/编辑/批量制定', '物料、供应商、交货日期必填', '采购员/计划员(编辑)'],
  544. ],
  545. verify: [
  546. ['1', '制定交货计划', '交货计划正确创建'],
  547. ['2', '批量制定交货计划', '批量操作正确执行'],
  548. ],
  549. },
  550. {
  551. id: 'S3-M04', name: '物料采购申请', goal: '管理物料采购申请的生成、审批与执行追踪', role: '计划员',
  552. precondition: '物料需求计划已生成',
  553. flow: '采购申请列表 → 新建采购申请 → 选择需求物料 → 提交审批 → 审批通过 → 生成采购订单',
  554. processes: [
  555. ['FUNC-S3-004', '物料采购申请', '物料需求', '采购申请列表查询/新建/编辑;提交审批', '采购申请单', '采购申请state状态流转(1→2→5);幂等生成防重复', '重复生成拦截;审批流未配置提示'],
  556. ],
  557. pages: [
  558. ['/aidop/s3/procurement/purchase-request', '采购申请列表+表单', '查询/新建/编辑/删除', '物料、数量、需求日期必填', '计划员(编辑)'],
  559. ],
  560. verify: [
  561. ['1', '新建采购申请', '申请单正确创建'],
  562. ['2', '提交审批', '审批流正常启动'],
  563. ],
  564. },
  565. {
  566. id: 'S3-M06', name: '物料采购订单', goal: '管理采购订单的全流程,从创建到执行跟踪', role: '采购员',
  567. precondition: '采购申请已审批通过;供应商已维护',
  568. flow: '采购订单列表 → 新建采购订单 → 关联采购申请 → 下达供应商 → 跟踪执行状态',
  569. processes: [
  570. ['FUNC-S3-006', '物料采购订单', '采购申请/供应商', '采购订单列表查询/新建/编辑;关联采购申请;下达供应商', '采购订单', '采购订单与采购申请关联;订单状态流转', '采购申请已关联时提示'],
  571. ],
  572. pages: [
  573. ['/aidop/s3/procurement/purchase-order', '采购订单列表', '查询/新建/编辑', '供应商、物料、数量必填', '采购员(编辑)'],
  574. ],
  575. verify: [
  576. ['1', '新建采购订单', '订单正确创建并关联采购申请'],
  577. ['2', '下达供应商', '订单状态正确更新'],
  578. ],
  579. },
  580. {
  581. id: 'S3-M05', name: '要货令', goal: '向供应商发出要货指令,驱动供应商按计划交货', role: '采购员',
  582. precondition: '采购订单已创建;供应商已确认',
  583. flow: '要货令列表 → 新建要货令 → 选择采购订单 → 填写要货信息 → 下达供应商',
  584. processes: [
  585. ['FUNC-S3-005', '要货令管理', '采购订单/物料需求', '要货令列表查询/新建/编辑;关联采购订单', '要货令', '要货令与采购订单关联;支持远程搜索物料', '物料不存在时提示'],
  586. ],
  587. pages: [
  588. ['/aidop/s3/procurement/demand-order', '要货令列表+表单', '查询/新建/编辑', '物料、数量、交货日期必填', '采购员(编辑)'],
  589. ],
  590. verify: [
  591. ['1', '新建要货令', '要货令正确创建'],
  592. ['2', '关联采购订单', '采购订单信息正确回显'],
  593. ],
  594. },
  595. {
  596. id: 'S3-M07', name: '委外加工订单', goal: '管理委外加工订单的创建、执行与跟踪', role: '采购员',
  597. precondition: '物料需求已生成;委外供应商已维护',
  598. flow: '委外订单列表 → 新建委外订单 → 填写委外信息 → 下达供应商 → 跟踪执行',
  599. processes: [
  600. ['FUNC-S3-007', '委外加工订单', '物料需求/供应商', '委外订单CRUD;委外明细管理;状态跟踪', '委外加工订单', '委外订单与采购申请关联;明细行管理', '供应商不存在时提示'],
  601. ],
  602. pages: [
  603. ['/aidop/s3/procurement/outsource-order', '委外订单列表+表单', '查询/新建/编辑/删除', '供应商、物料、数量必填', '采购员(编辑)'],
  604. ],
  605. verify: [
  606. ['1', '新建委外订单', '订单正确创建'],
  607. ['2', '管理委外明细', '明细行正确增删'],
  608. ],
  609. },
  610. {
  611. id: 'S3-M10', name: '工单物料齐套看板', goal: '实时监控工单物料齐套状态,识别缺料风险', role: '调度/计划员',
  612. precondition: '工单已下达;物料需求已计算',
  613. flow: '齐套看板 → 按工单查看齐套状态 → 识别缺料物料 → 触发紧急采购',
  614. processes: [
  615. ['FUNC-S3-010', '物料齐套看板', '工单物料需求', '齐套状态查询;缺料分析;工单维度筛选', '齐套状态数据', '基于dwd齐套宽表;缺料数量=需求-库存-在途', '数据未同步时显示空状态'],
  616. ],
  617. pages: [
  618. ['/aidop/s3/supply-kanban/work-order-material-readiness', '齐套看板', '查询/筛选', '—', '调度/计划员(查看)'],
  619. ],
  620. verify: [
  621. ['1', '查看工单齐套状态', '齐套/缺料状态正确显示'],
  622. ['2', '识别缺料物料', '缺料物料清单正确'],
  623. ],
  624. },
  625. ],
  626. dbTables: [
  627. ['ic_demandschedule', '需求计划表', '存储物料需求计划数据', 'S3-M01'],
  628. ['PurOrdMaster', '采购订单主表', '存储采购订单主数据', 'S3-M06'],
  629. ['PurOrdDetail', '采购订单明细表', '存储采购订单明细数据', 'S3-M06'],
  630. ['ic_purchase_request', '采购申请表', '存储采购申请数据', 'S3-M04'],
  631. ['ic_demand_order', '要货令表', '存储要货令数据', 'S3-M05'],
  632. ['OutsourceOrderMaster', '委外订单主表', '存储委外加工订单数据', 'S3-M07'],
  633. ['ProcessOutsourceOrder', '工序外协订单表', '存储工序外协订单数据', 'S3-M08'],
  634. ['dwd_supplier_delivery', '供应商交货宽表', '供应商交货主题宽表', '数据中台'],
  635. ['mdp_stg_purchase_order', '采购贴源表', '采购域贴源层数据', '数据中台'],
  636. ['mdp_std_purchase_order', '采购标准表', '采购域标准层数据', '数据中台'],
  637. ['ado_s9_kpi_value_l1_day', 'L1指标表', 'S3 L1层KPI日指标值', '数据中台'],
  638. ['ado_s9_kpi_value_l2_day', 'L2指标表', 'S3 L2层KPI日指标值', '数据中台'],
  639. ],
  640. apiList: [
  641. ['API-S3-001', '物料需求计划查询', '入站', 'REST', 'JWT Token', 'S3-M01'],
  642. ['API-S3-002', '交货计划CRUD', '入站', 'REST', 'JWT Token', 'S3-M02'],
  643. ['API-S3-003', '采购申请CRUD', '入站', 'REST', 'JWT Token', 'S3-M04'],
  644. ['API-S3-004', '采购订单CRUD', '入站', 'REST', 'JWT Token', 'S3-M06'],
  645. ['API-S3-005', '要货令CRUD', '入站', 'REST', 'JWT Token', 'S3-M05'],
  646. ['API-S3-006', '委外订单CRUD', '入站', 'REST', 'JWT Token', 'S3-M07'],
  647. ['API-S3-007', '齐套看板查询', '入站', 'REST', 'JWT Token', 'S3-M10'],
  648. ['API-S3-008', 'MDP同步转换(外部)', '出站', 'MDP', '—', '数据中台'],
  649. ],
  650. };
  651. // ── S4 采购执行 ──
  652. const S4 = {
  653. moduleCode: 'S4',
  654. moduleName: '采购执行',
  655. systemGoal: 'S4采购执行模块承接S3采购订单后的执行跟踪与交付管理,实现从"供应商交货"到"采购退货"的采购执行闭环。核心能力包括供应商交货管理、供应商发货单管理、采购退货单管理、IQC退货查询,以及采购执行KPI的可视化监控。',
  656. architecture: 'S4模块采用前后端分离架构,前端基于Vue 3 + Element Plus,后端基于.NET + Admin.NET框架,数据层采用MySQL存储,与S3供应协同模块紧密集成。',
  657. techStack: [
  658. ['前端', 'Vue 3 + Vite + TypeScript + Element Plus', '3.x', '用户界面与交互'],
  659. ['后端', '.NET 10 + Admin.NET + SqlSugar ORM', '10.0', '业务逻辑与采购执行API'],
  660. ['数据存储', 'MySQL 8.0', '8.0', '采购执行数据'],
  661. ['基础设施', 'Docker + Nginx', '—', '容器化部署与反向代理'],
  662. ],
  663. modules: [
  664. ['S4-M01', '供应商交货管理', '供应商交货计划的跟踪与执行管理', 'S3采购订单'],
  665. ['S4-M02', '供应商发货单', '供应商发货单的创建与管理', 'S4-M01'],
  666. ['S4-M03', '采购退货单', '采购退货单的创建与审批管理', 'S4-M01, S5收货'],
  667. ['S4-M04', 'IQC退货查询', '来料检验退货结果的查询', 'S5 IQC'],
  668. ['S4-M05', '采购执行看板', 'S4模块KPI可视化监控', '全部S4模块'],
  669. ['S4-M06', '供应商欠料看板', '供应商欠料状态的可视化监控', 'S4-M01'],
  670. ],
  671. funcList: [
  672. ['FUNC-S4-001', '供应商交货管理', 'S4-M01', '采购员/仓管', '供应商交货计划的跟踪与执行'],
  673. ['FUNC-S4-002', '供应商发货单', 'S4-M02', '采购员/仓管', '供应商发货单的创建与管理'],
  674. ['FUNC-S4-003', '采购退货单', 'S4-M03', '采购员/仓管', '采购退货单的创建与审批'],
  675. ['FUNC-S4-004', 'IQC退货查询', 'S4-M04', '质量/仓管', '来料检验退货结果查询'],
  676. ['FUNC-S4-005', '采购执行看板主页', 'S4-M05', '管理层', 'S4 KPI可视化监控'],
  677. ['FUNC-S4-006', '供应商欠料看板', 'S4-M06', '采购员/管理层', '供应商欠料状态监控'],
  678. ],
  679. funcDetail: [
  680. {
  681. id: 'S4-M01', name: '供应商交货管理', goal: '跟踪供应商交货计划的执行状态,管理交货全过程', role: '采购员/仓管',
  682. precondition: '采购订单已下达;交货计划已制定',
  683. flow: '交货管理列表 → 筛选查询 → 查看交货状态 → 确认收货',
  684. processes: [
  685. ['FUNC-S4-001', '供应商交货管理', '采购订单/交货计划', '交货列表查询;交货状态跟踪;多条件筛选', '交货状态数据', '数据来源采购订单+交货计划;按ShipDate排序;支持按供应商/物料/日期筛选', '数据未同步时显示空列表'],
  686. ],
  687. pages: [
  688. ['/aidop/s4/delivery/supplier-delivery-management', '交货管理列表', '查询/筛选', '—', '采购员/仓管(查看)'],
  689. ],
  690. verify: [
  691. ['1', '查看交货列表', '交货状态正确显示'],
  692. ['2', '按供应商筛选', '筛选结果正确'],
  693. ],
  694. },
  695. {
  696. id: 'S4-M02', name: '供应商发货单', goal: '管理供应商发货单的创建、编辑与状态跟踪', role: '采购员/仓管',
  697. precondition: '采购订单已存在;供应商已维护',
  698. flow: '发货单列表 → 新建发货单 → 填写发货信息 → 上传附件 → 保存 → 状态跟踪',
  699. processes: [
  700. ['FUNC-S4-002', '供应商发货单管理', '采购订单/发货信息', '发货单列表查询/新建/编辑/删除;附件上传', '发货单', '发货单与采购订单关联;支持附件上传;取消操作清理标签页', '重复发货提示;附件上传失败'],
  701. ],
  702. pages: [
  703. ['/aidop/s4/delivery/supplier-shipment', '发货单列表+表单', '查询/新建/编辑/删除/上传附件', '供应商、物料、数量必填', '采购员/仓管(编辑)'],
  704. ],
  705. verify: [
  706. ['1', '新建发货单', '发货单正确创建'],
  707. ['2', '上传附件', '附件正确上传并关联'],
  708. ],
  709. },
  710. {
  711. id: 'S4-M03', name: '采购退货单', goal: '管理采购退货单的创建、审批与执行', role: '采购员/仓管',
  712. precondition: '收货单已生成;退货原因已确认',
  713. flow: '退货单列表 → 新建退货单 → 选择收货单 → 填写退货信息 → 提交审批 → 执行退货',
  714. processes: [
  715. ['FUNC-S4-003', '采购退货单管理', '收货单/退货信息', '退货单列表查询/新建/编辑;选择收货单;审批流', '退货单', '退货单与收货单关联;RecID自动生成;筛选条件放宽', '重复退货拦截;审批流未配置提示'],
  716. ],
  717. pages: [
  718. ['/aidop/s4/return-mgmt/purchase-return-order', '退货单列表+表单', '查询/新建/编辑/删除', '收货单、物料、退货数量必填', '采购员/仓管(编辑)'],
  719. ],
  720. verify: [
  721. ['1', '新建退货单并选择收货单', '退货单正确创建'],
  722. ['2', '提交退货审批', '审批流正常启动'],
  723. ],
  724. },
  725. {
  726. id: 'S4-M04', name: 'IQC退货查询', goal: '查询来料检验产生的退货结果,支持质量追溯', role: '质量/仓管',
  727. precondition: 'IQC检验已完成;退货数据已生成',
  728. flow: '退货查询列表 → 筛选查询 → 查看退货详情 → 导出数据',
  729. processes: [
  730. ['FUNC-S4-004', 'IQC退货查询', '筛选条件', '退货查询列表;多条件筛选;数据导出', '退货查询结果', '数据来源IQC检验结果;支持按物料/供应商/日期筛选', '无退货数据时显示空列表'],
  731. ],
  732. pages: [
  733. ['/aidop/s4/return-mgmt/iqc-return-query', '退货查询列表', '查询/筛选/导出', '—', '质量/仓管(查看)'],
  734. ],
  735. verify: [
  736. ['1', '查看退货查询列表', '退货数据正确显示'],
  737. ['2', '导出退货数据', '导出文件正确'],
  738. ],
  739. },
  740. {
  741. id: 'S4-M06', name: '供应商欠料看板', goal: '实时监控供应商欠料状态,识别供应风险', role: '采购员/管理层',
  742. precondition: '采购订单和交货数据已存在',
  743. flow: '欠料看板 → 按供应商查看欠料 → 识别风险物料 → 触发催货',
  744. processes: [
  745. ['FUNC-S4-006', '供应商欠料看板', '采购订单/交货数据', '欠料状态查询;供应商维度筛选;欠料分析', '欠料状态数据', '欠料=订单量-已交货量;实时计算', '数据未同步时显示空状态'],
  746. ],
  747. pages: [
  748. ['/aidop/s4/execution-kanban/supplier-shortage-kanban', '欠料看板', '查询/筛选', '—', '采购员/管理层(查看)'],
  749. ],
  750. verify: [
  751. ['1', '查看欠料看板', '欠料状态正确显示'],
  752. ['2', '按供应商筛选', '筛选结果正确'],
  753. ],
  754. },
  755. ],
  756. dbTables: [
  757. ['PurOrdMaster', '采购订单主表', '存储采购订单主数据', 'S4-M01'],
  758. ['PurOrdDetail', '采购订单明细表', '存储采购订单明细数据', 'S4-M01'],
  759. ['ic_purchase_return', '采购退货单表', '存储采购退货单数据', 'S4-M03'],
  760. ['ic_item_stockoccupy', '库存占用表', '存储库存占用数据', 'S4-M01'],
  761. ['srm_po_occupy', '采购占用表', '存储采购订单占用数据', 'S4-M01'],
  762. ['ado_s9_kpi_value_l1_day', 'L1指标表', 'S4 L1层KPI日指标值', '数据中台'],
  763. ['dwd_supplier_delivery', '供应商交货宽表', '供应商交货主题宽表', '数据中台'],
  764. ],
  765. apiList: [
  766. ['API-S4-001', '供应商交货列表查询', '入站', 'REST', 'JWT Token', 'S4-M01'],
  767. ['API-S4-002', '供应商发货单CRUD', '入站', 'REST', 'JWT Token', 'S4-M02'],
  768. ['API-S4-003', '采购退货单CRUD', '入站', 'REST', 'JWT Token', 'S4-M03'],
  769. ['API-S4-004', 'IQC退货查询', '入站', 'REST', 'JWT Token', 'S4-M04'],
  770. ['API-S4-005', '采购执行看板', '入站', 'REST', 'JWT Token', 'S4-M05'],
  771. ['API-S4-006', '供应商欠料看板', '入站', 'REST', 'JWT Token', 'S4-M06'],
  772. ],
  773. };
  774. // ═══════════════════════════════════════════════════
  775. // 文档构建函数
  776. // ═══════════════════════════════════════════════════
  777. function buildChapter1(mod) {
  778. const ch = [];
  779. ch.push(h1('1. 文档概述'));
  780. ch.push(h2('1.1 编写目的'));
  781. ch.push(p(`本文档为${mod.moduleCode}${mod.moduleName}模块的详细设计说明书,旨在为开发团队提供完整的技术实现依据,为测试团队提供验证参考,为运维团队提供部署和运维指导。`));
  782. ch.push(p('使用对象:开发工程师、测试工程师、系统架构师、项目经理、运维工程师。'));
  783. ch.push(h2('1.2 设计范围'));
  784. ch.push(p(`本次详细设计覆盖${mod.moduleCode}${mod.moduleName}模块的全部功能,包括前端页面、后端API、数据库设计、数据中台链路、以及与其他模块的集成接口。`));
  785. ch.push(h2('1.3 参考资料'));
  786. ch.push(table(['序号', '资料名称', '版本/日期', '说明'],
  787. [
  788. ['1', `${mod.moduleCode}${mod.moduleName}业务需求描述`, 'V1.0 / 2026-06', '业务需求文档'],
  789. ['2', `${mod.moduleCode}${mod.moduleName}模块蓝图设计方案`, 'V2.0 / 2026-06', '蓝图设计文档'],
  790. ['3', 'Ai-DOP新系统数据库设计方案', 'V1.0 / 2026-05', '数据库总体方案'],
  791. ['4', 'Ai-DOP数字化运营平台开发报价清单', '2026-06-30', '项目范围基准'],
  792. ],
  793. [600, 3000, 2000, 4400]));
  794. ch.push(h2('1.4 术语和缩略语'));
  795. ch.push(table(['术语/缩写', '说明'],
  796. [
  797. ['MDP', '数据中台平台(Middle Data Platform),负责数据同步、转换与计算'],
  798. ['STG', '贴源层(Staging),保留源系统原始数据'],
  799. ['STD', '标准层(Standard),统一字段口径的标准业务对象'],
  800. ['DWD', '宽表层(Data Warehouse Detail),面向分析的主题事实表'],
  801. ['KPI', '关键绩效指标(Key Performance Indicator)'],
  802. ['MRP', '物料需求计划(Material Requirements Planning)'],
  803. ['BOM', '物料清单(Bill of Materials)'],
  804. ['ASN', '预先发货通知(Advanced Shipping Notice)'],
  805. ['IQC', '来料质量控制(Incoming Quality Control)'],
  806. ['JWT', 'JSON Web Token,用于API身份认证'],
  807. ['SaaS', '软件即服务(Software as a Service),多租户架构模式'],
  808. ],
  809. [2000, 8000]));
  810. return ch;
  811. }
  812. function buildChapter2(mod) {
  813. const ch = [];
  814. ch.push(h1('2. 系统总体设计'));
  815. ch.push(h2('2.1 系统目标和范围'));
  816. ch.push(p(mod.systemGoal));
  817. ch.push(h2('2.2 总体架构'));
  818. ch.push(p(mod.architecture));
  819. ch.push(h2('2.3 技术栈'));
  820. ch.push(table(['层次', '技术/组件', '版本', '用途'],
  821. mod.techStack,
  822. [1500, 4000, 1000, 3500]));
  823. ch.push(h2('2.4 模块划分'));
  824. ch.push(table(['模块编号', '模块名称', '主要职责', '依赖模块'],
  825. mod.modules,
  826. [1200, 2000, 4200, 2600]));
  827. return ch;
  828. }
  829. function buildChapter3(mod) {
  830. const ch = [];
  831. ch.push(h1('3. 功能模块详细设计'));
  832. ch.push(h2('3.1 功能清单'));
  833. ch.push(table(['功能编号', '功能名称', '所属模块', '用户角色', '简要说明'],
  834. mod.funcList,
  835. [1500, 2000, 1200, 2000, 3300]));
  836. ch.push(h2('3.2 模块详细设计'));
  837. for (const fd of mod.funcDetail) {
  838. ch.push(pageBreak());
  839. ch.push(h3(`3.2.${mod.funcDetail.indexOf(fd) + 1} ${fd.name}(${fd.id})`));
  840. // 模块概要
  841. ch.push(table(['项目', '内容'],
  842. [
  843. ['模块编号', fd.id],
  844. ['模块名称', fd.name],
  845. ['模块目标', fd.goal],
  846. ['使用角色', fd.role],
  847. ['前置条件', fd.precondition],
  848. ],
  849. [2000, 8000]));
  850. // 3.2.x.1 业务流程
  851. ch.push(h3(`3.2.${mod.funcDetail.indexOf(fd) + 1}.1 业务流程`));
  852. ch.push(p(fd.flow));
  853. // 3.2.x.2 功能处理
  854. ch.push(h3(`3.2.${mod.funcDetail.indexOf(fd) + 1}.2 功能处理`));
  855. ch.push(table(['功能编号', '输入', '主要处理', '输出', '业务规则', '异常处理'],
  856. fd.processes,
  857. [1400, 1400, 2400, 1400, 2200, 1200]));
  858. // 3.2.x.3 页面设计
  859. ch.push(h3(`3.2.${mod.funcDetail.indexOf(fd) + 1}.3 页面设计`));
  860. ch.push(table(['页面/路由', '主要区域', '主要操作', '校验规则', '权限要求'],
  861. fd.pages,
  862. [2800, 2200, 2200, 1800, 1000]));
  863. // 3.2.x.4 设计验证要点
  864. ch.push(h3(`3.2.${mod.funcDetail.indexOf(fd) + 1}.4 设计验证要点`));
  865. ch.push(table(['序号', '验证要点', '预期结果'],
  866. fd.verify,
  867. [600, 4600, 4800]));
  868. }
  869. return ch;
  870. }
  871. function buildChapter4(mod) {
  872. const ch = [];
  873. ch.push(h1('4. 数据库设计'));
  874. ch.push(h2('4.1 数据库说明'));
  875. ch.push(table(['项目', '内容'],
  876. [
  877. ['数据库类型', 'MySQL'],
  878. ['数据库名称', 'aidopdev'],
  879. ['字符集', 'utf8mb4'],
  880. ['租户数据隔离方式', 'tenant_id字段 + SqlSugar自动过滤'],
  881. ],
  882. [2500, 7500]));
  883. ch.push(h2('4.2 数据表清单'));
  884. ch.push(table(['表名', '中文名称', '用途', '所属模块'],
  885. mod.dbTables,
  886. [3200, 2200, 2600, 2000]));
  887. ch.push(h2('4.3 表结构设计'));
  888. ch.push(p(`核心业务表结构设计遵循Admin.NET框架的EntityBase基类规范,包含Id、TenantId、CreateUserId、CreateTime、UpdateUserId、UpdateTime、IsDeleted等基础字段。各模块表的详细字段设计参见数据库设计文档和代码中的Entity定义。`));
  889. ch.push(p('以销售订单表(crm_seorder)为例:'));
  890. ch.push(table(['字段名', '数据类型', '长度', '主键', '可空', '默认值', '说明'],
  891. [
  892. ['Id', 'bigint', '—', '是', '否', '—', '主键ID'],
  893. ['BillNo', 'varchar', '128', '否', '否', '—', '订单编号'],
  894. ['CustomerId', 'bigint', '—', '否', '是', 'NULL', '客户ID'],
  895. ['OrderDate', 'datetime', '—', '否', '是', 'NULL', '订单日期'],
  896. ['RequestDate', 'datetime', '—', '否', '是', 'NULL', '需求交期'],
  897. ['Status', 'varchar', '32', '否', '是', 'NULL', '订单状态'],
  898. ['FlowState', 'varchar', '32', '否', '是', 'NULL', '审批流状态'],
  899. ['Closed', 'tinyint', '—', '否', '否', '0', '关闭标记(0=未关闭,1=已关闭)'],
  900. ['TenantId', 'bigint', '—', '否', '否', '—', '租户ID'],
  901. ['CreateUserId', 'bigint', '—', '否', '否', '—', '创建人ID'],
  902. ['CreateTime', 'datetime', '—', '否', '否', '—', '创建时间'],
  903. ],
  904. [1800, 1200, 800, 600, 600, 800, 4200]));
  905. ch.push(h2('4.4 表关系和索引'));
  906. ch.push(p('主要表关系:'));
  907. ch.push(bullet('crm_seorder (1) ── (N) crm_seorderentry:订单主表与明细表一对多关系'));
  908. ch.push(bullet('crm_seorder (1) ── (N) crm_seorder_change:订单主表与变更记录一对多关系'));
  909. ch.push(bullet('PurOrdMaster (1) ── (N) PurOrdDetail:采购订单主表与明细表一对多关系'));
  910. ch.push(p('主要索引建议:'));
  911. ch.push(table(['表名', '索引名称', '索引字段', '类型', '用途'],
  912. [
  913. ['crm_seorder', 'idx_tenant_billno', 'TenantId, BillNo', 'UNIQUE', '租户内订单编号唯一'],
  914. ['crm_seorder', 'idx_customer_date', 'CustomerId, OrderDate', 'NORMAL', '按客户和日期查询'],
  915. ['PurOrdMaster', 'idx_tenant_supplier', 'TenantId, SupplierId', 'NORMAL', '按供应商查询'],
  916. ['WorkOrdMaster', 'idx_tenant_status', 'TenantId, Status', 'NORMAL', '按状态筛选'],
  917. ],
  918. [2200, 2200, 2400, 1200, 2000]));
  919. return ch;
  920. }
  921. function buildChapter5(mod) {
  922. const ch = [];
  923. ch.push(h1('5. 接口设计'));
  924. ch.push(h2('5.1 接口清单'));
  925. ch.push(table(['接口编号', '接口名称', '调用方向', '协议', '鉴权方式', '所属模块'],
  926. mod.apiList,
  927. [1400, 2400, 1000, 1000, 1400, 2800]));
  928. ch.push(h2('5.2 接口详细设计'));
  929. // 取第一个API做详细示例
  930. if (mod.apiList.length > 0) {
  931. const api = mod.apiList[0];
  932. ch.push(table(['项目', '内容'],
  933. [
  934. ['接口地址', `GET /api/${mod.moduleCode.toLowerCase()}/{resource}/list`],
  935. ['请求方式', 'GET'],
  936. ['请求参数', '分页参数(page/size)、筛选条件(租户ID自动注入)、排序参数'],
  937. ['响应参数', '标准分页响应:{code, message, data: {items, total, page, size}}'],
  938. ['错误码', '200=成功, 400=参数错误, 401=未认证, 403=无权限, 500=服务异常'],
  939. ['超时/重试', '超时30秒,前端自动重试1次'],
  940. ['日志要求', '请求URL、参数、响应码、耗时记录到操作日志'],
  941. ],
  942. [2000, 8000]));
  943. }
  944. ch.push(p('其余接口均遵循Admin.NET框架的Dynamic API规范,自动生成标准RESTful接口,统一使用JWT Token鉴权,tenant_id由框架自动注入。'));
  945. ch.push(h2('5.3 接口时序'));
  946. ch.push(p('接口调用时序遵循标准前后端分离模式:前端Vue组件 → Axios请求 → Nginx反向代理 → .NET API → SqlSugar ORM → MySQL数据库。数据中台MDP链路为异步定时执行,不阻塞前端请求。'));
  947. return ch;
  948. }
  949. function buildChapter6_9(mod) {
  950. const sections = [];
  951. // 第6章 安全与多租户设计
  952. sections.push(h1('6. 安全与多租户设计'));
  953. sections.push(table(['设计项', '设计内容'],
  954. [
  955. ['身份认证', '采用JWT Token认证机制,登录后颁发Token,后续请求通过Authorization头携带。Token有效期可配置,支持刷新机制。'],
  956. ['角色和功能权限', '基于Admin.NET RBAC权限模型:用户→角色→菜单权限。功能权限通过sys_menu表配置,按钮权限通过权限编码控制。'],
  957. ['数据权限', '支持按组织/部门/用户的数据权限隔离,通过SysRole.DataScope配置。敏感数据可配置行级过滤规则。'],
  958. ['多租户隔离', '采用tenant_id字段实现租户数据隔离。SqlSugar ORM自动注入租户过滤条件。所有业务表均包含tenant_id字段。字典基础表(如sys_dict_type)不隔离。多租户关联查询需显式补充tenant_id JOIN条件。'],
  959. ['敏感数据保护', '传输层使用HTTPS加密。密码存储使用BCrypt哈希。关键业务字段(如价格)可按需配置脱敏规则。密钥通过环境变量注入。'],
  960. ['日志与审计', '操作日志记录用户操作行为(sys_log_op表)。登录日志记录认证行为(sys_log_login表)。审计日志保留周期默认180天。'],
  961. ],
  962. [2000, 8000]));
  963. // 第7章 SaaS部署与运维设计
  964. sections.push(h1('7. SaaS部署与运维设计'));
  965. sections.push(h2('7.1 部署模式和环境'));
  966. sections.push(table(['环境', '用途', '访问方式', '数据要求'],
  967. [
  968. ['开发环境', '开发联调', '本地localhost', '测试数据'],
  969. ['测试/UAT环境', '测试和验收', '内网域名+端口', '脱敏或测试数据'],
  970. ['生产环境', '正式租户运行', '公网域名+HTTPS', '生产数据'],
  971. ],
  972. [1800, 2500, 2700, 3000]));
  973. sections.push(h2('7.2 部署架构'));
  974. sections.push(p('采用Docker Compose容器化部署:Nginx(反向代理) + Web(前端静态资源) + API(.NET后端) + MySQL(数据库) + Redis(缓存)。各服务独立容器,通过内部网络通信。'));
  975. sections.push(h2('7.3 租户开通和初始化'));
  976. sections.push(table(['步骤', '处理内容', '责任方', '输出'],
  977. [
  978. ['1', '创建租户', '系统管理员', '租户标识(TenantId)'],
  979. ['2', '初始化组织、角色和菜单', '系统管理员', '基础配置'],
  980. ['3', '创建管理员账号', '系统管理员', '登录信息'],
  981. ['4', '初始化基础数据', '实施顾问', '初始化记录'],
  982. ],
  983. [800, 5200, 2000, 2000]));
  984. sections.push(h2('7.4 发布、升级和回滚'));
  985. sections.push(table(['项目', '设计内容'],
  986. [
  987. ['版本管理', '前后端版本号独立管理:Web/package.json version字段,Admin.NET.Web.Entry.csproj Version/AssemblyVersion/FileVersion字段。Git提交时自动递增patch版本号。'],
  988. ['发布方式', 'Docker镜像构建→推送镜像仓库→目标环境拉取→容器重启。支持CI/CD自动化发布。'],
  989. ['数据库变更', '数据库变更脚本通过Migration管理,按版本号顺序执行。DDL脚本存放在deploy/sql目录。'],
  990. ['回滚机制', '应用回滚:重新部署上一版本Docker镜像。数据库回滚:执行逆向Migration脚本。'],
  991. ['租户影响', '小版本升级无感(滚动更新)。大版本升级需提前通知租户,安排维护窗口。'],
  992. ],
  993. [2000, 8000]));
  994. sections.push(h2('7.5 监控、备份和恢复'));
  995. sections.push(table(['项目', '设计内容'],
  996. [
  997. ['监控与告警', '服务健康检查端点(/health)。API响应时间监控。MDP作业执行状态监控。异常通过钉钉/企微告警通知。'],
  998. ['日志管理', '应用日志(sys_log_op/sys_log_login)。MDP作业日志(mdp_transform_run_log)。错误日志。保留周期:应用日志180天,MDP日志90天。'],
  999. ['数据备份', 'MySQL全量备份:每日凌晨自动执行。binlog增量备份:实时。备份保留30天,存储于独立备份服务器。'],
  1000. ['恢复机制', '全量恢复:从最近全量备份+binlog恢复到指定时间点。验证方式:恢复后执行数据一致性检查脚本。'],
  1001. ['故障处理', '一级响应:系统管理员(30分钟内)。二级响应:开发团队(2小时内)。升级机制:重大故障上报项目经理。'],
  1002. ],
  1003. [2000, 8000]));
  1004. // 第8章 非功能设计
  1005. sections.push(h1('8. 非功能设计'));
  1006. sections.push(table(['类别', '设计指标/要求', '实现方式', '验证方式'],
  1007. [
  1008. ['性能', '列表查询响应时间<3秒;看板数据加载<5秒;并发用户≥50', '数据库索引优化;分页查询;Redis缓存热点数据;前端懒加载', 'JMeter压力测试;生产环境监控'],
  1009. ['可用性', '系统可用性≥99.5%;故障恢复时间<30分钟', 'Docker容器健康检查;自动重启;Nginx负载均衡', '故障演练;监控告警验证'],
  1010. ['容量', '支持100+租户;单租户数据量可达千万级', '数据库分库分表预留;MDP并行处理;数据归档策略', '容量规划测试;数据增长监控'],
  1011. ['安全', '身份认证/授权/审计/数据加密', 'JWT Token;RBAC权限;HTTPS传输;操作日志审计', '安全扫描;渗透测试'],
  1012. ['兼容性', '支持Chrome/Edge/Firefox最新版', 'Vue 3 + Element Plus响应式设计', '浏览器兼容性测试'],
  1013. ],
  1014. [1200, 2800, 3400, 2600]));
  1015. // 第9章 附录及变更记录
  1016. sections.push(h1('9. 附录及变更记录'));
  1017. sections.push(h2('9.1 附录清单'));
  1018. sections.push(table(['序号', '附件名称', '说明'],
  1019. [
  1020. ['1', `${mod.moduleCode}${mod.moduleName}模块蓝图设计方案`, '业务蓝图设计文档'],
  1021. ['2', `${mod.moduleCode}${mod.moduleName}模块业务需求描述`, '业务需求文档'],
  1022. ['3', '系统架构图', '总体架构和部署架构图'],
  1023. ['4', 'ER图', '核心数据表关系图'],
  1024. ],
  1025. [600, 4000, 5400]));
  1026. sections.push(h2('9.2 变更记录'));
  1027. sections.push(table(['日期', '版本', '变更内容', '编制/修改人'],
  1028. [
  1029. ['2026-07-30', 'V1.0', '初版', '智造易项目组'],
  1030. ],
  1031. [1800, 1000, 5000, 2200]));
  1032. sections.push(h2('9.3 审批记录'));
  1033. sections.push(table(['角色', '姓名', '意见', '日期'],
  1034. [
  1035. ['编制', '', '', ''],
  1036. ['审核', '', '', ''],
  1037. ['批准', '', '', ''],
  1038. ],
  1039. [1500, 2000, 4000, 2500]));
  1040. return sections;
  1041. }
  1042. // ═══════════════════════════════════════════════════
  1043. // 完整文档构建
  1044. // ═══════════════════════════════════════════════════
  1045. function buildDocument(mod) {
  1046. const sections = [];
  1047. // 封面
  1048. sections.push(...buildCover(mod.moduleCode, mod.moduleName, '详细设计说明书'));
  1049. // 目录
  1050. sections.push(pageBreak());
  1051. sections.push(h1('目录'));
  1052. sections.push(...buildTOC());
  1053. sections.push(pageBreak());
  1054. // 正文
  1055. sections.push(...buildChapter1(mod));
  1056. sections.push(pageBreak());
  1057. sections.push(...buildChapter2(mod));
  1058. sections.push(pageBreak());
  1059. sections.push(...buildChapter3(mod));
  1060. sections.push(pageBreak());
  1061. sections.push(...buildChapter4(mod));
  1062. sections.push(pageBreak());
  1063. sections.push(...buildChapter5(mod));
  1064. sections.push(pageBreak());
  1065. sections.push(...buildChapter6_9(mod));
  1066. return sections;
  1067. }
  1068. async function generateDoc(mod) {
  1069. const doc = new Document({
  1070. styles: {
  1071. default: {
  1072. document: { run: { font: FONT_BODY, size: 21 } },
  1073. heading1: { run: { font: FONT, size: 32, bold: true } },
  1074. heading2: { run: { font: FONT, size: 28, bold: true } },
  1075. heading3: { run: { font: FONT, size: 24, bold: true } },
  1076. },
  1077. },
  1078. sections: [{
  1079. properties: {
  1080. page: {
  1081. margin: {
  1082. top: convertInchesToTwip(0.8),
  1083. bottom: convertInchesToTwip(0.8),
  1084. left: convertInchesToTwip(1.0),
  1085. right: convertInchesToTwip(1.0),
  1086. },
  1087. },
  1088. },
  1089. children: buildDocument(mod),
  1090. }],
  1091. });
  1092. const buffer = await Packer.toBuffer(doc);
  1093. const fileName = `【${mod.moduleCode}${mod.moduleName}模块详细设计说明书】软件系统详细设计说明书模板.docx`;
  1094. const outPath = path.join('d:\\DEMONET\\doc', fileName);
  1095. fs.writeFileSync(outPath, buffer);
  1096. console.log(`Generated: ${fileName} (${(buffer.length / 1024).toFixed(1)} KB)`);
  1097. return outPath;
  1098. }
  1099. // ═══════════════════════════════════════════════════
  1100. // 主入口
  1101. // ═══════════════════════════════════════════════════
  1102. async function main() {
  1103. console.log('=== 开始生成 S1-S4 详细设计说明书 ===\n');
  1104. const modules = [S1, S2, S3, S4];
  1105. for (const mod of modules) {
  1106. console.log(`生成 ${mod.moduleCode} ${mod.moduleName}...`);
  1107. await generateDoc(mod);
  1108. }
  1109. console.log('\n=== 全部生成完成 ===');
  1110. console.log('输出目录: d:\\DEMONET\\doc\\');
  1111. }
  1112. main().catch(err => { console.error('Error:', err); process.exit(1); });