Bladeren bron

详细设计

Pengxy 1 week geleden
bovenliggende
commit
3d6ebbc5d2

+ 0 - 5
Web/src/views/aidop/s4/delivery/supplierDeliveryManagementList.vue

@@ -256,11 +256,6 @@ async function onPublish() {
 		ElMessage.warning('请先勾选数据');
 		return null;
 	}
-	const supplier = selectedRows.value[0].gysdm || '';
-	if (!supplier) {
-		ElMessage.warning('所选数据缺少供应商代码');
-		return null;
-	}
 	const ids = selectedRows.value.map((x) => (x.id != null && x.id !== '' ? String(x.id) : '')).filter(Boolean).join(',');
 	if (!ids) {
 		ElMessage.warning('所选数据缺少ID');

BIN
doc/S1产销协同模块详细设计说明书.docx


BIN
doc/S2制造协同模块详细设计说明书.docx


BIN
doc/S3供应协同模块详细设计说明书.docx


BIN
doc/S4采购执行模块详细设计说明书.docx


+ 1182 - 0
doc/generate_detail_design_docs.js

@@ -0,0 +1,1182 @@
+/**
+ * 生成 S1-S4 模块详细设计说明书 (DOCX)
+ * 基于模板:软件系统详细设计说明书模板.docx
+ * 输出文件:
+ *   - 【S1产销协同模块详细设计说明书】软件系统详细设计说明书模板.docx
+ *   - 【S2制造协同模块详细设计说明书】软件系统详细设计说明书模板.docx
+ *   - 【S3供应协同模块详细设计说明书】软件系统详细设计说明书模板.docx
+ *   - 【S4采购执行模块详细设计说明书】软件系统详细设计说明书模板.docx
+ */
+const fs = require('fs');
+const path = require('path');
+const {
+  Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
+  HeadingLevel, AlignmentType, BorderStyle, WidthType, ShadingType,
+  convertInchesToTwip, PageBreak, TabStopType, TabStopPosition,
+  TableOfContents
+} = require('docx');
+
+// ═══════════════════════════════════════════════════
+// 通用样式与辅助函数
+// ═══════════════════════════════════════════════════
+const FONT = '微软雅黑';
+const FONT_BODY = '宋体';
+const thinBorder = {
+  top: { style: BorderStyle.SINGLE, size: 1 },
+  bottom: { style: BorderStyle.SINGLE, size: 1 },
+  left: { style: BorderStyle.SINGLE, size: 1 },
+  right: { style: BorderStyle.SINGLE, size: 1 },
+};
+const headerShading = { fill: '1F3864', type: ShadingType.CLEAR };
+const lightShading = { fill: 'D6E4F0', type: ShadingType.CLEAR };
+
+function p(text, opts = {}) {
+  return new Paragraph({
+    children: [new TextRun({ text, size: 21, font: FONT_BODY, ...opts })],
+    spacing: { after: 120, line: 360 },
+  });
+}
+function bp(text) { return p(text, { bold: true, font: FONT }); }
+function empty() { return new Paragraph({ spacing: { after: 80 }, children: [] }); }
+function pageBreak() { return new Paragraph({ children: [new PageBreak()] }); }
+function note(text) {
+  return new Paragraph({
+    children: [new TextRun({ text, size: 20, font: FONT_BODY, italics: true, color: '666666' })],
+    spacing: { after: 80, line: 320 },
+  });
+}
+
+function h1(text) {
+  return new Paragraph({
+    children: [new TextRun({ text, bold: true, size: 32, font: FONT })],
+    heading: HeadingLevel.HEADING_1,
+    spacing: { before: 400, after: 200 },
+  });
+}
+function h2(text) {
+  return new Paragraph({
+    children: [new TextRun({ text, bold: true, size: 28, font: FONT })],
+    heading: HeadingLevel.HEADING_2,
+    spacing: { before: 300, after: 150 },
+  });
+}
+function h3(text) {
+  return new Paragraph({
+    children: [new TextRun({ text, bold: true, size: 24, font: FONT })],
+    heading: HeadingLevel.HEADING_3,
+    spacing: { before: 200, after: 100 },
+  });
+}
+function bullet(text, indent = 0) {
+  return new Paragraph({
+    children: [new TextRun({ text: `  ${text}`, size: 21, font: FONT_BODY })],
+    spacing: { after: 60, line: 340 },
+    indent: { left: 300 + indent * 400 },
+  });
+}
+
+// Table helpers
+function hdrCell(text, w = 1800) {
+  return new TableCell({
+    children: [new Paragraph({ children: [new TextRun({ text, bold: true, size: 20, font: FONT, color: 'FFFFFF' })], alignment: AlignmentType.CENTER })],
+    width: { size: w, type: WidthType.DXA }, borders: thinBorder, shading: headerShading,
+  });
+}
+function tc(text, w = 1800, opts = {}) {
+  const align = opts.center ? AlignmentType.CENTER : AlignmentType.LEFT;
+  const bold = opts.bold || false;
+  return new TableCell({
+    children: [new Paragraph({ children: [new TextRun({ text: String(text ?? ''), size: 20, font: FONT_BODY, bold })], alignment: align })],
+    width: { size: w, type: WidthType.DXA }, borders: thinBorder, shading: opts.shading || undefined,
+  });
+}
+function kvCell(key, val, kW = 2000, vW = 7000) {
+  return new TableRow({
+    children: [
+      tc(key, kW, { bold: true, shading: lightShading }),
+      tc(val, vW),
+    ],
+  });
+}
+function table(headers, rows, widths) {
+  return new Table({
+    rows: [
+      new TableRow({ children: headers.map((h, i) => hdrCell(h, widths ? widths[i] : 1800)), tableHeader: true }),
+      ...rows.map(r => new TableRow({ children: r.map((c, i) => tc(c, widths ? widths[i] : 1800)) })),
+    ],
+    width: { size: 100, type: WidthType.PERCENTAGE },
+  });
+}
+
+// TOC
+function buildTOC() {
+  return [
+    new TableOfContents('目录', { headingStyleRange: '1-3', hyperlink: true }),
+    new Paragraph({
+      children: [new TextRun({ text: '(如目录未显示,请在 Word 中右键此处 → 更新域)', size: 18, font: FONT, italics: true, color: '888888' })],
+      spacing: { before: 40, after: 200 },
+    }),
+  ];
+}
+
+// Info table (2-col key-value)
+function infoTable(rows) {
+  return new Table({
+    rows: rows.map(([k, v]) => kvCell(k, v)),
+    width: { size: 100, type: WidthType.PERCENTAGE },
+  });
+}
+
+// ═══════════════════════════════════════════════════
+// 封面生成
+// ═══════════════════════════════════════════════════
+function buildCover(moduleCode, moduleName, docTitle) {
+  const sections = [];
+  sections.push(empty(), empty(), empty(), empty());
+  // 标题行1:模块名
+  sections.push(new Paragraph({
+    children: [new TextRun({ text: `${moduleCode} ${moduleName}`, bold: true, size: 52, font: FONT, color: '1F4E79' })],
+    alignment: AlignmentType.CENTER, spacing: { after: 100 },
+  }));
+  // 标题行2:文档类型
+  sections.push(new Paragraph({
+    children: [new TextRun({ text: docTitle, bold: true, size: 44, font: FONT, color: '1F4E79' })],
+    alignment: AlignmentType.CENTER, spacing: { after: 300 },
+  }));
+  // 标题行3:系统名
+  sections.push(new Paragraph({
+    children: [new TextRun({ text: 'Ai-DOP智慧运营管理系统', size: 26, font: FONT, color: '333333' })],
+    alignment: AlignmentType.CENTER, spacing: { after: 800 },
+  }));
+  // 信息表
+  sections.push(infoTable([
+    ['项目名称', 'Ai-DOP智慧运营管理系统'],
+    ['系统名称', `${moduleCode} ${moduleName}`],
+    ['文档版本', 'V1.0'],
+    ['文档状态', '编制中'],
+    ['编制单位', '智造易项目组'],
+    ['编制日期', '2026-07-30'],
+  ]));
+  return sections;
+}
+
+// ═══════════════════════════════════════════════════
+// 模块数据定义
+// ═══════════════════════════════════════════════════
+
+// ── S1 产销协同 ──
+const S1 = {
+  moduleCode: 'S1',
+  moduleName: '产销协同',
+  systemGoal: 'S1产销协同模块是Ai-DOP平台订单履约链路的起点,承担"从订单到交付"的产销协同管理职能。指导销售订单从接收→评审→排产→采购→生产→发运的全流程在线化协同,通过KPI指标体系监控产销协同健康度,驱动业务流程持续改善。',
+  architecture: 'S1模块采用前后端分离架构,前端基于Vue 3 + Element Plus,后端基于.NET + Admin.NET框架,数据层采用MySQL + 数据中台分层架构(STG贴源层→STD标准层→DWD宽表层→KPI指标层)。',
+  techStack: [
+    ['前端', 'Vue 3 + Vite + TypeScript + Element Plus', '3.x', '用户界面与交互'],
+    ['后端', '.NET 10 + Admin.NET + SqlSugar ORM', '10.0', '业务逻辑与API服务'],
+    ['数据存储', 'MySQL 8.0', '8.0', '业务数据与中台数据'],
+    ['基础设施', 'Docker + Nginx', '—', '容器化部署与反向代理'],
+  ],
+  modules: [
+    ['S1-M01', '产品设计管理', '产品设计BOM和工艺路线的在线录入与维护', 'S0物料主数据'],
+    ['S1-M02', '合同评审管理', '客户合同的多级审批与KPI考核', 'S0客户管理'],
+    ['S1-M03', '订单评审管理', '销售订单的CRUD、交期评估与确认', 'S0物料/客户'],
+    ['S1-M04', '订单交付管理', '8Tab全景追踪,从订单到发运全链路可视化', 'S1-M03, S2, S3, S4'],
+    ['S1-M05', '订单发货管理', '发货计划、ASN发货、计划联动的在线管理', 'S1-M03'],
+    ['S1-M06', '工单下达', '生产工单的物料齐套检查、MRP同步与逐单下达', 'S1-M03, S2'],
+    ['S1-M07', '计划联动看板', '多源数据联动整合与手动刷新', 'S1-M03, S1-M05'],
+    ['S1-M08', '需求明细核验', 'BOM需求展开与核验结果的在线查看', 'S1-M03'],
+    ['S1-M09', '产销协同看板', 'L1/L2/L3/L4多层级KPI可视化监控', '全部S1模块'],
+  ],
+  funcList: [
+    ['FUNC-S1-001', '产品设计管理', 'S1-M01', '设计员/计划工程师', '产品设计BOM和工艺路线的在线录入与维护'],
+    ['FUNC-S1-002', '合同评审管理', 'S1-M02', '商务人员/审批人', '客户合同的多级审批流程管理'],
+    ['FUNC-S1-003', '订单评审管理', 'S1-M03', '销售/计划员', '销售订单的在线录入、交期评估与确认'],
+    ['FUNC-S1-004', '订单交付管理', 'S1-M04', '计划员/物流', '8Tab全景追踪全链路履约状态'],
+    ['FUNC-S1-005', '订单发货管理', 'S1-M05', '物流/仓管', '发货单和ASN发货的在线管理'],
+    ['FUNC-S1-006', '工单下达', 'S1-M06', '计划员/调度', '生产工单的物料齐套检查与逐单下达'],
+    ['FUNC-S1-007', '计划联动看板', 'S1-M07', '计划工程师', '多源数据联动整合与手动刷新'],
+    ['FUNC-S1-008', '需求明细核验', 'S1-M08', '计划工程师', 'BOM需求展开与核验结果查看'],
+    ['FUNC-S1-009', '产销协同看板', 'S1-M09', '管理层/计划员', 'L1-L4多层级KPI可视化监控'],
+  ],
+  funcDetail: [
+    {
+      id: 'S1-M01', name: '产品设计管理', goal: '实现产品设计任务的在线管理,涵盖BOM和工艺路线的录入与维护', role: '设计员',
+      precondition: '用户已登录,具有设计员权限;物料主数据已同步',
+      flow: '产品设计新建 → BOM子表录入 → 工艺子表录入 → 保存生效',
+      processes: [
+        ['FUNC-S1-001', '产品设计任务管理', '产品需求信息', '新建/编辑/查询/删除设计任务;BOM子表增删行;工艺子表增删行', '产品设计记录', '物料编码、任务名称、计划完成日期为必填;BOM子表至少保留一行;采用直接保存模式无审批流', '保存失败时提示必填字段;物料编码不存在时远程搜索无结果'],
+      ],
+      pages: [
+        ['/aidop/s1/order-mgmt/product-design', '列表页+详情抽屉', '新建/编辑/删除/搜索', '必填字段校验;物料编码唯一性', '设计员(编辑), 计划工程师(查看)'],
+      ],
+      verify: [
+        ['1', '新建产品设计任务并保存', '任务正常创建,列表显示新记录'],
+        ['2', 'BOM子表新增行并保存', 'BOM子表数据正确保存'],
+        ['3', '工艺子表产线下拉框搜索', '下拉框正确显示产线列表'],
+      ],
+    },
+    {
+      id: 'S1-M03', name: '订单评审管理', goal: '实现销售订单的在线录入、交期评估与确认', role: '销售/计划员',
+      precondition: '用户已登录;物料和客户主数据已同步',
+      flow: '订单信息录入 → 订单评审(交期评估) → 交期确认 → 如需变更则发起变更审批流',
+      processes: [
+        ['FUNC-S1-003', '订单管理', '销售需求/订单信息', '订单列表查询/新建/编辑/删除;订单评审执行;交期确认;订单变更申请', '已确认订单', '订单编号自动生成全局唯一;主流程无审批流;变更场景触发审批流;closed字段默认0', '订单号重复时自动生成新号;交期确认接口失败时提示错误'],
+      ],
+      pages: [
+        ['/aidop/s1/order-mgmt/order', '订单列表页+详情抽屉', '查询/新建/编辑/删除/评审/确认/变更', '客户、物料、数量、交期必填', '销售(编辑), 计划员(评审/确认)'],
+      ],
+      verify: [
+        ['1', '新建销售订单', '订单正常创建,编号自动生成'],
+        ['2', '执行订单评审', '交期评估结果正确返回'],
+        ['3', '发起订单变更', '变更审批流正常触发'],
+      ],
+    },
+    {
+      id: 'S1-M04', name: '订单交付管理', goal: '以订单行为粒度集中展示交付状态,实现全链路履约追踪', role: '计划员/物流',
+      precondition: '订单已评审确认;数据中台宽表数据已同步',
+      flow: '交付列表筛选查询 → 点击订单行 → 8Tab全景追踪(订单信息→评审→排程→物料需求→采购→备料→生产→入库发运)',
+      processes: [
+        ['FUNC-S1-004', '订单交付追踪', '筛选条件', '交付列表查询;8Tab详情查看;交付状态跟踪', '交付状态数据', '数据来源dwd_ship_trans宽表;只取最新批次;跨模块Tab渐进就绪', '宽表数据未同步时显示空状态'],
+      ],
+      pages: [
+        ['/aidop/s1/order-mgmt/orderDelivery', '交付列表+8Tab详情页', '筛选查询/点击查看详情', '—', '计划员/物流/销售(查看)'],
+      ],
+      verify: [
+        ['1', '查看交付列表', '列表正确展示交付状态'],
+        ['2', '点击订单行进入详情', '8Tab正确加载对应数据'],
+      ],
+    },
+    {
+      id: 'S1-M05', name: '订单发货管理', goal: '实现发货单和ASN发货的在线管理,与销售订单联动', role: '物流/仓管',
+      precondition: '订单已确认;销售订单数据已存在',
+      flow: '发货计划制定 → 发货单新建 → 选择销售单号 → 填写发货明细 → 保存 → MDP数据同步',
+      processes: [
+        ['FUNC-S1-005', '发货单管理', '销售订单/发货信息', '发货单列表查询/新建/编辑/删除;ASN发货录入;明细行管理', '发货单/ASN记录', '发货单号SH+日期+流水号;已发货不可删除;销售单号下拉远程搜索', '重复发货提示;已发货删除拦截'],
+      ],
+      pages: [
+        ['/aidop/s1/order-mgmt/asnShipper', '发货单列表+表单', '新建/编辑/删除/搜索', '销售单号、客户、物料必填', '物流/仓管(编辑), 计划员(查看)'],
+      ],
+      verify: [
+        ['1', '新建发货单并关联销售单号', '发货单创建成功,关联正确'],
+        ['2', 'ASN发货录入', 'ASN记录正确保存'],
+      ],
+    },
+    {
+      id: 'S1-M06', name: '工单下达', goal: '管理生产工单的下达,是产销协同到制造执行的衔接环节', role: '计划员/调度',
+      precondition: '订单已评审确认;物料需求计划已生成',
+      flow: '工单列表 → 物料齐套检查 → 生成物料需求(MRP) → 逐行点击工单下达 → 确认下达 → MES可见',
+      processes: [
+        ['FUNC-S1-006', '工单下达管理', '工单列表', '工单列表查询;物料齐套检查;生成物料需求;逐单下达', '已下达工单', '工单状态待下达→已下达;防重复下达;逐单操作非批量', '已下达工单重复下达拦截;齐套检查失败提示'],
+      ],
+      pages: [
+        ['/aidop/s1/workorder-mgmt/dispatch', '工单列表页+下达表单', '查询/齐套检查/物料需求/逐行下达', '开工日期、生产批号必填', '计划员/调度(操作)'],
+      ],
+      verify: [
+        ['1', '执行物料齐套检查', '齐套状态正确更新'],
+        ['2', '逐行点击工单下达', '工单状态变更为已下达'],
+      ],
+    },
+    {
+      id: 'S1-M02', name: '合同评审管理', goal: '实现客户合同的在线评审管理,通过审批流管控多级审核', role: '商务人员/审批人',
+      precondition: '审批流已配置发布;用户具有相应权限',
+      flow: '合同录入 → 合同评审列表 → 提交审批 → 多级审批流转 → 审核通过/驳回 → KPI计算',
+      processes: [
+        ['FUNC-S1-002', '合同评审管理', '合同信息', '合同评审列表查询/新建/编辑;提交审批流;审批流操作', '审批结果', '审批流类型CONTRACT_REVIEW;KPI自动计算;节点耗时单独统计', '审批流未配置时提示;审批人不存在时提示'],
+      ],
+      pages: [
+        ['/aidop/s1/order-mgmt/contract-review', '合同评审列表+表单', '查询/新建/编辑/提交审批', '合同编号、客户、签订日期必填', '商务(编辑), 审批人(审核)'],
+      ],
+      verify: [
+        ['1', '新建合同评审并提交审批', '审批流正常启动'],
+        ['2', '审批人审批通过', '合同状态更新为已通过'],
+      ],
+    },
+    {
+      id: 'S1-M07', name: '计划联动看板', goal: '实现销售订单、发货计划、ASN发货等业务数据的联动整合', role: '计划工程师',
+      precondition: 'MDP作业已配置;业务数据已存在',
+      flow: '查看联动列表 → 点击手动刷新 → MDP执行全量同步转换 → STG→STD→DWD→KPI链路 → 返回最新联动结果',
+      processes: [
+        ['FUNC-S1-007', '计划联动刷新', '刷新请求', '查看联动列表;手动触发全量同步转换;查看联动结果', '最新联动数据', '作业编码S1_MDP_SYNC_TRANSFORM;批次格式S1_MDP_FULL_yyyyMMddHHmmss', 'MDP作业执行失败时记录日志'],
+      ],
+      pages: [
+        ['/aidop/s1/SalesKanBan/linkage-plan', '联动列表+刷新按钮', '查看/手动刷新', '—', '计划工程师(操作)'],
+      ],
+      verify: [
+        ['1', '点击手动刷新按钮', 'MDP作业正常触发执行'],
+        ['2', '查看刷新后联动结果', '联动数据正确更新'],
+      ],
+    },
+    {
+      id: 'S1-M09', name: '产销协同看板', goal: '为管理层和业务人员提供S1模块核心KPI可视化看板', role: '管理层/计划员',
+      precondition: 'KPI数据已通过MDP计算写入',
+      flow: '进入看板 → L1核心指标卡片 → 趋势图表 → 客户筛选 → 指标下钻L2→L3→L4',
+      processes: [
+        ['FUNC-S1-009', '产销协同看板', 'KPI数据', 'L1-L4指标展示;客户维度筛选;指标下钻;趋势分析', '可视化看板', 'DynamicModuleDashboard组件;module-code=S1;L1 4项核心指标', 'KPI数据未计算时显示空状态'],
+      ],
+      pages: [
+        ['/aidop/kanban/s1', '看板主页', '查看/筛选/下钻', '—', '管理层(全部), 计划员(查看)'],
+      ],
+      verify: [
+        ['1', '查看L1核心指标卡片', '4项核心指标正确显示'],
+        ['2', '客户维度筛选', '看板数据按客户正确过滤'],
+      ],
+    },
+  ],
+  dbTables: [
+    ['crm_seorder', '销售订单表', '存储销售订单主数据', 'S1-M03'],
+    ['crm_seorderentry', '销售订单明细表', '存储订单行明细数据', 'S1-M03'],
+    ['crm_seorder_change', '订单变更表', '存储订单变更申请记录', 'S1-M03'],
+    ['ado_contract_review', '合同评审表', '存储合同评审数据', 'S1-M02'],
+    ['ado_product_design', '产品设计表', '存储产品设计任务数据', 'S1-M01'],
+    ['ShippingPlan', '发货计划表', '存储发货计划数据', 'S1-M05'],
+    ['ASNBOLShipper', 'ASN发货表', '存储ASN发货记录', 'S1-M05'],
+    ['LinkagePlan', '计划联动表', '存储计划联动数据', 'S1-M07'],
+    ['WorkOrdMaster', '工单主表', '存储生产工单主数据', 'S1-M06'],
+    ['mdp_stg_so', '销售贴源表', 'S1销售域贴源层数据', '数据中台'],
+    ['mdp_std_so', '销售标准表', 'S1销售域标准层数据', '数据中台'],
+    ['dwd_ship_trans', '发运宽表', 'S1交付发运主题宽表', '数据中台'],
+    ['dwd_requirement_examine_detail', '需求核验宽表', 'S1需求核验主题宽表', '数据中台'],
+    ['ado_s9_kpi_value_l1_day', 'L1指标表', 'S1 L1层KPI日指标值', '数据中台'],
+    ['ado_s9_kpi_value_l2_day', 'L2指标表', 'S1 L2层KPI日指标值', '数据中台'],
+  ],
+  apiList: [
+    ['API-S1-001', '订单列表查询', '入站', 'REST', 'JWT Token', 'S1-M03'],
+    ['API-S1-002', '订单评审/交期确认', '入站', 'REST', 'JWT Token', 'S1-M03'],
+    ['API-S1-003', '订单交付列表', '入站', 'REST', 'JWT Token', 'S1-M04'],
+    ['API-S1-004', '订单交付详情(8Tab)', '入站', 'REST', 'JWT Token', 'S1-M04'],
+    ['API-S1-005', '发货单CRUD', '入站', 'REST', 'JWT Token', 'S1-M05'],
+    ['API-S1-006', '工单下达列表/操作', '入站', 'REST', 'JWT Token', 'S1-M06'],
+    ['API-S1-007', '计划联动手动刷新', '入站', 'REST', 'JWT Token', 'S1-M07'],
+    ['API-S1-008', '需求核验列表', '入站', 'REST', 'JWT Token', 'S1-M08'],
+    ['API-S1-009', '看板聚合数据', '入站', 'REST', 'JWT Token', 'S1-M09'],
+    ['API-S1-010', 'MDP数据同步(外部)', '出站', 'MDP', '—', '数据中台'],
+  ],
+};
+
+// ── S2 制造协同 ──
+const S2 = {
+  moduleCode: 'S2',
+  moduleName: '制造协同',
+  systemGoal: 'S2制造协同模块承接S1工单下达后的生产排程与执行管理,实现从"排程优化"到"日计划执行"的制造协同闭环。核心能力包括基于产能约束的智能排程、可执行日计划的生成与跟踪、产线日历管理、以及工单执行进度的全程可视化监控。',
+  architecture: 'S2模块采用前后端分离架构,前端基于Vue 3 + Element Plus,后端基于.NET + Admin.NET框架,排程引擎采用独立计算服务,数据层采用MySQL存储。',
+  techStack: [
+    ['前端', 'Vue 3 + Vite + TypeScript + Element Plus', '3.x', '用户界面与交互'],
+    ['后端', '.NET 10 + Admin.NET + SqlSugar ORM', '10.0', '业务逻辑与排程API'],
+    ['数据存储', 'MySQL 8.0', '8.0', '排程数据与执行数据'],
+    ['基础设施', 'Docker + Nginx', '—', '容器化部署与反向代理'],
+  ],
+  modules: [
+    ['S2-M01', '生产排程', '基于产能约束的工单排程计算与结果管理', 'S1工单下达, S0产线/BOM'],
+    ['S2-M02', '排产异常记录', '排程过程中产生的异常信息记录与查询', 'S2-M01'],
+    ['S2-M03', '可执行日计划', '排程结果转化为每日可执行计划', 'S2-M01'],
+    ['S2-M04', '产线日历管理', '产线工作日历、休息时间、节假日管理', 'S0产线管理'],
+    ['S2-M05', '产线加班管理', '产线加班时间配置与管理', 'S0产线管理'],
+    ['S2-M06', '工单执行追踪', '工单执行进度、物料明细、工序明细的跟踪', 'S2-M01, S2-M03'],
+    ['S2-M07', '制造协同看板', 'S2模块KPI可视化监控', '全部S2模块'],
+  ],
+  funcList: [
+    ['FUNC-S2-001', '生产排程', 'S2-M01', '计划员/调度', '基于产能约束的工单排程计算'],
+    ['FUNC-S2-002', '排产异常记录', 'S2-M02', '计划员/调度', '排程异常信息记录与查询'],
+    ['FUNC-S2-003', '可执行日计划', 'S2-M03', '计划员/调度', '排程结果转化为每日可执行计划'],
+    ['FUNC-S2-004', '产线工作日历管理', 'S2-M04', '计划员', '产线工作日历的维护管理'],
+    ['FUNC-S2-005', '产线休息时间管理', 'S2-M04', '计划员', '产线休息时间的配置管理'],
+    ['FUNC-S2-006', '产线节假日管理', 'S2-M04', '计划员', '产线节假日的维护管理'],
+    ['FUNC-S2-007', '产线加班管理', 'S2-M05', '计划员', '产线加班时间的配置管理'],
+    ['FUNC-S2-008', '工单执行进度看板', 'S2-M06', '管理层/调度', '工单执行进度的可视化监控'],
+    ['FUNC-S2-009', 'S2制造协同看板(KPI)', 'S2-M07', '管理层', 'S2模块KPI指标可视化'],
+    ['FUNC-S2-010', '工单执行追踪', 'S2-M06', '调度', '工单执行过程的详细追踪'],
+    ['FUNC-S2-011', '工单物料明细', 'S2-M06', '调度', '工单物料消耗明细查询'],
+    ['FUNC-S2-012', '工单工序明细', 'S2-M06', '调度', '工单工序执行明细查询'],
+  ],
+  funcDetail: [
+    {
+      id: 'S2-M01', name: '生产排程', goal: '基于产能约束、物料齐套、优先级等条件,对已下达工单进行智能排程计算', role: '计划员/调度',
+      precondition: '工单已下达;产线产能数据已配置;工作日历已设置',
+      flow: '排程列表 → 选择排程条件 → 触发排程计算 → 查看排程结果 → 排程结果写入ScheduleResultOpMaster',
+      processes: [
+        ['FUNC-S2-001', '生产排程计算', '工单列表/排程条件', '排程列表查询;排程参数设置;触发排程计算;查看排程结果甘特图', '排程结果(ScheduleResultOpMaster)', '排程优先级ASC排序;考虑产能/物料/交期约束;排程结果写入ScheduleResultOpMaster', '排程计算超时;产能不足提示'],
+      ],
+      pages: [
+        ['/aidop/s2/production-scheduling/work-order-scheduling', '排程列表+甘特图', '查询/排程/查看结果', '排程参数必选', '计划员/调度(操作)'],
+      ],
+      verify: [
+        ['1', '触发排程计算', '排程结果正确生成'],
+        ['2', '查看甘特图', '工单排程可视化展示正确'],
+      ],
+    },
+    {
+      id: 'S2-M03', name: '可执行日计划', goal: '将排程结果转化为每日可执行的生产计划,指导车间生产执行', role: '计划员/调度',
+      precondition: '排程已执行;排程结果已生成',
+      flow: '日计划列表 → 按PlanDate排序 → 查看每日任务 → 查看模具分配/产能信息',
+      processes: [
+        ['FUNC-S2-003', '可执行日计划查看', '排程结果', '日计划列表查询;按日期筛选;查看模具分配数量', '日计划数据', '按PlanDate排序;MoldAllocationCount字段显示模具分配数', '无排程数据时显示空列表'],
+      ],
+      pages: [
+        ['/aidop/s2/operation-plan/executable-daily-plan', '日计划列表', '查询/筛选', '—', '计划员/调度(查看)'],
+      ],
+      verify: [
+        ['1', '查看日计划列表', '按日期正确展示日计划'],
+        ['2', '查看模具分配', 'MoldAllocationCount正确显示'],
+      ],
+    },
+    {
+      id: 'S2-M04', name: '产线日历管理', goal: '管理产线的工作日历、休息时间和节假日,为排程提供产能约束基础数据', role: '计划员',
+      precondition: '产线主数据已配置',
+      flow: '日历配置 → 休息时间设置 → 节假日维护 → 排程引用',
+      processes: [
+        ['FUNC-S2-004', '工作日历', '产线/日期', '工作日历CRUD;休息时间配置;节假日配置', '日历配置', '日历与产线关联;休息时间支持多时段', '产线未选择时提示'],
+      ],
+      pages: [
+        ['/aidop/s2/operation-plan/line-work-calendar', '日历列表', '查询/新增/编辑/删除', '产线、日期必填', '计划员(编辑)'],
+      ],
+      verify: [
+        ['1', '新增工作日历', '日历正确创建'],
+        ['2', '设置休息时间', '休息时间正确保存'],
+      ],
+    },
+    {
+      id: 'S2-M06', name: '工单执行追踪', goal: '跟踪工单从下达到完成的执行全过程,包括物料消耗和工序进度', role: '调度',
+      precondition: '工单已下达;排程已完成',
+      flow: '工单列表 → 查看工单执行状态 → 查看物料明细 → 查看工序明细',
+      processes: [
+        ['FUNC-S2-010', '工单执行追踪', '工单号', '工单执行状态查询;物料明细查看;工序明细查看', '执行状态数据', '工单状态W/S/R/P流转;物料明细关联WorkOrdDetail', '工单不存在时提示'],
+      ],
+      pages: [
+        ['/aidop/production/work-order-trace', '工单追踪列表', '查询/查看详情', '—', '调度(查看)'],
+      ],
+      verify: [
+        ['1', '查看工单执行状态', '状态正确显示'],
+        ['2', '查看物料明细', '物料消耗数据正确'],
+      ],
+    },
+    {
+      id: 'S2-M07', name: '制造协同看板', goal: '为管理层提供S2模块核心KPI可视化监控', role: '管理层',
+      precondition: 'KPI数据已计算写入',
+      flow: '进入看板 → L1核心指标 → 趋势分析 → 指标下钻',
+      processes: [
+        ['FUNC-S2-009', '制造协同看板', 'KPI数据', 'L1-L2指标展示;趋势分析', '可视化看板', 'module-code=S2', 'KPI数据未计算时显示空状态'],
+      ],
+      pages: [
+        ['/aidop/kanban/s2', '看板主页', '查看/筛选', '—', '管理层(全部)'],
+      ],
+      verify: [
+        ['1', '查看S2看板', 'KPI指标正确显示'],
+      ],
+    },
+  ],
+  dbTables: [
+    ['WorkOrdMaster', '工单主表', '存储生产工单主数据', 'S2-M01'],
+    ['WorkOrdDetail', '工单明细表', '存储工单物料明细', 'S2-M06'],
+    ['ScheduleResultOpMaster', '排程结果主表', '存储排程计算结果', 'S2-M01'],
+    ['ScheduleExceptionMaster', '排程异常表', '存储排程异常记录', 'S2-M02'],
+    ['PeriodSequenceDet', '周期排程明细表', '存储排程周期明细', 'S2-M01'],
+    ['LineMaster', '产线主表', '存储产线基础数据', 'S2-M04'],
+    ['ShopCalendarWorkCtr', '工作日历表', '存储产线工作日历', 'S2-M04'],
+    ['LineOvertime', '产线加班表', '存储产线加班配置', 'S2-M05'],
+    ['HolidayMaster', '节假日表', '存储节假日配置', 'S2-M04'],
+    ['QualityLineRestDetail', '产线休息时间表', '存储产线休息时间明细', 'S2-M04'],
+    ['ado_s9_kpi_value_l1_day', 'L1指标表', 'S2 L1层KPI日指标值', '数据中台'],
+    ['ado_s9_kpi_value_l2_day', 'L2指标表', 'S2 L2层KPI日指标值', '数据中台'],
+  ],
+  apiList: [
+    ['API-S2-001', '排程计算', '入站', 'REST', 'JWT Token', 'S2-M01'],
+    ['API-S2-002', '排程结果查询', '入站', 'REST', 'JWT Token', 'S2-M01'],
+    ['API-S2-003', '可执行日计划查询', '入站', 'REST', 'JWT Token', 'S2-M03'],
+    ['API-S2-004', '工作日历CRUD', '入站', 'REST', 'JWT Token', 'S2-M04'],
+    ['API-S2-005', '工单执行追踪', '入站', 'REST', 'JWT Token', 'S2-M06'],
+    ['API-S2-006', '制造协同看板', '入站', 'REST', 'JWT Token', 'S2-M07'],
+  ],
+};
+
+// ── S3 供应协同 ──
+const S3 = {
+  moduleCode: 'S3',
+  moduleName: '供应协同',
+  systemGoal: 'S3供应协同模块承接S2排程后的物料需求,实现从"物料需求计划"到"采购订单执行"的供应协同闭环。核心能力包括物料需求计划(MRP)的生成与管理、物料交货计划的制定与跟踪、采购申请与采购订单的全流程管理、委外加工订单与工序外协订单的管理,以及供应协同KPI的实时监控。',
+  architecture: 'S3模块采用前后端分离架构,前端基于Vue 3 + Element Plus,后端基于.NET + Admin.NET框架,数据层采用MySQL + 数据中台分层架构(S3试点已打通STG→STD→DWD→KPI全链路)。',
+  techStack: [
+    ['前端', 'Vue 3 + Vite + TypeScript + Element Plus', '3.x', '用户界面与交互'],
+    ['后端', '.NET 10 + Admin.NET + SqlSugar ORM', '10.0', '业务逻辑与MRP计算'],
+    ['数据存储', 'MySQL 8.0', '8.0', '供应数据与中台数据'],
+    ['基础设施', 'Docker + Nginx + MDP调度', '—', '容器化部署与数据同步'],
+  ],
+  modules: [
+    ['S3-M01', '物料需求计划', 'MRP计算与物料需求计划的生成管理', 'S2排程结果, S0 BOM'],
+    ['S3-M02', '物料交货计划', '供应商交货计划的制定与跟踪', 'S3-M01'],
+    ['S3-M03', '交货单异常记录', '交货异常情况的记录与跟踪', 'S3-M02'],
+    ['S3-M04', '物料采购申请', '采购申请的生成与审批管理', 'S3-M01'],
+    ['S3-M05', '要货令', '向供应商发出的要货指令管理', 'S3-M04'],
+    ['S3-M06', '物料采购订单', '采购订单的全流程管理', 'S3-M04, S3-M05'],
+    ['S3-M07', '委外加工订单', '委外加工订单的创建与管理', 'S3-M04'],
+    ['S3-M08', '工序外协订单', '工序外协订单的创建与管理', 'S3-M04'],
+    ['S3-M09', '供应协同看板', 'S3模块KPI可视化监控', '全部S3模块'],
+    ['S3-M10', '工单物料齐套看板', '工单物料齐套状态的可视化监控', 'S3-M01, S2-M01'],
+    ['S3-M11', 'MDP运行监控', '数据中台作业运行状态监控', '数据中台'],
+  ],
+  funcList: [
+    ['FUNC-S3-001', '物料需求计划', 'S3-M01', '计划员', 'MRP计算与物料需求计划管理'],
+    ['FUNC-S3-002', '物料交货计划', 'S3-M02', '采购员/计划员', '供应商交货计划的制定与跟踪'],
+    ['FUNC-S3-003', '交货单异常记录', 'S3-M03', '采购员', '交货异常记录与跟踪'],
+    ['FUNC-S3-004', '物料采购申请', 'S3-M04', '计划员', '采购申请的生成与审批'],
+    ['FUNC-S3-005', '要货令', 'S3-M05', '采购员', '向供应商发出的要货指令'],
+    ['FUNC-S3-006', '物料采购订单', 'S3-M06', '采购员', '采购订单的全流程管理'],
+    ['FUNC-S3-007', '委外加工订单', 'S3-M07', '采购员', '委外加工订单管理'],
+    ['FUNC-S3-008', '工序外协订单', 'S3-M08', '采购员', '工序外协订单管理'],
+    ['FUNC-S3-009', '供应协同看板', 'S3-M09', '管理层', 'S3 KPI可视化监控'],
+    ['FUNC-S3-010', '工单物料齐套看板', 'S3-M10', '调度/计划员', '工单物料齐套状态监控'],
+    ['FUNC-S3-011', 'MDP运行监控', 'S3-M11', '系统管理员', '数据中台作业运行状态'],
+    ['FUNC-S3-012', '委外采购明细', 'S3-M07', '采购员', '委外采购明细查询'],
+  ],
+  funcDetail: [
+    {
+      id: 'S3-M01', name: '物料需求计划', goal: '基于排程结果和BOM展开,计算物料需求计划(MRP)', role: '计划员',
+      precondition: '排程已完成;BOM数据已维护',
+      flow: '需求计划列表 → 触发MRP计算 → 查看需求结果 → 生成采购申请',
+      processes: [
+        ['FUNC-S3-001', '物料需求计划', '排程结果/BOM', 'MRP计算触发;需求列表查询;需求结果查看', '物料需求计划', 'MRP幂等生成;基于BOM展开计算需求数量', 'MRP计算超时;BOM数据缺失提示'],
+      ],
+      pages: [
+        ['/aidop/s3/material-plan/demand-schedule', '需求计划列表', '查询/触发MRP', '—', '计划员(操作)'],
+      ],
+      verify: [
+        ['1', '触发MRP计算', '需求计划正确生成'],
+        ['2', '查看需求明细', '物料需求数量和日期正确'],
+      ],
+    },
+    {
+      id: 'S3-M02', name: '物料交货计划', goal: '制定供应商物料交货计划,跟踪交货执行状态', role: '采购员/计划员',
+      precondition: '物料需求计划已生成;供应商已维护',
+      flow: '交货计划列表 → 制定交货计划 → 分配供应商 → 跟踪交货状态',
+      processes: [
+        ['FUNC-S3-002', '物料交货计划', '物料需求/供应商', '交货计划制定;交货状态跟踪;批量操作', '交货计划', '交货计划与采购申请关联;支持批量制定', '供应商不存在时提示'],
+      ],
+      pages: [
+        ['/aidop/s3/material-plan/delivery-schedule', '交货计划列表', '查询/新增/编辑/批量制定', '物料、供应商、交货日期必填', '采购员/计划员(编辑)'],
+      ],
+      verify: [
+        ['1', '制定交货计划', '交货计划正确创建'],
+        ['2', '批量制定交货计划', '批量操作正确执行'],
+      ],
+    },
+    {
+      id: 'S3-M04', name: '物料采购申请', goal: '管理物料采购申请的生成、审批与执行追踪', role: '计划员',
+      precondition: '物料需求计划已生成',
+      flow: '采购申请列表 → 新建采购申请 → 选择需求物料 → 提交审批 → 审批通过 → 生成采购订单',
+      processes: [
+        ['FUNC-S3-004', '物料采购申请', '物料需求', '采购申请列表查询/新建/编辑;提交审批', '采购申请单', '采购申请state状态流转(1→2→5);幂等生成防重复', '重复生成拦截;审批流未配置提示'],
+      ],
+      pages: [
+        ['/aidop/s3/procurement/purchase-request', '采购申请列表+表单', '查询/新建/编辑/删除', '物料、数量、需求日期必填', '计划员(编辑)'],
+      ],
+      verify: [
+        ['1', '新建采购申请', '申请单正确创建'],
+        ['2', '提交审批', '审批流正常启动'],
+      ],
+    },
+    {
+      id: 'S3-M06', name: '物料采购订单', goal: '管理采购订单的全流程,从创建到执行跟踪', role: '采购员',
+      precondition: '采购申请已审批通过;供应商已维护',
+      flow: '采购订单列表 → 新建采购订单 → 关联采购申请 → 下达供应商 → 跟踪执行状态',
+      processes: [
+        ['FUNC-S3-006', '物料采购订单', '采购申请/供应商', '采购订单列表查询/新建/编辑;关联采购申请;下达供应商', '采购订单', '采购订单与采购申请关联;订单状态流转', '采购申请已关联时提示'],
+      ],
+      pages: [
+        ['/aidop/s3/procurement/purchase-order', '采购订单列表', '查询/新建/编辑', '供应商、物料、数量必填', '采购员(编辑)'],
+      ],
+      verify: [
+        ['1', '新建采购订单', '订单正确创建并关联采购申请'],
+        ['2', '下达供应商', '订单状态正确更新'],
+      ],
+    },
+    {
+      id: 'S3-M05', name: '要货令', goal: '向供应商发出要货指令,驱动供应商按计划交货', role: '采购员',
+      precondition: '采购订单已创建;供应商已确认',
+      flow: '要货令列表 → 新建要货令 → 选择采购订单 → 填写要货信息 → 下达供应商',
+      processes: [
+        ['FUNC-S3-005', '要货令管理', '采购订单/物料需求', '要货令列表查询/新建/编辑;关联采购订单', '要货令', '要货令与采购订单关联;支持远程搜索物料', '物料不存在时提示'],
+      ],
+      pages: [
+        ['/aidop/s3/procurement/demand-order', '要货令列表+表单', '查询/新建/编辑', '物料、数量、交货日期必填', '采购员(编辑)'],
+      ],
+      verify: [
+        ['1', '新建要货令', '要货令正确创建'],
+        ['2', '关联采购订单', '采购订单信息正确回显'],
+      ],
+    },
+    {
+      id: 'S3-M07', name: '委外加工订单', goal: '管理委外加工订单的创建、执行与跟踪', role: '采购员',
+      precondition: '物料需求已生成;委外供应商已维护',
+      flow: '委外订单列表 → 新建委外订单 → 填写委外信息 → 下达供应商 → 跟踪执行',
+      processes: [
+        ['FUNC-S3-007', '委外加工订单', '物料需求/供应商', '委外订单CRUD;委外明细管理;状态跟踪', '委外加工订单', '委外订单与采购申请关联;明细行管理', '供应商不存在时提示'],
+      ],
+      pages: [
+        ['/aidop/s3/procurement/outsource-order', '委外订单列表+表单', '查询/新建/编辑/删除', '供应商、物料、数量必填', '采购员(编辑)'],
+      ],
+      verify: [
+        ['1', '新建委外订单', '订单正确创建'],
+        ['2', '管理委外明细', '明细行正确增删'],
+      ],
+    },
+    {
+      id: 'S3-M10', name: '工单物料齐套看板', goal: '实时监控工单物料齐套状态,识别缺料风险', role: '调度/计划员',
+      precondition: '工单已下达;物料需求已计算',
+      flow: '齐套看板 → 按工单查看齐套状态 → 识别缺料物料 → 触发紧急采购',
+      processes: [
+        ['FUNC-S3-010', '物料齐套看板', '工单物料需求', '齐套状态查询;缺料分析;工单维度筛选', '齐套状态数据', '基于dwd齐套宽表;缺料数量=需求-库存-在途', '数据未同步时显示空状态'],
+      ],
+      pages: [
+        ['/aidop/s3/supply-kanban/work-order-material-readiness', '齐套看板', '查询/筛选', '—', '调度/计划员(查看)'],
+      ],
+      verify: [
+        ['1', '查看工单齐套状态', '齐套/缺料状态正确显示'],
+        ['2', '识别缺料物料', '缺料物料清单正确'],
+      ],
+    },
+  ],
+  dbTables: [
+    ['ic_demandschedule', '需求计划表', '存储物料需求计划数据', 'S3-M01'],
+    ['PurOrdMaster', '采购订单主表', '存储采购订单主数据', 'S3-M06'],
+    ['PurOrdDetail', '采购订单明细表', '存储采购订单明细数据', 'S3-M06'],
+    ['ic_purchase_request', '采购申请表', '存储采购申请数据', 'S3-M04'],
+    ['ic_demand_order', '要货令表', '存储要货令数据', 'S3-M05'],
+    ['OutsourceOrderMaster', '委外订单主表', '存储委外加工订单数据', 'S3-M07'],
+    ['ProcessOutsourceOrder', '工序外协订单表', '存储工序外协订单数据', 'S3-M08'],
+    ['dwd_supplier_delivery', '供应商交货宽表', '供应商交货主题宽表', '数据中台'],
+    ['mdp_stg_purchase_order', '采购贴源表', '采购域贴源层数据', '数据中台'],
+    ['mdp_std_purchase_order', '采购标准表', '采购域标准层数据', '数据中台'],
+    ['ado_s9_kpi_value_l1_day', 'L1指标表', 'S3 L1层KPI日指标值', '数据中台'],
+    ['ado_s9_kpi_value_l2_day', 'L2指标表', 'S3 L2层KPI日指标值', '数据中台'],
+  ],
+  apiList: [
+    ['API-S3-001', '物料需求计划查询', '入站', 'REST', 'JWT Token', 'S3-M01'],
+    ['API-S3-002', '交货计划CRUD', '入站', 'REST', 'JWT Token', 'S3-M02'],
+    ['API-S3-003', '采购申请CRUD', '入站', 'REST', 'JWT Token', 'S3-M04'],
+    ['API-S3-004', '采购订单CRUD', '入站', 'REST', 'JWT Token', 'S3-M06'],
+    ['API-S3-005', '要货令CRUD', '入站', 'REST', 'JWT Token', 'S3-M05'],
+    ['API-S3-006', '委外订单CRUD', '入站', 'REST', 'JWT Token', 'S3-M07'],
+    ['API-S3-007', '齐套看板查询', '入站', 'REST', 'JWT Token', 'S3-M10'],
+    ['API-S3-008', 'MDP同步转换(外部)', '出站', 'MDP', '—', '数据中台'],
+  ],
+};
+
+// ── S4 采购执行 ──
+const S4 = {
+  moduleCode: 'S4',
+  moduleName: '采购执行',
+  systemGoal: 'S4采购执行模块承接S3采购订单后的执行跟踪与交付管理,实现从"供应商交货"到"采购退货"的采购执行闭环。核心能力包括供应商交货管理、供应商发货单管理、采购退货单管理、IQC退货查询,以及采购执行KPI的可视化监控。',
+  architecture: 'S4模块采用前后端分离架构,前端基于Vue 3 + Element Plus,后端基于.NET + Admin.NET框架,数据层采用MySQL存储,与S3供应协同模块紧密集成。',
+  techStack: [
+    ['前端', 'Vue 3 + Vite + TypeScript + Element Plus', '3.x', '用户界面与交互'],
+    ['后端', '.NET 10 + Admin.NET + SqlSugar ORM', '10.0', '业务逻辑与采购执行API'],
+    ['数据存储', 'MySQL 8.0', '8.0', '采购执行数据'],
+    ['基础设施', 'Docker + Nginx', '—', '容器化部署与反向代理'],
+  ],
+  modules: [
+    ['S4-M01', '供应商交货管理', '供应商交货计划的跟踪与执行管理', 'S3采购订单'],
+    ['S4-M02', '供应商发货单', '供应商发货单的创建与管理', 'S4-M01'],
+    ['S4-M03', '采购退货单', '采购退货单的创建与审批管理', 'S4-M01, S5收货'],
+    ['S4-M04', 'IQC退货查询', '来料检验退货结果的查询', 'S5 IQC'],
+    ['S4-M05', '采购执行看板', 'S4模块KPI可视化监控', '全部S4模块'],
+    ['S4-M06', '供应商欠料看板', '供应商欠料状态的可视化监控', 'S4-M01'],
+  ],
+  funcList: [
+    ['FUNC-S4-001', '供应商交货管理', 'S4-M01', '采购员/仓管', '供应商交货计划的跟踪与执行'],
+    ['FUNC-S4-002', '供应商发货单', 'S4-M02', '采购员/仓管', '供应商发货单的创建与管理'],
+    ['FUNC-S4-003', '采购退货单', 'S4-M03', '采购员/仓管', '采购退货单的创建与审批'],
+    ['FUNC-S4-004', 'IQC退货查询', 'S4-M04', '质量/仓管', '来料检验退货结果查询'],
+    ['FUNC-S4-005', '采购执行看板主页', 'S4-M05', '管理层', 'S4 KPI可视化监控'],
+    ['FUNC-S4-006', '供应商欠料看板', 'S4-M06', '采购员/管理层', '供应商欠料状态监控'],
+  ],
+  funcDetail: [
+    {
+      id: 'S4-M01', name: '供应商交货管理', goal: '跟踪供应商交货计划的执行状态,管理交货全过程', role: '采购员/仓管',
+      precondition: '采购订单已下达;交货计划已制定',
+      flow: '交货管理列表 → 筛选查询 → 查看交货状态 → 确认收货',
+      processes: [
+        ['FUNC-S4-001', '供应商交货管理', '采购订单/交货计划', '交货列表查询;交货状态跟踪;多条件筛选', '交货状态数据', '数据来源采购订单+交货计划;按ShipDate排序;支持按供应商/物料/日期筛选', '数据未同步时显示空列表'],
+      ],
+      pages: [
+        ['/aidop/s4/delivery/supplier-delivery-management', '交货管理列表', '查询/筛选', '—', '采购员/仓管(查看)'],
+      ],
+      verify: [
+        ['1', '查看交货列表', '交货状态正确显示'],
+        ['2', '按供应商筛选', '筛选结果正确'],
+      ],
+    },
+    {
+      id: 'S4-M02', name: '供应商发货单', goal: '管理供应商发货单的创建、编辑与状态跟踪', role: '采购员/仓管',
+      precondition: '采购订单已存在;供应商已维护',
+      flow: '发货单列表 → 新建发货单 → 填写发货信息 → 上传附件 → 保存 → 状态跟踪',
+      processes: [
+        ['FUNC-S4-002', '供应商发货单管理', '采购订单/发货信息', '发货单列表查询/新建/编辑/删除;附件上传', '发货单', '发货单与采购订单关联;支持附件上传;取消操作清理标签页', '重复发货提示;附件上传失败'],
+      ],
+      pages: [
+        ['/aidop/s4/delivery/supplier-shipment', '发货单列表+表单', '查询/新建/编辑/删除/上传附件', '供应商、物料、数量必填', '采购员/仓管(编辑)'],
+      ],
+      verify: [
+        ['1', '新建发货单', '发货单正确创建'],
+        ['2', '上传附件', '附件正确上传并关联'],
+      ],
+    },
+    {
+      id: 'S4-M03', name: '采购退货单', goal: '管理采购退货单的创建、审批与执行', role: '采购员/仓管',
+      precondition: '收货单已生成;退货原因已确认',
+      flow: '退货单列表 → 新建退货单 → 选择收货单 → 填写退货信息 → 提交审批 → 执行退货',
+      processes: [
+        ['FUNC-S4-003', '采购退货单管理', '收货单/退货信息', '退货单列表查询/新建/编辑;选择收货单;审批流', '退货单', '退货单与收货单关联;RecID自动生成;筛选条件放宽', '重复退货拦截;审批流未配置提示'],
+      ],
+      pages: [
+        ['/aidop/s4/return-mgmt/purchase-return-order', '退货单列表+表单', '查询/新建/编辑/删除', '收货单、物料、退货数量必填', '采购员/仓管(编辑)'],
+      ],
+      verify: [
+        ['1', '新建退货单并选择收货单', '退货单正确创建'],
+        ['2', '提交退货审批', '审批流正常启动'],
+      ],
+    },
+    {
+      id: 'S4-M04', name: 'IQC退货查询', goal: '查询来料检验产生的退货结果,支持质量追溯', role: '质量/仓管',
+      precondition: 'IQC检验已完成;退货数据已生成',
+      flow: '退货查询列表 → 筛选查询 → 查看退货详情 → 导出数据',
+      processes: [
+        ['FUNC-S4-004', 'IQC退货查询', '筛选条件', '退货查询列表;多条件筛选;数据导出', '退货查询结果', '数据来源IQC检验结果;支持按物料/供应商/日期筛选', '无退货数据时显示空列表'],
+      ],
+      pages: [
+        ['/aidop/s4/return-mgmt/iqc-return-query', '退货查询列表', '查询/筛选/导出', '—', '质量/仓管(查看)'],
+      ],
+      verify: [
+        ['1', '查看退货查询列表', '退货数据正确显示'],
+        ['2', '导出退货数据', '导出文件正确'],
+      ],
+    },
+    {
+      id: 'S4-M06', name: '供应商欠料看板', goal: '实时监控供应商欠料状态,识别供应风险', role: '采购员/管理层',
+      precondition: '采购订单和交货数据已存在',
+      flow: '欠料看板 → 按供应商查看欠料 → 识别风险物料 → 触发催货',
+      processes: [
+        ['FUNC-S4-006', '供应商欠料看板', '采购订单/交货数据', '欠料状态查询;供应商维度筛选;欠料分析', '欠料状态数据', '欠料=订单量-已交货量;实时计算', '数据未同步时显示空状态'],
+      ],
+      pages: [
+        ['/aidop/s4/execution-kanban/supplier-shortage-kanban', '欠料看板', '查询/筛选', '—', '采购员/管理层(查看)'],
+      ],
+      verify: [
+        ['1', '查看欠料看板', '欠料状态正确显示'],
+        ['2', '按供应商筛选', '筛选结果正确'],
+      ],
+    },
+  ],
+  dbTables: [
+    ['PurOrdMaster', '采购订单主表', '存储采购订单主数据', 'S4-M01'],
+    ['PurOrdDetail', '采购订单明细表', '存储采购订单明细数据', 'S4-M01'],
+    ['ic_purchase_return', '采购退货单表', '存储采购退货单数据', 'S4-M03'],
+    ['ic_item_stockoccupy', '库存占用表', '存储库存占用数据', 'S4-M01'],
+    ['srm_po_occupy', '采购占用表', '存储采购订单占用数据', 'S4-M01'],
+    ['ado_s9_kpi_value_l1_day', 'L1指标表', 'S4 L1层KPI日指标值', '数据中台'],
+    ['dwd_supplier_delivery', '供应商交货宽表', '供应商交货主题宽表', '数据中台'],
+  ],
+  apiList: [
+    ['API-S4-001', '供应商交货列表查询', '入站', 'REST', 'JWT Token', 'S4-M01'],
+    ['API-S4-002', '供应商发货单CRUD', '入站', 'REST', 'JWT Token', 'S4-M02'],
+    ['API-S4-003', '采购退货单CRUD', '入站', 'REST', 'JWT Token', 'S4-M03'],
+    ['API-S4-004', 'IQC退货查询', '入站', 'REST', 'JWT Token', 'S4-M04'],
+    ['API-S4-005', '采购执行看板', '入站', 'REST', 'JWT Token', 'S4-M05'],
+    ['API-S4-006', '供应商欠料看板', '入站', 'REST', 'JWT Token', 'S4-M06'],
+  ],
+};
+
+// ═══════════════════════════════════════════════════
+// 文档构建函数
+// ═══════════════════════════════════════════════════
+
+function buildChapter1(mod) {
+  const ch = [];
+  ch.push(h1('1. 文档概述'));
+  ch.push(h2('1.1 编写目的'));
+  ch.push(p(`本文档为${mod.moduleCode}${mod.moduleName}模块的详细设计说明书,旨在为开发团队提供完整的技术实现依据,为测试团队提供验证参考,为运维团队提供部署和运维指导。`));
+  ch.push(p('使用对象:开发工程师、测试工程师、系统架构师、项目经理、运维工程师。'));
+
+  ch.push(h2('1.2 设计范围'));
+  ch.push(p(`本次详细设计覆盖${mod.moduleCode}${mod.moduleName}模块的全部功能,包括前端页面、后端API、数据库设计、数据中台链路、以及与其他模块的集成接口。`));
+
+  ch.push(h2('1.3 参考资料'));
+  ch.push(table(['序号', '资料名称', '版本/日期', '说明'],
+    [
+      ['1', `${mod.moduleCode}${mod.moduleName}业务需求描述`, 'V1.0 / 2026-06', '业务需求文档'],
+      ['2', `${mod.moduleCode}${mod.moduleName}模块蓝图设计方案`, 'V2.0 / 2026-06', '蓝图设计文档'],
+      ['3', 'Ai-DOP新系统数据库设计方案', 'V1.0 / 2026-05', '数据库总体方案'],
+      ['4', 'Ai-DOP数字化运营平台开发报价清单', '2026-06-30', '项目范围基准'],
+    ],
+    [600, 3000, 2000, 4400]));
+
+  ch.push(h2('1.4 术语和缩略语'));
+  ch.push(table(['术语/缩写', '说明'],
+    [
+      ['MDP', '数据中台平台(Middle Data Platform),负责数据同步、转换与计算'],
+      ['STG', '贴源层(Staging),保留源系统原始数据'],
+      ['STD', '标准层(Standard),统一字段口径的标准业务对象'],
+      ['DWD', '宽表层(Data Warehouse Detail),面向分析的主题事实表'],
+      ['KPI', '关键绩效指标(Key Performance Indicator)'],
+      ['MRP', '物料需求计划(Material Requirements Planning)'],
+      ['BOM', '物料清单(Bill of Materials)'],
+      ['ASN', '预先发货通知(Advanced Shipping Notice)'],
+      ['IQC', '来料质量控制(Incoming Quality Control)'],
+      ['JWT', 'JSON Web Token,用于API身份认证'],
+      ['SaaS', '软件即服务(Software as a Service),多租户架构模式'],
+    ],
+    [2000, 8000]));
+
+  return ch;
+}
+
+function buildChapter2(mod) {
+  const ch = [];
+  ch.push(h1('2. 系统总体设计'));
+
+  ch.push(h2('2.1 系统目标和范围'));
+  ch.push(p(mod.systemGoal));
+
+  ch.push(h2('2.2 总体架构'));
+  ch.push(p(mod.architecture));
+
+  ch.push(h2('2.3 技术栈'));
+  ch.push(table(['层次', '技术/组件', '版本', '用途'],
+    mod.techStack,
+    [1500, 4000, 1000, 3500]));
+
+  ch.push(h2('2.4 模块划分'));
+  ch.push(table(['模块编号', '模块名称', '主要职责', '依赖模块'],
+    mod.modules,
+    [1200, 2000, 4200, 2600]));
+
+  return ch;
+}
+
+function buildChapter3(mod) {
+  const ch = [];
+  ch.push(h1('3. 功能模块详细设计'));
+
+  ch.push(h2('3.1 功能清单'));
+  ch.push(table(['功能编号', '功能名称', '所属模块', '用户角色', '简要说明'],
+    mod.funcList,
+    [1500, 2000, 1200, 2000, 3300]));
+
+  ch.push(h2('3.2 模块详细设计'));
+
+  for (const fd of mod.funcDetail) {
+    ch.push(pageBreak());
+    ch.push(h3(`3.2.${mod.funcDetail.indexOf(fd) + 1}  ${fd.name}(${fd.id})`));
+
+    // 模块概要
+    ch.push(table(['项目', '内容'],
+      [
+        ['模块编号', fd.id],
+        ['模块名称', fd.name],
+        ['模块目标', fd.goal],
+        ['使用角色', fd.role],
+        ['前置条件', fd.precondition],
+      ],
+      [2000, 8000]));
+
+    // 3.2.x.1 业务流程
+    ch.push(h3(`3.2.${mod.funcDetail.indexOf(fd) + 1}.1  业务流程`));
+    ch.push(p(fd.flow));
+
+    // 3.2.x.2 功能处理
+    ch.push(h3(`3.2.${mod.funcDetail.indexOf(fd) + 1}.2  功能处理`));
+    ch.push(table(['功能编号', '输入', '主要处理', '输出', '业务规则', '异常处理'],
+      fd.processes,
+      [1400, 1400, 2400, 1400, 2200, 1200]));
+
+    // 3.2.x.3 页面设计
+    ch.push(h3(`3.2.${mod.funcDetail.indexOf(fd) + 1}.3  页面设计`));
+    ch.push(table(['页面/路由', '主要区域', '主要操作', '校验规则', '权限要求'],
+      fd.pages,
+      [2800, 2200, 2200, 1800, 1000]));
+
+    // 3.2.x.4 设计验证要点
+    ch.push(h3(`3.2.${mod.funcDetail.indexOf(fd) + 1}.4  设计验证要点`));
+    ch.push(table(['序号', '验证要点', '预期结果'],
+      fd.verify,
+      [600, 4600, 4800]));
+  }
+
+  return ch;
+}
+
+function buildChapter4(mod) {
+  const ch = [];
+  ch.push(h1('4. 数据库设计'));
+
+  ch.push(h2('4.1 数据库说明'));
+  ch.push(table(['项目', '内容'],
+    [
+      ['数据库类型', 'MySQL'],
+      ['数据库名称', 'aidopdev'],
+      ['字符集', 'utf8mb4'],
+      ['租户数据隔离方式', 'tenant_id字段 + SqlSugar自动过滤'],
+    ],
+    [2500, 7500]));
+
+  ch.push(h2('4.2 数据表清单'));
+  ch.push(table(['表名', '中文名称', '用途', '所属模块'],
+    mod.dbTables,
+    [3200, 2200, 2600, 2000]));
+
+  ch.push(h2('4.3 表结构设计'));
+  ch.push(p(`核心业务表结构设计遵循Admin.NET框架的EntityBase基类规范,包含Id、TenantId、CreateUserId、CreateTime、UpdateUserId、UpdateTime、IsDeleted等基础字段。各模块表的详细字段设计参见数据库设计文档和代码中的Entity定义。`));
+  ch.push(p('以销售订单表(crm_seorder)为例:'));
+  ch.push(table(['字段名', '数据类型', '长度', '主键', '可空', '默认值', '说明'],
+    [
+      ['Id', 'bigint', '—', '是', '否', '—', '主键ID'],
+      ['BillNo', 'varchar', '128', '否', '否', '—', '订单编号'],
+      ['CustomerId', 'bigint', '—', '否', '是', 'NULL', '客户ID'],
+      ['OrderDate', 'datetime', '—', '否', '是', 'NULL', '订单日期'],
+      ['RequestDate', 'datetime', '—', '否', '是', 'NULL', '需求交期'],
+      ['Status', 'varchar', '32', '否', '是', 'NULL', '订单状态'],
+      ['FlowState', 'varchar', '32', '否', '是', 'NULL', '审批流状态'],
+      ['Closed', 'tinyint', '—', '否', '否', '0', '关闭标记(0=未关闭,1=已关闭)'],
+      ['TenantId', 'bigint', '—', '否', '否', '—', '租户ID'],
+      ['CreateUserId', 'bigint', '—', '否', '否', '—', '创建人ID'],
+      ['CreateTime', 'datetime', '—', '否', '否', '—', '创建时间'],
+    ],
+    [1800, 1200, 800, 600, 600, 800, 4200]));
+
+  ch.push(h2('4.4 表关系和索引'));
+  ch.push(p('主要表关系:'));
+  ch.push(bullet('crm_seorder (1) ── (N) crm_seorderentry:订单主表与明细表一对多关系'));
+  ch.push(bullet('crm_seorder (1) ── (N) crm_seorder_change:订单主表与变更记录一对多关系'));
+  ch.push(bullet('PurOrdMaster (1) ── (N) PurOrdDetail:采购订单主表与明细表一对多关系'));
+  ch.push(p('主要索引建议:'));
+  ch.push(table(['表名', '索引名称', '索引字段', '类型', '用途'],
+    [
+      ['crm_seorder', 'idx_tenant_billno', 'TenantId, BillNo', 'UNIQUE', '租户内订单编号唯一'],
+      ['crm_seorder', 'idx_customer_date', 'CustomerId, OrderDate', 'NORMAL', '按客户和日期查询'],
+      ['PurOrdMaster', 'idx_tenant_supplier', 'TenantId, SupplierId', 'NORMAL', '按供应商查询'],
+      ['WorkOrdMaster', 'idx_tenant_status', 'TenantId, Status', 'NORMAL', '按状态筛选'],
+    ],
+    [2200, 2200, 2400, 1200, 2000]));
+
+  return ch;
+}
+
+function buildChapter5(mod) {
+  const ch = [];
+  ch.push(h1('5. 接口设计'));
+
+  ch.push(h2('5.1 接口清单'));
+  ch.push(table(['接口编号', '接口名称', '调用方向', '协议', '鉴权方式', '所属模块'],
+    mod.apiList,
+    [1400, 2400, 1000, 1000, 1400, 2800]));
+
+  ch.push(h2('5.2 接口详细设计'));
+  // 取第一个API做详细示例
+  if (mod.apiList.length > 0) {
+    const api = mod.apiList[0];
+    ch.push(table(['项目', '内容'],
+      [
+        ['接口地址', `GET /api/${mod.moduleCode.toLowerCase()}/{resource}/list`],
+        ['请求方式', 'GET'],
+        ['请求参数', '分页参数(page/size)、筛选条件(租户ID自动注入)、排序参数'],
+        ['响应参数', '标准分页响应:{code, message, data: {items, total, page, size}}'],
+        ['错误码', '200=成功, 400=参数错误, 401=未认证, 403=无权限, 500=服务异常'],
+        ['超时/重试', '超时30秒,前端自动重试1次'],
+        ['日志要求', '请求URL、参数、响应码、耗时记录到操作日志'],
+      ],
+      [2000, 8000]));
+  }
+  ch.push(p('其余接口均遵循Admin.NET框架的Dynamic API规范,自动生成标准RESTful接口,统一使用JWT Token鉴权,tenant_id由框架自动注入。'));
+
+  ch.push(h2('5.3 接口时序'));
+  ch.push(p('接口调用时序遵循标准前后端分离模式:前端Vue组件 → Axios请求 → Nginx反向代理 → .NET API → SqlSugar ORM → MySQL数据库。数据中台MDP链路为异步定时执行,不阻塞前端请求。'));
+
+  return ch;
+}
+
+function buildChapter6_9(mod) {
+  const sections = [];
+
+  // 第6章 安全与多租户设计
+  sections.push(h1('6. 安全与多租户设计'));
+  sections.push(table(['设计项', '设计内容'],
+    [
+      ['身份认证', '采用JWT Token认证机制,登录后颁发Token,后续请求通过Authorization头携带。Token有效期可配置,支持刷新机制。'],
+      ['角色和功能权限', '基于Admin.NET RBAC权限模型:用户→角色→菜单权限。功能权限通过sys_menu表配置,按钮权限通过权限编码控制。'],
+      ['数据权限', '支持按组织/部门/用户的数据权限隔离,通过SysRole.DataScope配置。敏感数据可配置行级过滤规则。'],
+      ['多租户隔离', '采用tenant_id字段实现租户数据隔离。SqlSugar ORM自动注入租户过滤条件。所有业务表均包含tenant_id字段。字典基础表(如sys_dict_type)不隔离。多租户关联查询需显式补充tenant_id JOIN条件。'],
+      ['敏感数据保护', '传输层使用HTTPS加密。密码存储使用BCrypt哈希。关键业务字段(如价格)可按需配置脱敏规则。密钥通过环境变量注入。'],
+      ['日志与审计', '操作日志记录用户操作行为(sys_log_op表)。登录日志记录认证行为(sys_log_login表)。审计日志保留周期默认180天。'],
+    ],
+    [2000, 8000]));
+
+  // 第7章 SaaS部署与运维设计
+  sections.push(h1('7. SaaS部署与运维设计'));
+
+  sections.push(h2('7.1 部署模式和环境'));
+  sections.push(table(['环境', '用途', '访问方式', '数据要求'],
+    [
+      ['开发环境', '开发联调', '本地localhost', '测试数据'],
+      ['测试/UAT环境', '测试和验收', '内网域名+端口', '脱敏或测试数据'],
+      ['生产环境', '正式租户运行', '公网域名+HTTPS', '生产数据'],
+    ],
+    [1800, 2500, 2700, 3000]));
+
+  sections.push(h2('7.2 部署架构'));
+  sections.push(p('采用Docker Compose容器化部署:Nginx(反向代理) + Web(前端静态资源) + API(.NET后端) + MySQL(数据库) + Redis(缓存)。各服务独立容器,通过内部网络通信。'));
+
+  sections.push(h2('7.3 租户开通和初始化'));
+  sections.push(table(['步骤', '处理内容', '责任方', '输出'],
+    [
+      ['1', '创建租户', '系统管理员', '租户标识(TenantId)'],
+      ['2', '初始化组织、角色和菜单', '系统管理员', '基础配置'],
+      ['3', '创建管理员账号', '系统管理员', '登录信息'],
+      ['4', '初始化基础数据', '实施顾问', '初始化记录'],
+    ],
+    [800, 5200, 2000, 2000]));
+
+  sections.push(h2('7.4 发布、升级和回滚'));
+  sections.push(table(['项目', '设计内容'],
+    [
+      ['版本管理', '前后端版本号独立管理:Web/package.json version字段,Admin.NET.Web.Entry.csproj Version/AssemblyVersion/FileVersion字段。Git提交时自动递增patch版本号。'],
+      ['发布方式', 'Docker镜像构建→推送镜像仓库→目标环境拉取→容器重启。支持CI/CD自动化发布。'],
+      ['数据库变更', '数据库变更脚本通过Migration管理,按版本号顺序执行。DDL脚本存放在deploy/sql目录。'],
+      ['回滚机制', '应用回滚:重新部署上一版本Docker镜像。数据库回滚:执行逆向Migration脚本。'],
+      ['租户影响', '小版本升级无感(滚动更新)。大版本升级需提前通知租户,安排维护窗口。'],
+    ],
+    [2000, 8000]));
+
+  sections.push(h2('7.5 监控、备份和恢复'));
+  sections.push(table(['项目', '设计内容'],
+    [
+      ['监控与告警', '服务健康检查端点(/health)。API响应时间监控。MDP作业执行状态监控。异常通过钉钉/企微告警通知。'],
+      ['日志管理', '应用日志(sys_log_op/sys_log_login)。MDP作业日志(mdp_transform_run_log)。错误日志。保留周期:应用日志180天,MDP日志90天。'],
+      ['数据备份', 'MySQL全量备份:每日凌晨自动执行。binlog增量备份:实时。备份保留30天,存储于独立备份服务器。'],
+      ['恢复机制', '全量恢复:从最近全量备份+binlog恢复到指定时间点。验证方式:恢复后执行数据一致性检查脚本。'],
+      ['故障处理', '一级响应:系统管理员(30分钟内)。二级响应:开发团队(2小时内)。升级机制:重大故障上报项目经理。'],
+    ],
+    [2000, 8000]));
+
+  // 第8章 非功能设计
+  sections.push(h1('8. 非功能设计'));
+  sections.push(table(['类别', '设计指标/要求', '实现方式', '验证方式'],
+    [
+      ['性能', '列表查询响应时间<3秒;看板数据加载<5秒;并发用户≥50', '数据库索引优化;分页查询;Redis缓存热点数据;前端懒加载', 'JMeter压力测试;生产环境监控'],
+      ['可用性', '系统可用性≥99.5%;故障恢复时间<30分钟', 'Docker容器健康检查;自动重启;Nginx负载均衡', '故障演练;监控告警验证'],
+      ['容量', '支持100+租户;单租户数据量可达千万级', '数据库分库分表预留;MDP并行处理;数据归档策略', '容量规划测试;数据增长监控'],
+      ['安全', '身份认证/授权/审计/数据加密', 'JWT Token;RBAC权限;HTTPS传输;操作日志审计', '安全扫描;渗透测试'],
+      ['兼容性', '支持Chrome/Edge/Firefox最新版', 'Vue 3 + Element Plus响应式设计', '浏览器兼容性测试'],
+    ],
+    [1200, 2800, 3400, 2600]));
+
+  // 第9章 附录及变更记录
+  sections.push(h1('9. 附录及变更记录'));
+
+  sections.push(h2('9.1 附录清单'));
+  sections.push(table(['序号', '附件名称', '说明'],
+    [
+      ['1', `${mod.moduleCode}${mod.moduleName}模块蓝图设计方案`, '业务蓝图设计文档'],
+      ['2', `${mod.moduleCode}${mod.moduleName}模块业务需求描述`, '业务需求文档'],
+      ['3', '系统架构图', '总体架构和部署架构图'],
+      ['4', 'ER图', '核心数据表关系图'],
+    ],
+    [600, 4000, 5400]));
+
+  sections.push(h2('9.2 变更记录'));
+  sections.push(table(['日期', '版本', '变更内容', '编制/修改人'],
+    [
+      ['2026-07-30', 'V1.0', '初版', '智造易项目组'],
+    ],
+    [1800, 1000, 5000, 2200]));
+
+  sections.push(h2('9.3 审批记录'));
+  sections.push(table(['角色', '姓名', '意见', '日期'],
+    [
+      ['编制', '', '', ''],
+      ['审核', '', '', ''],
+      ['批准', '', '', ''],
+    ],
+    [1500, 2000, 4000, 2500]));
+
+  return sections;
+}
+
+// ═══════════════════════════════════════════════════
+// 完整文档构建
+// ═══════════════════════════════════════════════════
+function buildDocument(mod) {
+  const sections = [];
+
+  // 封面
+  sections.push(...buildCover(mod.moduleCode, mod.moduleName, '详细设计说明书'));
+
+  // 目录
+  sections.push(pageBreak());
+  sections.push(h1('目录'));
+  sections.push(...buildTOC());
+  sections.push(pageBreak());
+
+  // 正文
+  sections.push(...buildChapter1(mod));
+  sections.push(pageBreak());
+  sections.push(...buildChapter2(mod));
+  sections.push(pageBreak());
+  sections.push(...buildChapter3(mod));
+  sections.push(pageBreak());
+  sections.push(...buildChapter4(mod));
+  sections.push(pageBreak());
+  sections.push(...buildChapter5(mod));
+  sections.push(pageBreak());
+  sections.push(...buildChapter6_9(mod));
+
+  return sections;
+}
+
+async function generateDoc(mod) {
+  const doc = new Document({
+    styles: {
+      default: {
+        document: { run: { font: FONT_BODY, size: 21 } },
+        heading1: { run: { font: FONT, size: 32, bold: true } },
+        heading2: { run: { font: FONT, size: 28, bold: true } },
+        heading3: { run: { font: FONT, size: 24, bold: true } },
+      },
+    },
+    sections: [{
+      properties: {
+        page: {
+          margin: {
+            top: convertInchesToTwip(0.8),
+            bottom: convertInchesToTwip(0.8),
+            left: convertInchesToTwip(1.0),
+            right: convertInchesToTwip(1.0),
+          },
+        },
+      },
+      children: buildDocument(mod),
+    }],
+  });
+
+  const buffer = await Packer.toBuffer(doc);
+  const fileName = `【${mod.moduleCode}${mod.moduleName}模块详细设计说明书】软件系统详细设计说明书模板.docx`;
+  const outPath = path.join('d:\\DEMONET\\doc', fileName);
+  fs.writeFileSync(outPath, buffer);
+  console.log(`Generated: ${fileName} (${(buffer.length / 1024).toFixed(1)} KB)`);
+  return outPath;
+}
+
+// ═══════════════════════════════════════════════════
+// 主入口
+// ═══════════════════════════════════════════════════
+async function main() {
+  console.log('=== 开始生成 S1-S4 详细设计说明书 ===\n');
+
+  const modules = [S1, S2, S3, S4];
+  for (const mod of modules) {
+    console.log(`生成 ${mod.moduleCode} ${mod.moduleName}...`);
+    await generateDoc(mod);
+  }
+
+  console.log('\n=== 全部生成完成 ===');
+  console.log('输出目录: d:\\DEMONET\\doc\\');
+}
+
+main().catch(err => { console.error('Error:', err); process.exit(1); });