generate_s4_req_docx.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /**
  2. * Generate S4 采购执行业务需求描述.docx
  3. * 严格按照 S1 产销协同业务需求描述.docx 的格式:
  4. * 标题 → 文档信息 → 目录 → (一)模块功能说明+业务描述 → ...
  5. */
  6. const fs = require('fs');
  7. const {
  8. Document, Packer, Paragraph, TextRun, HeadingLevel,
  9. AlignmentType, PageBreak, TableOfContents, convertInchesToTwip,
  10. } = require('docx');
  11. const FONT = '微软雅黑';
  12. // ── 辅助函数 ──
  13. function empty() { return new Paragraph({ spacing: { after: 80 }, children: [] }); }
  14. function pageBreak() { return new Paragraph({ children: [new PageBreak()] }); }
  15. function normalPara(text, opts = {}) {
  16. return new Paragraph({
  17. children: [new TextRun({ text, size: 21, font: FONT, ...opts })],
  18. spacing: { after: 100, line: 360 },
  19. indent: opts.indent ? { left: convertInchesToTwip(opts.indent) } : undefined,
  20. });
  21. }
  22. // H2: (一) 供应商交货管理
  23. function sectionHeading(text) {
  24. return new Paragraph({
  25. children: [new TextRun({ text, bold: true, size: 28, font: FONT })],
  26. heading: HeadingLevel.HEADING_2,
  27. spacing: { before: 400, after: 200 },
  28. });
  29. }
  30. // H3: 功能说明 / 业务描述
  31. function subHeading(text) {
  32. return new Paragraph({
  33. children: [new TextRun({ text, bold: true, size: 22, font: FONT })],
  34. heading: HeadingLevel.HEADING_3,
  35. spacing: { before: 200, after: 100 },
  36. });
  37. }
  38. // Title paragraph
  39. function titlePara(text) {
  40. return new Paragraph({
  41. children: [new TextRun({ text, bold: true, size: 36, font: FONT, color: '1F4E79' })],
  42. alignment: AlignmentType.CENTER,
  43. spacing: { after: 300 },
  44. });
  45. }
  46. function docInfoPara(text) {
  47. return new Paragraph({
  48. children: [new TextRun({ text, size: 21, font: FONT })],
  49. spacing: { after: 40 },
  50. bullet: { level: 0 },
  51. });
  52. }
  53. // ═══════════════════════════════════════════════════
  54. // 各模块业务需求描述数据
  55. // ═══════════════════════════════════════════════════
  56. const CN_NUM = ['', '一', '二', '三', '四', '五', '六', '七', '八'];
  57. const modules = [
  58. {
  59. title: '供应商交货管理',
  60. funcDesc: [
  61. '供应商交货管理模块管理采购订单下达后的供应商交货执行过程,通过交货计划发布驱动供应商交期回复和发货单生成。',
  62. '采购跟单员可从MDP同步的交货计划中勾选发布至供应商,要求所选记录属于同一供应商,支持"按计划日期回复"(批量)和"回复交期"(手动)两种交期回复方式。',
  63. '支持基于交货记录在弹窗中嵌入发货单表单,一键生成发货单,实现"发布→回复→发货单"全流程在单个页面内完成。',
  64. '全链路状态跟踪覆盖在途、在检、入库各阶段,支持多维度筛选、排序和列设置(20个字段自定义显示)。',
  65. ],
  66. bizDesc: [
  67. '采购跟单员登录DOP系统,进入"S4采购执行→供应商交货管理"菜单,查看交货计划列表。',
  68. '从MDP同步的交货计划中勾选目标记录(须属同一供应商),点击"发布"按钮将交货计划发布至供应商。',
  69. '供应商收到交货计划后进行交期回复:采购跟单员可选择"按计划日期回复"进行批量快速回复,或选择"回复交期"手动指定单个日期。',
  70. '交期回复完成后,采购跟单员勾选已回复的交货记录,点击"生成发货单",在嵌入式弹窗中填写发货单信息并确认生成。',
  71. '系统自动同步在途/在检/入库状态,采购跟单员可在列表中实时跟踪每条交货记录的当前状态。',
  72. '列表支持按供应商、物料、日期范围等多条件筛选,支持CSV导出;交货数据通过MDP同步至SRM系统供供应商查看。',
  73. ],
  74. },
  75. {
  76. title: '供应商发货单',
  77. funcDesc: [
  78. '供应商发货单模块管理从交货管理生成的发货单,覆盖从发货单生成到供应商发货、入库关联的全链路操作。',
  79. '发货单仅由交货管理的"生成发货单"操作产生,不支持手动独立创建,确保数据来源的一致性和可追溯性。',
  80. '支持标签生成和打印功能,基于发货单信息自动生成物流标签(含物料编码、数量、供应商等关键信息),打印后粘贴于货物外包装用于物流识别。',
  81. '发货单数据通过SupplierShipment表与ERP/SRM双向同步,入库数据自动关联发货单并更新状态。',
  82. ],
  83. bizDesc: [
  84. '采购跟单员在交货管理页面勾选交货记录后一键生成发货单,发货单自动进入供应商发货单列表。',
  85. '采购跟单员进入"S4采购执行→供应商发货单"菜单,查看发货单列表,支持按供应商、物料、日期等条件筛选。',
  86. '基于发货单信息点击"生成标签"按钮,系统自动生成包含物料编码、数量、供应商等关键信息的物流标签。',
  87. '上传发货单相关附件(签收单、运输单、质检报告等),支持多格式附件上传。',
  88. '打印物流标签粘贴于货物外包装,供应商按发货单要求进行实物发货。',
  89. '采购跟单员打印正式发货单据作为运输和收货凭证;收货数据入库后系统自动关联发货单并更新状态。',
  90. ],
  91. },
  92. {
  93. title: '采购退货单',
  94. funcDesc: [
  95. '采购退货单模块处理来料检验不合格后的退货流程,管理退货单据的创建、出库和状态跟踪。',
  96. '退货单必须关联原始采购订单和不合格IQC检验记录,确保退货流程的可追溯性。',
  97. '退货单状态生命周期管理:新建→已出库→已完成,顺序流转不可跳转,已出库的退货单不可删除。',
  98. '退货出库时自动校验库存数量充足,出库后自动扣减库存并同步至ERP系统。',
  99. ],
  100. bizDesc: [
  101. '质量管理员在IQC来料检验中判定不合格,触发退货流程。',
  102. '质量管理员进入"S4采购执行→采购退货单"菜单,点击"新建退货单",基于不合格判定创建退货单,系统自动关联原始采购订单和检验记录。',
  103. '退货单创建后状态为"新建",质量管理员填写退货原因、退货数量等信息后保存。',
  104. '仓库管理员在退货单列表中执行"退货出库"操作,系统校验库存数量充足后执行出库,自动扣减库存数据,退货单状态更新为"已出库"。',
  105. '退货处理完成后,退货单状态自动更新为"已完成";退货数据可关联至供应商绩效评估。',
  106. '采购经理可在列表中查看所有退货单记录,支持按供应商、物料、退货原因、日期范围等条件筛选。',
  107. ],
  108. },
  109. {
  110. title: 'IQC退货查询',
  111. funcDesc: [
  112. 'IQC退货查询模块提供只读的退货历史查询功能,面向质量管理人员查看IQC检验不合格后的退货处理记录。',
  113. '展示退货详情,包括检验结果、不合格原因、处理方式等完整信息,支持按检验单号、物料编码、日期范围检索。',
  114. '该页面为只读查询视图,不支持增删改操作,确保质量记录的完整性和不可篡改性。',
  115. '每条退货记录可关联到原始IQC检验单和采购订单,实现完整的质量追溯链路。',
  116. ],
  117. bizDesc: [
  118. '质量管理员进入"S4采购执行→IQC退货查询"菜单,查看IQC退货查询列表。',
  119. '通过检验单号、物料编码、日期范围等条件筛选查询退货记录。',
  120. '在列表中查看每条退货记录的详情:IQC检验结果、不合格原因、退货处理方式、退货数量等。',
  121. '退货记录自动关联原始采购订单和供应商信息,支持供应商质量评级分析。',
  122. '采购经理和仓库管理员可查看退货查询记录,了解退货处理进度和结果。',
  123. ],
  124. },
  125. {
  126. title: '采购执行看板主页',
  127. funcDesc: [
  128. '采购执行看板主页通过可视化看板展示S4采购执行四大L1核心指标:物料交货周期(S4-L1-A)、物料交货满足率(S4-L1-B)、物料采购人效(S4-L1-C)、采购在途周转(S4-L1-D)。',
  129. '采用"双面板"设计——左侧"物料采购执行"按单品项展示KPI明细,右侧"供应商交付绩效"按供应商维度展示交付表现。',
  130. '每个指标配有达成等级标签(优秀/良好/关注/预警),直观反映绩效水平,帮助管理层快速识别问题。',
  131. '支持按日期、产品、订单号、产线、供应商、采购单号、物料等多维度筛选,左右面板联动更新;支持导出报告和运营指标建模。',
  132. ],
  133. bizDesc: [
  134. '采购经理登录DOP系统,进入"S4采购执行→采购执行看板主页"菜单,系统自动加载四大L1核心KPI指标卡片。',
  135. '左侧"物料采购执行"面板按单品项展示KPI明细,包含指标名称、计算公式和达成等级标签。',
  136. '右侧"供应商交付绩效"面板按供应商维度展示交付表现,帮助识别优质和问题供应商。',
  137. '通过日期、产品、订单号、产线、供应商等筛选条件进行多维分析,左面板筛选条件变更时右面板数据同步更新。',
  138. '点击"导出报告"按钮将看板当前筛选条件下的分析结果导出为报告文件。',
  139. 'KPI数据通过MDP作业S4_MDP_SYNC_TRANSFORM定时或手动刷新,指标定义存储在ado_smart_ops_kpi_master,计算结果存储在ado_s9_kpi_value_l1~l4_day。',
  140. ],
  141. },
  142. {
  143. title: '供应商欠料看板',
  144. funcDesc: [
  145. '供应商欠料看板提供未来15天(含当日D0)的供应商欠料滚动预测视图,帮助采购团队提前识别和应对缺料风险。',
  146. '基于WorkOrdDetailTotalKB宽表通过MRP计算工单物料齐套情况,预测未来D0~D14共15天各周期的供应缺口。',
  147. '15天日期列自动计算生成,日期变化时列自动滚动更新;右侧展示每日欠料数量,直观反映缺料趋势。',
  148. '支持手动刷新执行实时缺料计算,页面不自动刷新;支持按供应商维度筛选,快速定位责任供应商。',
  149. ],
  150. bizDesc: [
  151. '采购跟单员进入"S4采购执行→供应商欠料看板"菜单,系统从WorkOrdDetailTotalKB宽表加载工单需求/BOM/库存/在途数据。',
  152. '系统自动计算D0(今日)~D14共15天的滚动欠料预测,15天日期列自动生成显示。',
  153. '在看板列表中查看各物料在未来15天内的每日欠料数量,重点关注欠料严重的物料和供应商。',
  154. '通过供应商维度筛选,快速定位责任供应商的欠料情况;支持自定义显示/隐藏15天日期列及基础信息列。',
  155. '点击"刷新"按钮执行实时欠料计算,获取最新的工单需求、库存和在途数据后重新计算欠料预测。',
  156. '采购经理可查看和导出欠料预测日报,按供应商统计历史欠料趋势,为供应商管理决策提供数据支持。',
  157. ],
  158. },
  159. {
  160. title: '数据中台架构',
  161. funcDesc: [
  162. 'S4采购执行模块的数据基础依赖于MDP数据中台,采用统一分层架构(STG→STD→DWD→KPI),负责从ERP、SRM和IQC等外部系统抽取、清洗和转换采购订单、交货计划、收货数据和检验记录。',
  163. '贴源层(STG/mdp_stg_*)保留源系统原始数据;标准层(STD/mdp_std_*)统一字段口径并清洗脏数据;宽表层(DWD/dwd_*)构建面向页面和KPI的主题事实表;指标层(KPI/ado_s9_kpi_value_*)按天存储L1-L4指标值。',
  164. 'MDP作业(S4_MDP_SYNC_TRANSFORM)负责全链路同步转换,支持Cron定时调度和手动触发,作业日志可观测、异常可追溯。',
  165. '核心数据表包括:srm_polist_ds(采购订单交付计划)、SupplierShipment(发货单)、PurchaseReturnOrder(退货单)、IQCReturnQuery(退货查询视图)、WorkOrdDetailTotalKB(欠料宽表)。',
  166. ],
  167. bizDesc: [
  168. 'S4模块的业务数据(交货计划、发货单、退货单、IQC检验记录等)通过MDP作业自动同步至数据中台各层。',
  169. '交货管理链路:ERP采购订单→mdp_stg_po贴源→mdp_std_po标准→srm_polist_ds/SupplierShipment宽表→交货页面。',
  170. '退货管理链路:IQC检验结果→mdp_stg_iqc贴源→mdp_std_iqc标准→PurchaseReturnOrder/IQCReturnQuery宽表→退货页面。',
  171. '看板/KPI链路:srm_polist_ds/ReceivingData/WorkOrdDetailTotalKB→DWD关联计算→ado_s9_kpi_value_*指标层→看板消费。',
  172. '页面查询统一消费DWD/KPI层数据,避免直接访问运行时表,确保数据口径一致和查询性能优化。',
  173. ],
  174. },
  175. {
  176. title: '权限管理汇总',
  177. funcDesc: [
  178. 'S4采购执行模块涉及以下核心角色和权限:',
  179. '采购跟单员:增删改查交货管理、发货单;发布/交期回复/生成发货单/关闭/导出;查看欠料看板。',
  180. '采购经理:查看所有模块;查看采购执行看板和管理KPI;导出报告;指标建模。',
  181. '质量管理员:增删改查采购退货单;查看IQC退货查询全部记录。',
  182. '仓库管理员:查看交货管理、发货单、退货单;执行退货出库操作。',
  183. '物料计划员:查看供应商欠料看板(了解缺料预测)。',
  184. '供应链经理:查看采购执行看板和供应商欠料看板。',
  185. 'IT运维人员:查看MDP运行监控;监控同步任务状态。',
  186. '工厂厂长/总经理:查看采购执行看板全部指标。',
  187. ],
  188. },
  189. ];
  190. // ═══════════════════════════════════════════════════
  191. // 生成文档
  192. // ═══════════════════════════════════════════════════
  193. function buildDocument() {
  194. const sections = [];
  195. // ── 封面/标题 ──
  196. sections.push(empty(), empty(), empty(), empty());
  197. sections.push(titlePara('采购执行业务需求描述'));
  198. sections.push(empty());
  199. // ── 文档信息 ──
  200. const infoItems = [
  201. '文档作者:彭熙玉',
  202. '创建日期:2026-06-08',
  203. '更新日期:2026-06-08',
  204. '文档编号:DOP-S4-REQ-001',
  205. '当前版本:V1.0',
  206. ];
  207. infoItems.forEach(item => sections.push(docInfoPara(item)));
  208. sections.push(empty(), empty());
  209. // ── 目录 ──
  210. sections.push(pageBreak());
  211. sections.push(new Paragraph({
  212. children: [new TextRun({ text: '目录', bold: true, size: 28, font: FONT })],
  213. heading: HeadingLevel.HEADING_2,
  214. spacing: { before: 200, after: 300 },
  215. }));
  216. sections.push(new TableOfContents('目录', {
  217. headingStyleRange: '2-3',
  218. hyperlink: true,
  219. }));
  220. sections.push(new Paragraph({
  221. children: [new TextRun({ text: '(如目录未显示,请在 Word 中右键此处 → 更新域)', size: 18, font: FONT, italics: true, color: '888888' })],
  222. spacing: { before: 40, after: 200 },
  223. }));
  224. // ── 各功能模块 ──
  225. for (let i = 0; i < modules.length; i++) {
  226. const mod = modules[i];
  227. sections.push(pageBreak());
  228. // 章节标题:(一) 供应商交货管理
  229. sections.push(sectionHeading(`(${CN_NUM[i + 1]})${mod.title}`));
  230. // 功能说明
  231. sections.push(subHeading('功能说明'));
  232. (mod.funcDesc || []).forEach(desc => sections.push(normalPara(desc)));
  233. // 业务描述
  234. if (mod.bizDesc && mod.bizDesc.length) {
  235. sections.push(subHeading('业务描述'));
  236. mod.bizDesc.forEach(desc => sections.push(normalPara(desc)));
  237. }
  238. }
  239. return sections;
  240. }
  241. // ═══════════════════════════════════════════════════
  242. // 主流程
  243. // ═══════════════════════════════════════════════════
  244. async function main() {
  245. const sections = buildDocument();
  246. const doc = new Document({
  247. styles: { default: { document: { run: { font: FONT, size: 21 } } } },
  248. sections: [{
  249. properties: { page: { margin: { top: convertInchesToTwip(0.8), bottom: convertInchesToTwip(0.8), left: convertInchesToTwip(1.2), right: convertInchesToTwip(1.2) } } },
  250. children: sections,
  251. }],
  252. });
  253. const buffer = await Packer.toBuffer(doc);
  254. const outPath = 'd:\\DEMONET\\doc\\S4采购执行业务需求描述.docx';
  255. const tempPath = 'd:\\DEMONET\\doc\\s4_req_temp.docx';
  256. fs.writeFileSync(tempPath, buffer);
  257. try { fs.unlinkSync(outPath); } catch(e) {}
  258. try { fs.renameSync(tempPath, outPath); console.log(`Renamed to: ${outPath}`); }
  259. catch(e) { console.log(`Generated: ${tempPath}`); }
  260. console.log(`Size: ${(buffer.length / 1024).toFixed(1)} KB`);
  261. }
  262. main().catch(err => { console.error('Error:', err); process.exit(1); });