| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- const fs = require("fs");
- const path = require("path");
- const {
- Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
- Header, Footer, AlignmentType, HeadingLevel, BorderStyle, WidthType,
- ShadingType, PageNumber, PageBreak,
- } = require("docx");
- const OUTPUT = path.join(__dirname, "验收环境说明.docx");
- const A4_WIDTH = 11906;
- const A4_HEIGHT = 16838;
- const MARGIN = 1440;
- const CONTENT_WIDTH = A4_WIDTH - 2 * MARGIN;
- const border = { style: BorderStyle.SINGLE, size: 1, color: "999999" };
- const borders = { top: border, bottom: border, left: border, right: border };
- const cellMargins = { top: 60, bottom: 60, left: 100, right: 100 };
- function makeTable(rows, colWidths) {
- if (!colWidths) {
- const colCount = rows[0].length;
- const cw = Math.floor(CONTENT_WIDTH / colCount);
- colWidths = Array(colCount).fill(cw);
- colWidths[colCount - 1] = CONTENT_WIDTH - cw * (colCount - 1);
- }
- return new Table({
- width: { size: CONTENT_WIDTH, type: WidthType.DXA },
- columnWidths: colWidths,
- rows: rows.map((row, rowIdx) =>
- new TableRow({
- children: row.map((cell, colIdx) =>
- new TableCell({
- borders,
- width: { size: colWidths[colIdx], type: WidthType.DXA },
- margins: cellMargins,
- ...(rowIdx === 0 ? { shading: { fill: "D5E8F0", type: ShadingType.CLEAR } } : {}),
- children: [
- new Paragraph({
- children: [
- new TextRun({
- text: cell.replace(/\*\*/g, ""),
- font: "SimSun",
- size: 22,
- bold: rowIdx === 0,
- }),
- ],
- spacing: { line: 300 },
- }),
- ],
- })
- ),
- })
- ),
- });
- }
- const doc = new Document({
- styles: {
- default: { document: { run: { font: "SimSun", size: 24 } } },
- paragraphStyles: [
- {
- id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quickFormat: true,
- run: { size: 44, bold: true, font: "SimHei" },
- paragraph: { spacing: { before: 360, after: 240 }, outlineLevel: 0 },
- },
- {
- id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quickFormat: true,
- run: { size: 32, bold: true, font: "SimHei" },
- paragraph: { spacing: { before: 240, after: 160 }, outlineLevel: 1 },
- },
- ],
- },
- sections: [
- {
- properties: {
- page: {
- size: { width: A4_WIDTH, height: A4_HEIGHT },
- margin: { top: MARGIN, right: MARGIN, bottom: MARGIN, left: MARGIN },
- },
- },
- headers: {
- default: new Header({
- children: [
- new Paragraph({
- children: [new TextRun({ text: "陇耘鲜达系统验收环境说明", font: "SimSun", size: 18, color: "888888" })],
- alignment: AlignmentType.CENTER,
- }),
- ],
- }),
- },
- footers: {
- default: new Footer({
- children: [
- new Paragraph({
- children: [
- new TextRun({ text: "第 ", font: "SimSun", size: 18, color: "888888" }),
- new TextRun({ children: [PageNumber.CURRENT], font: "SimSun", size: 18, color: "888888" }),
- new TextRun({ text: " 页", font: "SimSun", size: 18, color: "888888" }),
- ],
- alignment: AlignmentType.CENTER,
- }),
- ],
- }),
- },
- children: [
- new Paragraph({
- children: [new TextRun({ text: "陇耘鲜达系统验收环境说明", font: "SimHei", size: 44, bold: true })],
- alignment: AlignmentType.CENTER,
- spacing: { after: 360 },
- }),
- makeTable([
- ["项目", "内容"],
- ["文档名称", "陇耘鲜达系统验收环境说明"],
- ["版本", "v1.0"],
- ["日期", "2026-05-07"],
- ["关联文档", "陇耘鲜达系统操作手册 v1.0"],
- ]),
- new Paragraph({ children: [new PageBreak()] }),
- new Paragraph({
- heading: HeadingLevel.HEADING_2,
- children: [new TextRun({ text: "系统访问信息", font: "SimHei", size: 32, bold: true })],
- spacing: { before: 240, after: 160 },
- }),
- makeTable([
- ["项目", "地址"],
- ["Web 运营端", "[待填写]"],
- ["小程序 H5 预览", "[待填写]"],
- ["后端 API", "[待填写]"],
- ]),
- new Paragraph({ children: [new PageBreak()] }),
- new Paragraph({
- heading: HeadingLevel.HEADING_2,
- children: [new TextRun({ text: "演示账号", font: "SimHei", size: 32, bold: true })],
- spacing: { before: 240, after: 160 },
- }),
- makeTable([
- ["角色", "用户名", "密码", "说明"],
- ["Web 超级管理员", "[待填写]", "[待填写]", "验证运营端全部菜单与功能"],
- ["客户端账号", "[待填写]", "[待填写]", "验证小程序客户端下单、支付等功能"],
- ["供应商端账号", "[待填写]", "[待填写]", "验证小程序供应商端商品管理、接单等功能"],
- ["配送员端账号", "[待填写]", "[待填写]", "验证小程序配送员端接单、配送等功能"],
- ]),
- new Paragraph({ children: [new PageBreak()] }),
- new Paragraph({
- heading: HeadingLevel.HEADING_2,
- children: [new TextRun({ text: "客户端环境要求", font: "SimHei", size: 32, bold: true })],
- spacing: { before: 240, after: 160 },
- }),
- makeTable([
- ["项目", "要求"],
- ["浏览器", "Chrome 90+ 或其他现代浏览器"],
- ["小程序", "微信 7.0+ 或 H5 浏览器预览"],
- ["Web 分辨率", "1920×1080"],
- ["小程序模拟", "iPhone 尺寸"],
- ]),
- new Paragraph({ children: [new PageBreak()] }),
- new Paragraph({
- heading: HeadingLevel.HEADING_2,
- children: [new TextRun({ text: "数据说明", font: "SimHei", size: 32, bold: true })],
- spacing: { before: 240, after: 160 },
- }),
- new Paragraph({
- children: [
- new TextRun({ text: "演示数据范围:", font: "SimSun", size: 24, bold: true }),
- new TextRun({ text: "系统已预置测试区域、测试商品、测试订单等数据,覆盖操作手册所述主要业务场景。", font: "SimSun", size: 24 }),
- ],
- spacing: { line: 360 },
- }),
- new Paragraph({
- children: [
- new TextRun({ text: "截图来源:", font: "SimSun", size: 24, bold: true }),
- new TextRun({ text: "操作手册中的截图均取自 H5 本地预览环境,实际小程序界面以微信端为准。", font: "SimSun", size: 24 }),
- ],
- spacing: { line: 360 },
- }),
- new Paragraph({ children: [new PageBreak()] }),
- new Paragraph({
- heading: HeadingLevel.HEADING_2,
- children: [new TextRun({ text: "保密说明", font: "SimHei", size: 32, bold: true })],
- spacing: { before: 240, after: 160 },
- }),
- new Paragraph({
- children: [new TextRun({ text: "本文档包含系统访问地址与演示账号信息,仅供项目验收期间使用。验收完成后,相关账号应及时回收或销毁,本文档不再分发。", font: "SimSun", size: 24 })],
- spacing: { line: 360 },
- }),
- ],
- },
- ],
- });
- Packer.toBuffer(doc).then(buffer => {
- fs.writeFileSync(OUTPUT, buffer);
- console.log(`✅ Environment spec saved to: ${OUTPUT}`);
- console.log(` Size: ${(buffer.length / 1024).toFixed(1)} KB`);
- });
|