/**
* Generate S3 供应协同模块蓝图设计方案.docx
* 参照 generate_s1_blueprint_docx.js 模板格式
* 章节结构: 封面 → 文档控制 → TOC → Ch1 总体方案 → Ch2~12 功能域(各8子节) → Ch13 数据中台 → Ch14 权限汇总
*/
const fs = require('fs');
const sharp = require('sharp');
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
HeadingLevel, AlignmentType, BorderStyle, WidthType, ShadingType,
convertInchesToTwip, PageBreak, ImageRun, TabStopType, TabStopPosition,
TableOfContents
} = require('docx');
// ═══════════════════════════════════════════════════
// 通用样式与辅助函数 (from S1 template)
// ═══════════════════════════════════════════════════
const FONT = '微软雅黑';
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: '4472C4', type: ShadingType.CLEAR };
function p(text, opts = {}) {
return new Paragraph({
children: [new TextRun({ text, size: 21, font: FONT, ...opts })],
spacing: { after: 120, line: 360 },
});
}
function bp(text) { return p(text, { bold: true }); }
function empty() { return new Paragraph({ spacing: { after: 80 }, children: [] }); }
function pageBreak() { return new Paragraph({ children: [new PageBreak()] }); }
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 })],
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 = {}) {
return new TableCell({
children: [new Paragraph({ children: [new TextRun({ text: String(text ?? ''), size: 20, font: FONT })], alignment: opts.center ? AlignmentType.CENTER : AlignmentType.LEFT })],
width: { size: w, type: WidthType.DXA }, borders: thinBorder,
});
}
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 },
});
}
// ── 活动流程表(6列) ──
function activityTable(rows) {
const w = [600, 1400, 1100, 3800, 1400, 1700];
return table(['编号', '活动名称', '执行角色', '活动描述', '输入', '输出'], rows, w);
}
// ── 业务规则表(3列) ──
function ruleTable(rows) {
return table(['序列号', '业务情形', '描述/方案'], rows, [900, 2800, 6300]);
}
// ── 接口表(4列) ──
function interfaceTable(rows) {
return table(['序号', '接口名称', '接口说明', '频次及触发方式'], rows, [600, 2400, 4200, 2800]);
}
// ── 报表表(4列) ──
function reportTable(rows) {
return table(['序号', '名称', '描述', '方案'], rows, [600, 2600, 3600, 3200]);
}
// ── 权限表(3列) ──
function permTable(rows) {
return table(['序号', '岗位名称', '对应系统权限'], rows, [600, 2000, 7400]);
}
// ═══════════════════════════════════════════════════
// 目录 (TOC)
// ═══════════════════════════════════════════════════
const TOC2_TAB = 2880;
const TOC3_TAB = 3600;
const TOC_FONT_SIZE = 20;
function tocChapter(num, title) {
return new Paragraph({
children: [
new TextRun({ text: String(num), size: TOC_FONT_SIZE, font: FONT }),
new TextRun({ text: '\t', size: TOC_FONT_SIZE, font: FONT }),
new TextRun({ text: title, bold: true, size: TOC_FONT_SIZE, font: FONT }),
new TextRun({ text: '\t', size: TOC_FONT_SIZE, font: FONT }),
new TextRun({ text: ' ', size: TOC_FONT_SIZE, font: FONT }),
],
tabStops: [
{ type: TabStopType.LEFT, position: TOC2_TAB },
{ type: TabStopType.RIGHT, position: TabStopPosition.MAX },
],
spacing: { before: 80, after: 40 },
});
}
function tocSub(num, title) {
return new Paragraph({
children: [
new TextRun({ text: String(num), size: TOC_FONT_SIZE, font: FONT }),
new TextRun({ text: '\t', size: TOC_FONT_SIZE, font: FONT }),
new TextRun({ text: title, size: TOC_FONT_SIZE, font: FONT }),
new TextRun({ text: '\t', size: TOC_FONT_SIZE, font: FONT }),
new TextRun({ text: ' ', size: TOC_FONT_SIZE, font: FONT }),
],
tabStops: [
{ type: TabStopType.LEFT, position: TOC3_TAB },
{ type: TabStopType.RIGHT, position: TabStopPosition.MAX },
],
spacing: { before: 30, after: 30 },
});
}
function buildTOC() {
const ch = [];
ch.push(new TableOfContents('目录', { headingStyleRange: '1-2', hyperlink: true }));
ch.push(new Paragraph({
children: [new TextRun({ text: '(如目录未显示,请在 Word 中右键此处 → 更新域)', size: 18, font: FONT, italics: true, color: '888888' })],
spacing: { before: 40, after: 200 },
}));
ch.push(tocChapter('', '文档控制'));
ch.push(tocSub('', '更改记录'));
ch.push(tocSub('', '审核'));
ch.push(tocSub('', '发布'));
ch.push(tocChapter('', '目录'));
// 第1章
ch.push(tocChapter('1', '总体业务方案'));
ch.push(tocSub('1.1', '目标和宗旨'));
ch.push(tocSub('1.2', '总体业务流程图'));
ch.push(tocSub('1.3', '方案设计'));
// 第2~12章(8子章节)
const chSubs = [
'目标/宗旨', '业务流程图', '业务流程说明', '业务流程规则',
'变化和改进点', '权限管理需求', '系统接口集成', '报表需求',
];
const chTitles = [
'物料需求计划', '物料交货计划', '交货单异常记录',
'要货令', '物料采购申请', '物料采购订单',
'委外加工订单', '工序外协订单',
'供应协同看板', '工单物料齐套上线看板', 'MDP 运行监控',
];
for (let i = 0; i < chTitles.length; i++) {
const n = i + 2;
ch.push(tocChapter(String(n), chTitles[i]));
for (let j = 0; j < chSubs.length; j++) {
ch.push(tocSub(`${n}.${j + 1}`, chSubs[j]));
}
}
// 第13章
ch.push(tocChapter('13', '数据中台架构'));
['目标/宗旨', '分层设计', 'S3核心数据流', '对象映射总表', 'MDP作业调度'].forEach((title, i) => {
ch.push(tocSub(`13.${i + 1}`, title));
});
// 第14章
ch.push(tocChapter('14', '权限管理汇总'));
return ch;
}
// ═══════════════════════════════════════════════════
// 流程图生成 (S1 style: 纵向左角色+右节点)
// ═══════════════════════════════════════════════════
const FLOW_W = 680, BOX_W = 220, BOX_H = 42, GAP_Y = 28;
const ROLE_X = 30, BOX_X = 130, MARGIN_Y = 40;
const flowImageCache = {};
function flowImageParagraph(pngBuffer) {
return new Paragraph({
children: [new ImageRun({ data: pngBuffer, transformation: { width: 540, height: 360 }, type: 'png' })],
alignment: AlignmentType.CENTER,
spacing: { before: 120, after: 120 },
});
}
async function generateFlowPNG(steps) {
const N = steps.length;
const svgH = MARGIN_Y * 2 + N * (BOX_H + GAP_Y) - GAP_Y;
const centerX = BOX_X + BOX_W / 2;
let svg = `';
return sharp(Buffer.from(svg)).png().toBuffer();
}
// 第1章专用:S3 总体业务流程图(三区: 物料计划 → 采购执行 → 协同看板)
async function generateOverviewFlowPNG() {
const W = 780, H = 580;
let svg = `';
return sharp(Buffer.from(svg)).png().toBuffer();
}
// ═══════════════════════════════════════════════════
// 章节构建函数:8 子章节
// ═══════════════════════════════════════════════════
function buildChapter(num, title, cfg) {
const ch = [];
const pre = `${num}.`;
// §X.1 目标/宗旨
ch.push(h2(`${pre}1 目标/宗旨`));
(cfg.targets || []).forEach(t => ch.push(bullet(t)));
// §X.2 业务流程图
ch.push(h2(`${pre}2 业务流程图`));
const img = cfg.flowImage || (cfg.flowSteps ? flowImageCache[num] : null);
if (img) {
ch.push(flowImageParagraph(img));
} else {
ch.push(p('(见系统操作流程图 / 附件 Visio 流程图)'));
}
if (cfg.flowNote) ch.push(p(cfg.flowNote));
// §X.3 业务流程说明
ch.push(h2(`${pre}3 业务流程说明`));
if (cfg.activities && cfg.activities.length) {
ch.push(activityTable(cfg.activities));
} else {
ch.push(p('参照系统页面操作流程,主要操作步骤包含:'));
(cfg.activityDesc || []).forEach(a => ch.push(bullet(a)));
}
// §X.4 业务流程规则
ch.push(h2(`${pre}4 业务流程规则`));
if (cfg.rules && cfg.rules.length) {
ch.push(ruleTable(cfg.rules));
} else {
ch.push(p('无特殊业务规则'));
}
// §X.5 变化和改进点
ch.push(h2(`${pre}5 变化和改进点`));
(cfg.improvements || []).forEach(i => ch.push(bullet(i)));
// §X.6 权限管理需求
ch.push(h2(`${pre}6 权限管理需求`));
if (cfg.permissions && cfg.permissions.length) {
ch.push(permTable(cfg.permissions));
} else {
ch.push(p('参照第 14 章 权限管理汇总'));
}
// §X.7 系统接口集成
ch.push(h2(`${pre}7 系统接口集成`));
if (cfg.interfaces && cfg.interfaces.length) {
ch.push(interfaceTable(cfg.interfaces));
} else {
ch.push(p('无外部系统接口;页面数据通过 Admin.NET 内置 API 获取'));
}
// §X.8 报表需求
ch.push(h2(`${pre}8 报表需求`));
if (cfg.reports && cfg.reports.length) {
ch.push(reportTable(cfg.reports));
} else {
ch.push(p('无独立报表需求,相关数据通过看板和列表页面查看'));
}
return ch;
}
// ═══════════════════════════════════════════════════
// 章节数据配置
// ═══════════════════════════════════════════════════
// ── Chapter 2: 物料需求计划 ──
const _ch2cfg = {
targets: [
'实现物料需求计划的在线管理,通过MDP同步外部系统工单需求、库存和采购在途数据。',
'利用MRP逻辑自动计算物料净需求,生成可供发布的物料需求计划,为采购管理和交货计划提供数据基础。',
'核心KPI为物料净需求的准确性和计划发布的及时性。',
],
flowNote: '流程路径:MDP数据同步(工单/库存/在途) → MRP净需求计算 → 勾选发布/全部发布 → 手动调整 → 驱动采购申请/交货计划。',
flowSteps: [
{ label: 'MDP数据同步(工单/库存/在途)', role: '物料计划员' },
{ label: 'MRP净需求计算', role: '物料计划员' },
{ label: '勾选发布/全部发布', role: '物料计划员' },
{ label: '手动新增/编辑/删除', role: '物料计划员' },
{ label: '驱动采购申请/交货计划', role: '系统自动' },
],
activities: [
['10', '数据同步', '系统(MDP)', 'MDP定时从ERP同步工单需求、库存和采购在途数据写入ODS层', '外部系统数据', 'ODS数据'],
['20', 'MRP净需求计算', '系统(DWD)', 'DWD层清洗关联,计算To-be-Scheduled Qty = MES Qty - Loc Qty - Scheduled Qty', 'ODS工单/库存/在途数据', '物料净需求结果'],
['30', '计划查询筛选', '物料计划员', '按物料编码、物料名称、需求日期等维度过滤查询,支持分页和列设置', '查询条件', '物料需求列表'],
['40', '发布管理', '物料计划员', '支持勾选定向发布或一键全部发布,发布后状态变为"已发布",可取消发布回退', '未发布计划', '已发布/取消发布计划'],
['50', '手动CRUD', '物料计划员', '支持手动新增、编辑、删除物料需求记录,满足特殊场景灵活调整', '手动录入数据', '更新后计划'],
],
rules: [
['1', '净需求计算公式', 'To-be-Scheduled Qty = MES Qty - Loc Qty - Scheduled Qty,结果为负时净需求为零'],
['2', '发布校验', '发布前不做业务规则校验,计划员自行确认数据准确性后执行;仅已发布状态可取消发布'],
['3', '删除限制', '删除操作需二次确认,防止误操作'],
['4', '数据隔离', '不同租户数据通过租户ID隔离,同一租户内计划员共享视图'],
],
improvements: [
'原ERP物料需求计算为离线批处理,S3通过MDP实时同步将计算频率从"每日一次"提升为"近实时"。',
'新增勾选发布和全部发布两种模式,替代原系统单一全量发布方式,提高操作灵活性。',
'新增取消发布功能,填补原系统缺乏"发布回退"能力的空白。',
'新增列设置功能,不同角色可按需配置显示的字段组合。',
],
permissions: [
['1', '物料计划员', '查看和增删改查权限;发布/取消发布操作权限'],
['2', '采购员/供应链经理', '仅查看权限(只读)'],
],
interfaces: [
['1', 'MDP入站-工单需求', '从ERP同步工单需求数据(work_order_demand)', '定时(日)'],
['2', 'MDP入站-库存快照', '从库存系统同步期初库存(inventory snapshot)', '定时(日)'],
['3', 'MDP入站-在途采购', '从SRM同步采购在途数据', '定时(日)'],
['4', 'MDP出站-需求发布', '发布后物料需求计划同步至SRM驱动采购申请', '发布时触发'],
],
reports: [
['1', '物料需求计划明细报表', '按日期范围导出指定物料的需求计算明细', 'Excel/CSV格式'],
['2', '需求计划发布统计报表', '按时间段统计发布数量、发布及时率', '按周/月'],
['3', '需求满足率趋势报表', '按周/月展示物料净需求满足趋势', '趋势图表'],
],
};
const ch2 = () => buildChapter('2', '物料需求计划', _ch2cfg);
// ── Chapter 3: 物料交货计划 ──
const _ch3cfg = {
targets: [
'基于已发布物料需求计划生成交货计划,并驱动供应商端交货计划同步。',
'通过交货状态同步实现供应商与计划端的双向信息互通,提升交货管理的协同效率。',
],
flowNote: '流程路径:已发布物料需求计划 → 交货计划生成 → 驱动供应商交货计划 → 交货状态同步。',
flowSteps: [
{ label: '已发布物料需求计划', role: '物料计划员' },
{ label: '交货计划生成', role: '物料计划员' },
{ label: '驱动供应商交货计划', role: '物料计划员' },
{ label: '交货状态同步', role: '系统自动' },
],
activities: [
['10', '需求发布', '物料计划员', '基于MRP净需求计算结果确认并发布物料需求计划,作为交货计划的输入来源', 'MRP净需求结果', '已发布物料需求计划'],
['20', '计划生成', '系统(MDP)', '基于已发布物料需求计划自动生成交货计划,含物料、供应商、计划交期等核心信息', '已发布需求', '交货计划记录'],
['30', '驱动供应商', '物料计划员/系统', '交货计划同步至供应商端,驱动供应商按计划安排生产和交货', '交货计划', '供应商交货计划'],
['40', '状态同步', '系统(MDP)', '供应商交货状态回传至计划端,实现双向信息同步更新', '供应商交货状态', '同步后交货计划'],
],
rules: [
['1', '生成条件', '仅基于已发布物料需求计划生成交货计划,未发布需求不进入交货计划流程'],
['2', '供应商驱动', '交货计划生成后自动同步至供应商端,驱动供应商按计划安排交货'],
['3', '状态同步规则', '供应商交货状态变更时自动回传至计划端,确保计划与执行数据一致'],
['4', '交货单号唯一性', '每个交货计划行对应唯一dsnum,用于与供应商端交货单关联匹配'],
],
improvements: [
'从原ERP中交货计划与采购订单混合管理升级为独立专项页面,聚焦交货协同视角。',
'新增供应商交货计划驱动机制,替代原系统单向信息传递方式,实现双向协同。',
'新增交货状态自动同步功能,供应商交货反馈实时回传至计划端。',
],
permissions: [
['1', '物料计划员', '查看和操作权限'],
['2', '采购员/仓库管理员', '仅查看权限'],
['3', '供应链经理', '查看和导出权限'],
],
interfaces: [
['1', 'MDP入站-需求发布', '从物料需求计划读取已发布需求', '发布时触发'],
['2', 'MDP出站-交货计划', '交货计划同步至供应商端驱动生产和交货', '计划生成时'],
['3', 'MDP入站-交货状态', '供应商交货状态变更回传至计划端', '状态变更时'],
['4', '核心数据表', 'srm_polist_ds(采购订单交付计划)', '实时关联'],
],
reports: [
['1', '交货计划执行报表', '按供应商/物料统计交货计划生成与执行情况', '按周/月'],
['2', '供应商交货准时率报表', '按时间段统计各供应商交货准时率', '供应商维度'],
['3', '交货状态同步报表', '监控交货状态同步成功率和延迟情况', '实时监控'],
],
};
const ch3 = () => buildChapter('3', '物料交货计划', _ch3cfg);
// ── Chapter 4: 交货单异常记录 ──
const _ch4cfg = {
targets: [
'提供交货过程中产生的异常记录的只读查询视图,帮助物料计划员和质量管理人员快速掌握交货逾期、短缺、质量等异常情况。',
'异常数据来源于系统自动比对的交货计划与实际交货差异,为供应链风险管理和供应商绩效评估提供数据支撑。',
],
flowNote: '流程路径:MDP同步交货数据 → 系统自动比对计划vs实际 → 差异超阈值自动标记异常 → 异常记录列表展示 → 多维筛选查询 → 明细查看/导出。',
flowSteps: [
{ label: 'MDP同步交货数据', role: '系统(MDP)' },
{ label: '系统自动比对计划vs实际差异', role: '系统自动' },
{ label: '超阈值自动标记异常记录', role: '系统自动' },
{ label: '多维筛选查询(单号/供应商/类型/日期)', role: '物料计划员' },
{ label: '明细查看/导出', role: '物料计划员' },
],
activities: [
['10', '异常自动标记', '系统(MDP)', '基于交货计划与实际交货数据自动比对,逾期超3天或实收<计划80%时自动生成异常标记', '交货执行数据', '异常记录'],
['20', '异常记录查询', '计划员/质量员', '按交货单号、供应商、异常类型、计划日期范围多维度筛选查询', '筛选条件', '异常记录列表'],
['30', '明细查看', '计划员/质量员', '查看每条异常记录的详细信息:来源交货单、物料、计划/实际数量、异常原因', '异常记录', '异常详情'],
['40', '数据导出', '计划员', '将当前查询结果导出为CSV/Excel文件', '查询结果', '导出文件'],
],
rules: [
['1', '自动标记条件', '逾期超过3个工作日未到货,或实收数量<计划数量80%时,系统自动标记为异常记录'],
['2', '数据来源', '异常记录数据来源于MDP同步的交货计划和实际交货数据自动比对结果'],
['3', '只读视图', '该页面为只读查询视图,不支持手动新增、编辑或删除异常记录,确保数据客观性'],
['4', '可追溯性', '每条异常记录可关联到原始交货计划记录,追溯异常来源和影响范围'],
],
improvements: [
'从原系统"纸质异常报告+Excel人工比对"升级为系统自动识别和在线查询,减少人工发现异常的延迟和遗漏。',
'新增自动触发规则,系统根据阈值自动标记异常,替代原系统完全依赖人工发现的方式。',
'异常数据与供应商绩效评估模块联动,为供应商评级提供量化依据。',
],
permissions: [
['1', '物料计划员', '查看和导出权限'],
['2', '质量管理员', '查看权限(质量追溯)'],
['3', '供应链经理', '查看和导出权限'],
],
interfaces: [
['1', '交货差异比对', 'MDP从交货计划与收货数据自动比对计划vs实际差异', '定时(日)'],
['2', '核心数据表', 'DeliveryExceptionMaster(交货异常记录视图)', '只读查询'],
],
reports: [
['1', '交货异常统计报表', '按供应商/异常类型/时间段统计异常数量及趋势', '按周/月'],
['2', '供应商异常率排名报表', '按异常发生率对供应商排名,用于供应商绩效评估', '供应商维度'],
],
};
const ch4 = () => buildChapter('4', '交货单异常记录', _ch4cfg);
// ── Chapter 5: 要货令 ──
const _ch5cfg = {
targets: [
'承接物料采购申请驱动的要货指令(Demand Order)在线管理,作为采购执行的具体载体。',
'通过供应选择和物料选择确保要货令的精准下达,建立从申请到执行的衔接。',
],
flowNote: '流程路径:物料采购申请驱动 → 要货令创建 → 供应选择 → 物料选择 → 订单保存。',
flowSteps: [
{ label: '物料采购申请驱动', role: '采购员' },
{ label: '要货令创建', role: '采购员' },
{ label: '供应选择', role: '采购员' },
{ label: '物料选择', role: '采购员' },
{ label: '订单保存', role: '采购员' },
],
activities: [
['10', '申请驱动', '采购员', '接收已批准物料采购申请驱动信号,启动要货令创建流程', '已批准采购申请', '要货令创建入口'],
['20', '要货令创建', '采购员', '填写要货令核心信息:单号、采购组、部门、日期、合同编号等', '采购申请驱动', '要货令主记录'],
['30', '供应选择', '采购员', '从货源清单动态加载下拉选择供应商和采购组,确保数据实时性', '货源清单', '选定供应商/采购组'],
['40', '物料选择', '采购员', '选择要货物料,填写需求数量、交货日期等明细信息', '物料列表', '要货令明细行'],
['50', '订单保存', '采购员', '确认无误后保存要货令,生成DO类型采购订单记录', '要货令数据', '已保存要货令(PurOrdMaster/DO)'],
],
rules: [
['1', '驱动来源', '要货令由已批准物料采购申请驱动生成,确保需求来源可追溯'],
['2', '必填校验', '供应商、物料、需求数量为必填字段,提交时进行非空校验'],
['3', '供应校验', '选择的供应商须在有效货源清单中,确保货源合规'],
['4', '单号唯一性', '要货令单号需保证唯一性,删除操作需二次确认'],
],
improvements: [
'从原采购申请/要货令混合管理升级为采购申请驱动→要货令执行的清晰链路。',
'新增供应选择独立步骤,从货源清单动态加载,确保供应商资质合规。',
'新增物料选择独立步骤,支持明细行级精准管理。',
],
permissions: [
['1', '采购员', '增删改查全部权限'],
['2', '供应链经理', '查看权限'],
],
interfaces: [
['1', 'MDP入站-采购申请', '从物料采购申请读取已批准申请作为驱动来源', '申请批准时触发'],
['2', 'MDP入站-供应商数据', '供应商和采购组数据从SRM系统同步', '定时(日)'],
['3', 'MDP出站-要货令', '保存后要货令数据同步至ERP', '保存时触发'],
['4', '核心数据表', 'PurOrdMaster(采购订单主表,ReqBy=DO类型)', '实时'],
],
reports: [
['1', '要货令执行报表', '按时间段统计要货令数量和供应商分布', '按周/月'],
['2', '供应商要货令统计', '按供应商维度汇总要货令下发情况', '供应商维度'],
],
};
const ch5 = () => buildChapter('5', '要货令', _ch5cfg);
// ── Chapter 6: 物料采购申请 ──
const _ch6cfg = {
targets: [
'承接物料交货计划和MRP检查输出的采购需求,通过规范的申请-审批流程确保采购需求的合理性和合规性。',
'批准后根据物料类型自动驱动生成对应的采购订单(PO)、要货令(DO)或委外加工订单(PW),作为采购执行的依据。',
],
flowNote: '流程路径:物料交货计划/MRP检查 → 采购申请创建 → 审核/批准 → 驱动采购订单/要货令/委外加工订单生成。',
flowSteps: [
{ label: '物料交货计划/MRP检查驱动', role: '采购员' },
{ label: '采购申请创建/编辑', role: '采购员' },
{ label: '审核/批准', role: '审批人' },
{ label: '驱动采购订单/要货令/委外加工', role: '系统自动' },
],
activities: [
['10', '申请创建', '采购员', '基于物料交货计划或MRP检查结果新增采购申请,填写申请单号、物料、供应商、需求数量、需求日期', '物料交货计划/MRP检查结果', '采购申请单'],
['20', '查询编辑', '采购员', '按申请单号、物料、供应商、状态多维度筛选查询,支持编辑未提交的申请', '筛选条件', '申请列表'],
['30', '审批流流转', '审批人', '申请单提交后进入审批流,经指定审批人审核后状态更新为"已批准"', '已提交申请', '审核/批准结果'],
['40', '订单驱动', '系统', '已批准申请根据物料类型自动合并生成对应订单:DO物料→要货令,PO物料→采购订单,PW物料→委外加工订单', '已批准申请', '采购订单/要货令/委外加工订单'],
],
rules: [
['1', '审批流规则', '申请单提交后进入审批流,需经指定审批人审核后方可进入"已批准"状态'],
['2', '必填校验', '物料编码、供应商、需求数量、需求日期为必填,需求数量须>0'],
['3', '来源校验', '申请创建时需校验物料交货计划或MRP检查记录已发布且未关闭'],
['4', '批准后保护', '已批准申请单不可编辑或删除,仅可查看,保护审批结果严肃性'],
['5', '订单驱动规则', '批准后系统根据物料类型自动合并生成对应订单:DO物料→要货令,PO物料→采购订单,PW物料→委外加工订单'],
],
improvements: [
'从原系统依赖邮件/纸质审批升级为系统化审批流,审批过程可追溯、可审计。',
'新增与物料交货计划和MRP检查的关联追溯,确保需求来源可查。',
'新增状态驱动的操作权限控制(不同状态下可执行不同操作)。',
'新增批准后自动按物料类型分流驱动三类订单(采购订单/要货令/委外加工订单),替代原系统手动分类下达方式。',
],
permissions: [
['1', '采购员', '增删改查和提交权限'],
['2', '审批人(采购经理)', '审核/批准权限'],
['3', '物料计划员', '仅查看权限'],
],
interfaces: [
['1', 'MDP入站-交货计划', '从物料交货计划读取可关联的交货计划行项', '实时'],
['2', 'MDP入站-MRP检查', '从MRP检查结果读取可关联的需求行项', '实时'],
['3', 'MDP出站-批准申请', '批准后采购申请数据同步至ERP,根据物料类型自动分流驱动订单生成', '批准时触发'],
],
reports: [
['1', '采购申请审批效率报表', '统计申请从提交到批准的平均审批时长', '按周/月'],
['2', '采购申请转化率报表', '统计申请转化为各类型订单(PO/DO/PW)的比例', '按周/月'],
['3', '申请金额汇总报表', '按部门/采购组统计采购申请金额', '按周/月'],
],
};
const ch6 = () => buildChapter('6', '物料采购申请', _ch6cfg);
// ── Chapter 7: 物料采购订单 ──
const _ch7cfg = {
targets: [
'管理已下达至供应商的正式采购订单,跟踪订单从下达到收货完成的全生命周期。',
'确保采购执行的透明度和可控性,为S4交货管理提供数据基础。',
],
flowNote: '流程路径:采购订单生成 → 供应商确认/交期回复 → 发货关联 → 订单状态跟踪 → 收货完成/订单关闭。',
flowSteps: [
{ label: '采购订单生成', role: '采购员' },
{ label: '供应商确认/交期回复', role: '采购员' },
{ label: '发货关联', role: '采购员' },
{ label: '订单状态跟踪', role: '采购员' },
{ label: '收货完成/订单关闭', role: '系统自动' },
],
activities: [
['10', '订单生成', '采购员/系统', '基于已批准采购申请自动或手动生成采购订单,填写供应商、物料、数量、交期等核心信息', '已批准采购申请', '采购订单'],
['20', '供应商确认', '采购员', '供应商在线确认订单并回复预计交期,确认信息回写至订单', '供应商反馈', '确认后订单'],
['30', '发货关联', '采购员', '关联发货单数据,展示发货数量、日期与订单的对应关系', '发货数据', '发货关联视图'],
['40', '状态跟踪', '采购员', '跟踪订单从"已下达→部分收货→已完成→已关闭"完整生命周期状态', '订单数据', '状态视图'],
['50', '收货关闭', '系统', '收货数据累计达订单数量时自动更新为"已完成",已完成订单可手动关闭', '收货数据', '订单关闭'],
],
rules: [
['1', '订单号唯一性', '每个采购订单具有唯一订单号,自动分配或手动输入'],
['2', '供应商校验', '生成订单时校验供应商是否在有效货源清单中,确保货源合规'],
['3', '来源追溯', '订单来源于已批准的采购申请,确保需求可追溯'],
['4', '状态自动更新', '收货数据累计达订单数量时状态自动更新为"已完成"'],
['5', '订单关闭', '已完成/已取消订单可手动关闭,关闭后不可再收货'],
],
improvements: [
'从原ERP分散的采购订单管理整合为统一页面,支持跨供应商、跨物料一站式查询。',
'新增发货关联视图,替代原系统手动比对发货与订单的低效方式。',
'新增订单状态自动流转机制,减少人工状态更新的延迟和错误。',
],
permissions: [
['1', '采购员', '增删改查权限'],
['2', '物料计划员/供应链经理', '仅查看权限'],
['3', '仓库管理员', '查看权限(安排收货计划)'],
],
interfaces: [
['1', 'MDP入站-供应商确认', '从SRM同步供应商订单确认和交期回复数据', '定时(日)'],
['2', 'MDP入站-发货数据', '从WMS/SRM同步发货单数据用于发货关联', '定时(日)'],
['3', 'MDP出站-采购订单', '采购订单数据同步至ERP触发收货和付款流程', '订单变更时'],
['4', '核心数据表', 'vscm_jhjh(采购订单供应商视角)+ PurOrdMaster', '实时'],
],
reports: [
['1', '采购订单执行进度报表', '按订单/供应商展示下达数量、收货数量、完成百分比', '按周/月'],
['2', '采购订单逾期报表', '对超过计划交货日期未完成的订单生成逾期清单', '实时监控'],
['3', '采购金额汇总报表', '按时间段/采购组/供应商汇总采购金额', '按月/季'],
],
};
const ch7 = () => buildChapter('7', '物料采购订单', _ch7cfg);
// ── Chapter 8: 委外加工订单 ──
const _ch8cfg = {
targets: [
'管理委托外部供应商进行物料加工的采购订单(PurOrdMaster/PW类型)。',
'支持订单明细的增删改查和物料选择,确保委外加工业务的规范化和可追溯性。',
],
flowNote: '流程路径:委外加工订单创建 → 委外商选择 → 货源清单物料选择 → 明细行管理 → 订单保存。',
flowSteps: [
{ label: '委外加工订单创建', role: '外协管理员' },
{ label: '委外商选择', role: '外协管理员' },
{ label: '货源清单物料选择', role: '外协管理员' },
{ label: '明细行管理', role: '外协管理员' },
{ label: '订单保存', role: '外协管理员' },
],
activities: [
['10', '订单创建', '外协管理员', '新增委外加工订单,填写订单基本信息', '委外需求', '委外订单记录'],
['20', '委外商选择', '外协管理员', '从货源清单选择委外加工供应商', '货源清单', '选定委外商'],
['30', '货源物料选择', '外协管理员', '从货源清单(selectSourceList)选择委外加工物料', '货源清单', '选中物料'],
['40', '明细行管理', '外协管理员', '管理每个明细行的物料、数量、单价、交货日期等', '选中物料', '订单明细行'],
['50', '订单保存', '外协管理员', '确认无误后保存委外加工订单,生成PW类型订单记录', '委外订单数据', '已保存委外订单(PurOrdMaster/PW)'],
],
rules: [
['1', '订单类型区分', '委外加工订单类型为PW,与普通采购订单PO类型区分管理'],
['2', '货源校验', '选择委外商和委外物料时需校验其在货源清单中存在且状态有效'],
['3', '必填字段', '委外商、物料、加工数量、计划交付日期为必填项'],
['4', '明细行数量', '每个委外加工订单至少需包含一个明细行,不允许空订单'],
],
improvements: [
'从原ERP与普通采购订单混合管理升级为独立页面,支持PW类型专项管理。',
'新增货源清单校验,确保委外业务物料选择合规。',
'新增订单明细子页面增删改查,替代原系统单层管理方式。',
],
permissions: [
['1', '外协管理员', '增删改查全部权限'],
['2', '采购员/供应链经理', '查看权限'],
],
interfaces: [
['1', 'MDP入站-货源清单', '从SRM同步货源清单数据(sourcing_item表)', '定时(日)'],
['2', 'MDP出站-委外订单', '委外加工订单数据同步至ERP,与生产工单关联', '订单变更时'],
['3', '核心数据表', 'PurOrdMaster(订单类型PW)', '实时'],
],
reports: [
['1', '委外加工订单执行报表', '按委外商/物料统计订单下达和完成情况', '按周/月'],
['2', '委外加工成本分析', '按时间段/委外商统计委外加工总成本', '按月/季'],
],
};
const ch8 = () => buildChapter('8', '委外加工订单', _ch8cfg);
// ── Chapter 9: 工序外协订单 ──
const _ch9cfg = {
targets: [
'管理生产过程中特定工序委托外部供应商完成的采购订单。',
'支持工单-工序-外协订单三级关联,确保工序外协业务的精细化管理。',
],
flowNote: '流程路径:选择生产工单 → 选择外协工序 → 创建外协订单 → 供应商/数量校验 → 订单保存/工单工序关联。',
flowSteps: [
{ label: '选择生产工单', role: '外协管理员' },
{ label: '选择外协工序', role: '外协管理员' },
{ label: '创建外协订单', role: '外协管理员' },
{ label: '供应商/数量校验', role: '系统自动' },
{ label: '订单保存/工单工序关联', role: '系统自动' },
],
activities: [
['10', '选择工单', '外协管理员', '从生产工单列表选择需要外协的生产工单', '生产工单', '选中工单'],
['20', '选择工序', '外协管理员', '通过selectProcessWorkOrder组件从工单选择需要外协的工序', '选中工单', '选中工序'],
['30', '创建订单', '外协管理员', '基于选中的工单和工序创建外协订单,填写供应商、数量、交期等', '选中工序', '外协订单'],
['40', '供应商/数量校验', '系统', '校验外协商在货源清单中有效、外协数量不超过工序计划生产数量', '外协订单', '校验结果'],
['50', '保存关联', '外协管理员/系统', '保存订单并与生产工单工序建立关联,工单状态联动', '校验通过订单', '已保存关联订单'],
],
rules: [
['1', '工单校验', '选择的工序必须属于有效生产工单(状态不为已关闭或已取消)'],
['2', '工序唯一性', '同一工单同一工序不可重复创建外协订单,防止重复委外'],
['3', '供应商校验', '外协商必须在货源清单中有效,确保外协供应商资质'],
['4', '数量约束', '外协数量不可超过工单该工序的计划生产数量'],
],
improvements: [
'从原系统手工Excel管理升级为系统化管理,支持工单-工序-外协订单三级关联。',
'新增供应商/数量校验环节,确保外协业务合规。',
'新增订单保存与工单工序自动关联,实现工单状态联动。',
],
permissions: [
['1', '外协管理员', '增删改查全部权限'],
['2', '生产计划员', '查看权限'],
],
interfaces: [
['1', 'MDP入站-工单工序', '从MES同步生产工单和工序数据', '定时(日)'],
['2', 'MDP出站-外协订单', '工序外协订单数据同步至ERP', '订单变更时'],
['3', '核心数据表', 'PurOrdMaster(PW类型,关联工单和工序信息)', '实时'],
],
reports: [
['1', '工序外协执行报表', '按工单/工序/外协商统计外协订单执行情况', '按周/月'],
['2', '外协成本分析', '按工序类型统计外协成本', '按月/季'],
],
};
const ch9 = () => buildChapter('9', '工序外协订单', _ch9cfg);
// ── Chapter 10: 供应协同看板 ──
const _ch10cfg = {
targets: [
'为管理层和业务人员提供S3模块的核心KPI可视化看板。',
'通过三大L1核心指标(工单按需准时齐套率、工单齐套周期、物料库存周转天数)全面监控供应健康度。',
'支持策略模拟What-If分析和运营指标建模配置。',
],
flowNote: '流程路径:MDP数据同步/运营指标建模 → 4维KPI卡片展示 → 趋势箭头分析 → 多维筛选联动 → 分支看板(需求计划/交货计划) → 策略模拟/导出。',
flowSteps: [
{ label: 'MDP数据同步/运营指标建模', role: '供应链经理' },
{ label: '4维KPI卡片+趋势箭头展示', role: '供应链经理' },
{ label: '多维筛选联动/分支看板视图', role: '供应链经理' },
{ label: 'MDP同步任务监控', role: 'IT运维人员' },
{ label: '策略模拟What-If/报表导出', role: '供应链经理' },
],
activities: [
['10', '数据加载', '系统', '页面初始化从后端加载homeS3最新KPI计算数据', 'KPI数据库', 'KPI展示数据'],
['20', 'KPI卡片展示', '供应链经理', '4个KPI卡片:物料计划周期、物料计划满足率、物料计划人数、物料库存周转', 'KPI数据', '趋势+标签卡片'],
['30', '基础查询', '供应链经理', '按日期、产品、订单号、产线、物料、供应商维度筛选', '筛选条件', '筛选后数据'],
['40', '分支视图', '供应链经理', '分支一:MRP维度(BOM需求满足趋势+统计表);分支二:MDP维度(交货执行进度+满足率)', '看板数据', '分支详情'],
['50', '操作功能', '供应链经理', '策略模拟(What-If分析)、导出报表、运营指标建模链接跳转', '看板数据', '模拟结果/导出文件'],
],
rules: [
['1', '指标等级判定', '齐套率低于目标标"严重"(红),齐套周期超目标标"警告"(橙),库存周转达标标"优秀"(绿)'],
['2', '趋势计算', '趋势箭头基于同比/环比计算,上升为绿色箭头,下降为红色箭头'],
['3', '数据刷新', '页面不自动刷新,需手动点击刷新按钮获取最新数据'],
['4', '筛选联动', '基础查询条件变更时,KPI卡片和分支视图同步更新'],
],
improvements: [
'从原系统零散Excel报表升级为实时可视化看板,支持交互式数据探索。',
'新增策略模拟功能(What-If),替代原系统依赖人工计算的分析方式。',
'新增指标建模配置入口,支持自定义KPI口径,替代硬编码指标定义方式。',
],
permissions: [
['1', '供应链经理', '查看、导出和策略模拟权限'],
['2', '物料计划员/采购员/仓管员', '查看权限'],
['3', '工厂厂长/总经理', '查看权限'],
],
interfaces: [
['1', '看板聚合API', 'GET /api/AidopKanban/module-detail?moduleCode=S3', '实时(页面加载)'],
['2', 'KPI数据源', 'homeS3数据对象 (demandKitRatePct, kitCycleDays, materialInventoryTurnoverDays)', 'MDP定时刷新'],
['3', '运营指标建模', 'KPI口径和计算公式通过运营指标建模模块配置', '配置驱动'],
],
reports: [
['1', '供应协同月度报告', '含三大L1指标月度趋势和同比分析', '按月度'],
['2', '策略模拟分析报告', '记录策略模拟的输入参数和输出结果', '按需'],
],
};
const ch10 = () => buildChapter('10', '供应协同看板', _ch10cfg);
// ── Chapter 11: 工单物料齐套上线看板 ──
const _ch11cfg = {
targets: [
'以工单为维度,展示每个工单所需物料的齐套状态(需求、发料、欠料、备料、在检、在途、承诺数量)。',
'帮助生产计划和物料计划人员精准识别缺料工单和责任供应商。',
],
flowNote: '流程路径:MDP数据同步(工单/BOM/库存/在途) → MRP齐套计算 → 30+字段齐套信息展示 → 缺料定位/供应商维度分析 → 缺料预警/策略建议。',
flowSteps: [
{ label: 'MDP同步(工单/BOM/库存/在途)', role: '物料计划员' },
{ label: 'MRP齐套计算/手动刷新', role: '物料计划员' },
{ label: '30+字段齐套信息展示', role: '物料计划员' },
{ label: '欠料定位/供应商维度分析', role: '物料计划员' },
{ label: '缺料预警/策略建议输出', role: '系统自动' },
],
activities: [
['10', '数据加载', '系统', '从WorkOrdDetailTotalKB宽表加载工单物料齐套数据', 'MDP宽表', '齐套数据'],
['20', '多维筛选', '物料计划员', '按订单号、工单号、产品编码、物料编码、供应商名称筛选', '筛选条件', '筛选后列表'],
['30', '齐套信息展示', '物料计划员', '展示30+字段:序号、订单/工单号、BOM版本、物料描述、需求/发料/欠料/备料/在检/在途数量', '齐套数据', '齐套明细'],
['40', '缺料定位', '物料计划员', '欠料数量(shortage)>0标记为"未齐套",定位影响供应商', '齐套明细', '缺料清单'],
['50', '列设置/排序', '物料计划员', '自定义显示/隐藏列,多字段升序/降序排序,分页10/20/50', '视图配置', '个性化视图'],
],
rules: [
['1', '齐套判定', '欠料数量(shortage)>0时该物料行视为"未齐套"'],
['2', '欠料计算', 'shortage = qtyRequired - qtyRec,发料不足差额即为欠料'],
['3', '刷新触发', '调用refreshWorkOrderMaterialReadiness接口重新执行MRP齐套计算'],
['4', '分页显示', '按分页加载,支持10/20/50条每页,优化大数据量页面性能'],
],
improvements: [
'从原系统手工Excel跟踪齐套状态升级为实时在线看板,数据来源于MDP实时计算宽表。',
'新增30+字段完整视图,替代原系统仅有"物料/需求数量"两个维度的简单跟踪。',
'新增供应商维度齐套分析(供应商编码/名称/采购组/采购员),快速定位责任供应商。',
'新增列设置和排序功能,支持不同角色个性化视图配置。',
],
permissions: [
['1', '物料计划员/生产计划员', '查看和刷新权限'],
['2', '采购员', '查看权限(了解管辖供应商物料齐套情况)'],
['3', '车间主任/供应链经理', '查看权限'],
],
interfaces: [
['1', 'MDP入站-齐套数据', '从ERP/MES/SRM同步工单需求、BOM、库存、在途、发货数据,DWD关联计算入宽表', '定时(日)'],
['2', '齐套刷新API', 'refreshWorkOrderMaterialReadiness触发MRP齐套重算', '手动触发'],
['3', '核心数据表', 'WorkOrdDetailTotalKB(工单物料欠料宽表)', '实时'],
],
reports: [
['1', '工单齐套日报', '每日按工单汇总齐套率和欠料明细', '日报'],
['2', '供应商齐套分析', '按供应商统计供货工单齐套率,用于供应商绩效评估', '按周/月'],
['3', '欠料预警报表', '对欠料超阈值工单生成预警清单', '实时推送'],
],
};
const ch11 = () => buildChapter('11', '工单物料齐套上线看板', _ch11cfg);
// ── Chapter 12: MDP 运行监控 ──
const _ch12cfg = {
targets: [
'提供S3相关MDP数据同步与转换任务的运行状态可视化。',
'帮助IT运维人员和业务管理员及时发现和定位数据同步失败、转换异常等问题,确保数据准确性和时效性。',
],
flowNote: '流程路径:MDP任务调度引擎运行 → 同步日志记录 → 任务状态列表展示 → 异常告警 → 运维响应处理。',
flowSteps: [
{ label: 'MDP任务调度引擎运行', role: '系统(MDP)' },
{ label: '同步日志记录(成功/失败/运行中)', role: '系统(MDP)' },
{ label: 'S3模块任务列表展示', role: 'IT运维人员' },
{ label: '失败任务红色高亮告警', role: '系统' },
{ label: '运维响应处理/数据修复', role: 'IT运维人员' },
],
activities: [
['10', '任务列表展示', 'IT运维', '展示S3相关MDP同步任务列表:任务名、运行状态、开始/结束时间、记录数、错误信息', 'MDP日志', '任务列表'],
['20', '状态筛选', 'IT运维', '按任务状态(全部/成功/失败/运行中)过滤', '筛选条件', '筛选后列表'],
['30', '异常告警', '系统', '失败任务红色高亮标识和告警提示,便于及时响应', '任务状态', '告警视图'],
['40', '统一视图', 'IT运维', '与平台级MDP监控互补,S3页面聚焦本模块任务实例', 'S3 MDP任务', '模块监控视图'],
],
rules: [
['1', '状态判定', '任务执行返回码非零判定为失败,零为成功'],
['2', '记录数展示', '展示最近一次成功执行记录数;如最近失败则展示失败前最后成功记录数'],
['3', '刷新频率', '页面不自动刷新,需手动刷新获取最新任务状态'],
['4', '数据来源', '任务执行日志从MDP任务调度引擎日志表读取'],
],
improvements: [
'从原系统无统一监控(依赖DBA手动检查数据库日志)升级为可视化监控页面。',
'新增S3模块专属任务视图,与平台级监控形成"总-分"监控体系。',
'新增错误信息直接展示,替代原系统需要连接数据库查询日志的低效方式。',
],
permissions: [
['1', 'IT运维人员', '查看权限'],
['2', '供应链经理/物料计划员', '查看权限(了解数据同步状态)'],
],
interfaces: [
['1', 'MDP日志接口', '从MDP任务调度引擎读取同步任务日志(sync_logs表)', '实时'],
['2', '核心数据表', 'mdp_sync_task_log(MDP同步任务日志表)', '实时'],
],
reports: [
['1', 'MDP任务运行日报', '每日汇总S3相关MDP任务成功率和平均耗时', '日报'],
['2', '任务失败趋势报表', '按周/月统计任务失败趋势,评估数据同步稳定性', '按周/月'],
],
};
const ch12 = () => buildChapter('12', 'MDP 运行监控', _ch12cfg);
// ═══════════════════════════════════════════════════
// Chapter 13: 数据中台架构
// ═══════════════════════════════════════════════════
function buildCh13() {
const ch = [];
ch.push(h1('13 数据中台架构'));
ch.push(h2('13.1 目标/宗旨'));
ch.push(p('S3供应协同模块采用Ai-DOP统一数据中台分层架构,将业务运行数据经过贴源(STG)、标准化(STD)、宽表构建(DWD)、指标计算(KPI)四层处理,最终服务于前端页面查询、看板展示和KPI考核。'));
ch.push(h2('13.2 分层设计'));
ch.push(table(
['分层', '表前缀', '职责', '更新机制'],
[
['贴源层(STG)', 'mdp_stg_*', '保留源系统原始数据', 'MDP同步覆盖写入'],
['标准层(STD)', 'mdp_std_*', '统一字段口径,清洗脏数据', 'MDP转换(最新批次)'],
['宽表层(DWD)', 'dwd_*', '面向页面和KPI主题事实表', 'MDP转换(最新批次)'],
['指标层(KPI)', 'ado_s9_kpi_value_*', '按天存储L1-L4指标值', 'MDP KPI计算'],
],
[1500, 2000, 4200, 2300]
));
ch.push(h2('13.3 S3核心数据流'));
ch.push(bp('物料需求/计划链路'));
ch.push(p('work_order_demand / inventory_snapshot / srm_in_transit → mdp_stg_demand → mdp_std_demand → dwd_demand_schedule → ado_s9_kpi_value_*'));
ch.push(bp('采购订单/交货链路'));
ch.push(p('PurOrdMaster / srm_polist_ds / vscm_jhjh → mdp_stg_po → mdp_std_po → dwd_po_delivery → ado_s9_kpi_value_*'));
ch.push(bp('齐套/看板链路'));
ch.push(p('WorkOrdDetailTotalKB / homeS3 → DWD直接消费 → 前端看板和KPI卡片 → ado_s9_kpi_value_*'));
ch.push(h2('13.4 对象映射总表'));
ch.push(table(
['业务对象', '运行表', '贴源层', '标准层/DWD', '消费端'],
[
['物料需求计划', 'ic_demandschedule', 'mdp_stg_demand', 'mdp_std_demand / dwd_demand_schedule', '需求页、交货计划'],
['交货计划', 'srm_polist_ds', 'mdp_stg_delivery', 'mdp_std_delivery / dwd_delivery_schedule', '交货页、异常记录'],
['要货令(PurOrd DO)', 'PurOrdMaster', 'mdp_stg_po', 'mdp_std_po', '要货令页'],
['采购订单', 'PurOrdMaster / vscm_jhjh', 'mdp_stg_po', 'mdp_std_po / dwd_po_delivery', '采购订单页、看板'],
['委外加工(PW)', 'PurOrdMaster', 'mdp_stg_po', 'mdp_std_po', '委外页'],
['工序外协', 'PurOrdMaster (PW+工单)', 'mdp_stg_po', 'mdp_std_po', '工序外协页'],
['工单物料齐套', 'WorkOrdDetailTotalKB', '—', 'DWD宽表直接消费', '齐套看板'],
['供应协同KPI', 'homeS3数据对象', '—', 'KPI计算直接消费', '供应看板'],
],
[1100, 2200, 1600, 2400, 2700]
));
ch.push(h2('13.5 MDP作业调度'));
ch.push(table(
['配置项', '内容'],
[
['作业编码', 'S3_MDP_SYNC_TRANSFORM'],
['批次格式', 'S3_MDP_FULL_yyyyMMddHHmmss'],
['手动刷新入口', '各页面刷新按钮 / 计划联动手动触发'],
['监控入口', 'mdp_transform_run_log / mdp_sync_log / MDP运行监控页'],
['执行方式', '定时调度 + 手动触发'],
],
[2200, 7800]
));
ch.push(h2('13.6 变化和改进点'));
ch.push(bullet('建立统一数据中台分层架构,S3业务数据从"各自为政"收敛到标准数据链路。'));
ch.push(bullet('页面和看板统一从DWD/KPI层消费,确保数据口径一致。'));
ch.push(bullet('MDP作业可观测,支持日志查询和异常追溯。'));
ch.push(bullet('新增手动刷新机制,业务人员可按需触发即时数据同步。'));
return ch;
}
// ═══════════════════════════════════════════════════
// Chapter 14: 权限管理汇总
// ═══════════════════════════════════════════════════
function buildCh14() {
const ch = [];
ch.push(h1('14 权限管理汇总'));
ch.push(p('以下汇总S3供应协同模块各功能所涉及的角色和权限:'));
ch.push(table(
['序号', '角色', '权限范围', '涉及模块'],
[
['1', '物料计划员', '查看和操作物料需求计划、交货计划;查看交货异常记录;发布/取消发布;刷新齐套看板', '物料需求计划、交货计划、异常记录、齐套看板'],
['2', '采购员', '增删改查要货令、采购申请、采购订单;查看交货计划和交货异常', '要货令、采购申请、采购订单'],
['3', '外协管理员', '增删改查委外加工订单和工序外协订单', '委外加工、工序外协'],
['4', '供应链经理', '查看所有模块;查看供应协同看板和管理KPI;导出报表;策略模拟', '全模块(查看+看板操作)'],
['5', '审批人(采购经理)', '审核采购申请的审批流', '物料采购申请'],
['6', 'IT运维人员', '查看MDP运行监控;监控同步任务状态', 'MDP运行监控'],
['7', '质量管理员', '查看交货异常记录(质量追溯)', '交货单异常记录'],
['8', '仓库管理员', '查看采购订单和交货计划(安排收货)', '采购订单、交货计划'],
['9', '生产计划员/车间主任', '查看工序外协订单和齐套看板', '工序外协、齐套看板'],
['10', '工厂厂长/总经理', '查看供应协同看板全部指标', '供应协同看板'],
],
[600, 1600, 5000, 2800]
));
return ch;
}
// ═══════════════════════════════════════════════════
// 文档构建主流程
// ═══════════════════════════════════════════════════
async function buildDocument() {
console.log('Generating flow chart images...');
flowImageCache['overview'] = await generateOverviewFlowPNG();
const allChapterConfigs = {
'2': _ch2cfg, '3': _ch3cfg, '4': _ch4cfg, '5': _ch5cfg,
'6': _ch6cfg, '7': _ch7cfg, '8': _ch8cfg, '9': _ch9cfg,
'10': _ch10cfg, '11': _ch11cfg, '12': _ch12cfg,
};
for (const [num, cfg] of Object.entries(allChapterConfigs)) {
if (cfg.flowSteps) {
flowImageCache[num] = await generateFlowPNG(cfg.flowSteps);
}
}
console.log('Flow chart images generated.');
const sections = [];
// ── 封面 ──
sections.push(empty(), empty(), empty());
sections.push(new Paragraph({
children: [new TextRun({ text: 'S3 供应协同模块', bold: true, size: 52, font: FONT, color: '1F4E79' })],
alignment: AlignmentType.CENTER, spacing: { after: 100 },
}));
sections.push(new Paragraph({
children: [new TextRun({ text: '蓝图设计方案', bold: true, size: 52, font: FONT, color: '1F4E79' })],
alignment: AlignmentType.CENTER, spacing: { after: 600 },
}));
sections.push(new Paragraph({
children: [new TextRun({ text: 'Ai-DOP 智慧运营决策平台', size: 28, font: FONT, color: '4472C4' })],
alignment: AlignmentType.CENTER, spacing: { after: 120 },
}));
sections.push(new Paragraph({
children: [new TextRun({ text: '版本:V1.0 日期:2026年5月27日 作者:AI Agent', size: 22, font: FONT, color: '808080' })],
alignment: AlignmentType.CENTER, spacing: { after: 2400 },
}));
sections.push(new Paragraph({
children: [new TextRun({ text: '【机密文档 · 仅限项目内部使用】', size: 21, font: FONT, color: 'C00000', italics: true })],
alignment: AlignmentType.CENTER,
}));
// ── 文档控制 ──
sections.push(pageBreak(), h1('文档控制'));
sections.push(h2('更改记录'));
sections.push(table(['日期', '姓名', '版本', '变更说明'],
[['2026/05/27', 'AI Agent', 'V1.0', '初版(基于S3模块系统实现)']],
[1800, 1200, 1000, 6000]));
sections.push(empty());
sections.push(h2('审核'));
sections.push(table(['姓名', '职位', '签字/日期'], [['', '', ''], ['', '', '']], [3000, 3000, 4000]));
sections.push(empty());
sections.push(h2('发布'));
sections.push(table(['编号', '名称', '地点'], [['', '', '']], [3000, 4000, 3000]));
// ── 目录 ──
sections.push(pageBreak(), h1('目录'));
sections.push(...buildTOC());
sections.push(pageBreak());
// ── 第1章: 总体业务方案 ──
sections.push(h1('1 总体业务方案'));
sections.push(h2('1.1 目标和宗旨'));
sections.push(bullet('S3供应协同模块是Ai-DOP平台的核心模块,聚焦物料供需平衡与供应商协同管理。'));
sections.push(bullet('承接S1产销协同模块的订单需求和S2制造协同模块的生产计划,通过物料需求计划(MRP)、采购管理和供应看板三大核心能力,实现从需求识别到交付闭环的全流程数字化管控。'));
sections.push(bullet('核心KPI:工单按需准时齐套率(S3-L1-A)、工单齐套周期(S3-L1-B)、物料库存周转天数(S3-L1-C)。'));
sections.push(h2('1.2 总体业务流程图'));
sections.push(p('S3供应协同模块覆盖从"物料需求计算"到"供应协同监控"的完整链路,下图展示了物料计划域、采购管理域和供应协同看板域三大功能域的整体关系:'));
sections.push(flowImageParagraph(flowImageCache['overview']));
sections.push(h2('1.3 方案设计'));
sections.push(p('S3模块采用"数据中台驱动 + 业务操作闭环"的架构模式,覆盖以下核心功能模块:'));
sections.push(bullet('物料需求计划:MDP同步+MRP净需求计算,支持发布管理和手动CRUD'));
sections.push(bullet('物料交货计划:交货执行跟踪、批量操作、差异自动标记'));
sections.push(bullet('交货单异常记录:只读查询视图,系统自动比对标记异常,支持多维筛选和导出'));
sections.push(bullet('要货令:采购流程起点,4状态生命周期管理'));
sections.push(bullet('物料采购申请:规范申请-审批流程,确保采购需求合规'));
sections.push(bullet('物料采购订单:订单全生命周期跟踪,交货关联和状态自动流转'));
sections.push(bullet('委外加工订单:PW类型专项管理,货源清单校验'));
sections.push(bullet('工序外协订单:工序级外协精细化管理,工单关联'));
sections.push(bullet('供应协同看板:4维KPI卡片+趋势箭头+分支看板+策略模拟'));
sections.push(bullet('工单物料齐套上线看板:30+字段齐套展示,供应商维度欠料分析'));
sections.push(bullet('MDP运行监控:S3模块专属同步任务可视化监控'));
sections.push(p('前端采用Vue 3 + Element Plus + TypeScript技术栈,列表页使用通用AidopDemoShell容器组件,看板页使用KPI卡片+趋势图表组合布局。后端基于Admin.NET框架分层架构实现。S3模块关键L1指标通过运营指标建模支持自定义口径配置。'));
// ── 第2~12章: 各功能模块 ──
sections.push(pageBreak()); sections.push(h1('2 物料需求计划')); sections.push(...ch2());
sections.push(pageBreak()); sections.push(h1('3 物料交货计划')); sections.push(...ch3());
sections.push(pageBreak()); sections.push(h1('4 交货单异常记录')); sections.push(...ch4());
sections.push(pageBreak()); sections.push(h1('5 要货令')); sections.push(...ch5());
sections.push(pageBreak()); sections.push(h1('6 物料采购申请')); sections.push(...ch6());
sections.push(pageBreak()); sections.push(h1('7 物料采购订单')); sections.push(...ch7());
sections.push(pageBreak()); sections.push(h1('8 委外加工订单')); sections.push(...ch8());
sections.push(pageBreak()); sections.push(h1('9 工序外协订单')); sections.push(...ch9());
sections.push(pageBreak()); sections.push(h1('10 供应协同看板')); sections.push(...ch10());
sections.push(pageBreak()); sections.push(h1('11 工单物料齐套上线看板')); sections.push(...ch11());
sections.push(pageBreak()); sections.push(h1('12 MDP 运行监控')); sections.push(...ch12());
// ── 第13~14章 ──
sections.push(pageBreak()); sections.push(...buildCh13());
sections.push(pageBreak()); sections.push(...buildCh14());
return sections;
}
// ═══════════════════════════════════════════════════
// 生成文档
// ═══════════════════════════════════════════════════
async function main() {
const doc = new Document({
styles: { default: { document: { run: { font: FONT, size: 21 } } } },
sections: [{
properties: { page: { margin: { top: convertInchesToTwip(0.8), bottom: convertInchesToTwip(0.8), left: convertInchesToTwip(1.0), right: convertInchesToTwip(1.0) } } },
children: await buildDocument(),
}],
});
const buffer = await Packer.toBuffer(doc);
const outPath = 'd:\\DEMONET\\doc\\S3供应协同模块蓝图设计方案.docx';
const fallbackPath = 'd:\\DEMONET\\doc\\S3供应协同模块蓝图设计方案_V2.docx';
const tempPath = 'd:\\DEMONET\\doc\\S3_blueprint_temp.docx';
fs.writeFileSync(tempPath, buffer);
try { fs.unlinkSync(outPath); } catch(e) {}
try { fs.renameSync(tempPath, outPath); console.log(`Renamed to: ${outPath}`); }
catch(e) {
try { fs.unlinkSync(fallbackPath); } catch(_) {}
try { fs.renameSync(tempPath, fallbackPath); console.log(`Fallback to: ${fallbackPath}`); }
catch(e2) { console.log(`Generated: ${tempPath} (target locked)`); }
}
console.log(`Size: ${(buffer.length / 1024).toFixed(1)} KB`);
}
main().catch(err => { console.error('Error:', err); process.exit(1); });