const fs = require('fs'); const path = require('path'); const { Document, Packer, Paragraph, TextRun, ImageRun, HeadingLevel, AlignmentType, LevelFormat, PageBreak, PageNumber, Header, Footer, Table, TableRow, TableCell, WidthType, BorderStyle, ShadingType, VerticalAlign, } = require('docx'); const SCREENSHOT_DIR = path.join(__dirname, '.workbuddy', 'screenshots'); function getPngDimensions(filePath) { const buf = fs.readFileSync(filePath); const width = buf.readUInt32BE(16); const height = buf.readUInt32BE(20); return { width, height }; } function createImage(screenshotName, maxWidth = 480) { const filePath = path.join(SCREENSHOT_DIR, screenshotName); if (!fs.existsSync(filePath)) return null; const { width, height } = getPngDimensions(filePath); const ratio = height / width; const w = Math.min(maxWidth, width); const h = Math.round(w * ratio); return new Paragraph({ alignment: AlignmentType.CENTER, spacing: { before: 120, after: 80 }, children: [new ImageRun({ type: 'png', data: fs.readFileSync(filePath), transformation: { width: w, height: h }, altText: { title: screenshotName, description: screenshotName, name: screenshotName }, })], }); } function h1(text) { return new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun({ text, bold: true })] }); } function h2(text) { return new Paragraph({ heading: HeadingLevel.HEADING_2, children: [new TextRun({ text, bold: true })] }); } function h3(text) { return new Paragraph({ heading: HeadingLevel.HEADING_3, children: [new TextRun({ text, bold: true })] }); } function p(text) { return new Paragraph({ spacing: { after: 120, line: 360 }, children: [new TextRun({ text, size: 22 })] }); } function bullet(text) { return new Paragraph({ numbering: { reference: 'bullets', level: 0 }, spacing: { after: 60, line: 360 }, children: [new TextRun({ text, size: 22 })], }); } function caption(text) { return new Paragraph({ alignment: AlignmentType.CENTER, spacing: { after: 200 }, children: [new TextRun({ text, italics: true, size: 18, color: '888888' })], }); } function callout(label, text) { const border = { style: BorderStyle.SINGLE, size: 1, color: '0969DA' }; return new Table({ width: { size: 100, type: WidthType.PERCENTAGE }, columnWidths: [9026], rows: [new TableRow({ cantSplit: true, children: [new TableCell({ borders: { top: border, bottom: border, left: border, right: border }, width: { size: 9026, type: WidthType.DXA }, shading: { fill: 'EAF2FC', type: ShadingType.CLEAR }, margins: { top: 120, bottom: 120, left: 200, right: 200 }, children: [ new Paragraph({ spacing: { after: 40 }, children: [new TextRun({ text: label, bold: true, size: 22, color: '0969DA' })] }), new Paragraph({ children: [new TextRun({ text, size: 22 })] }), ], })], })], }); } // 数据统计卡片 function statCard(label, value, color) { const border = { style: BorderStyle.SINGLE, size: 4, color: color || '0969DA' }; return new TableCell({ borders: { top: border, bottom: border, left: border, right: border }, width: { size: 2256, type: WidthType.DXA }, shading: { fill: 'F5F8FC', type: ShadingType.CLEAR }, margins: { top: 200, bottom: 200, left: 120, right: 120 }, verticalAlign: VerticalAlign.CENTER, children: [ new Paragraph({ alignment: AlignmentType.CENTER, spacing: { after: 60 }, children: [new TextRun({ text: value, bold: true, size: 40, color: color || '0969DA' })] }), new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: label, size: 18, color: '6B7785' })] }), ], }); } const cjkFont = 'Microsoft YaHei'; const asciiFont = 'Arial'; const fontConfig = { ascii: asciiFont, hAnsi: asciiFont, eastAsia: cjkFont }; const doc = new Document({ styles: { default: { document: { run: { font: fontConfig, size: 22 } } }, paragraphStyles: [ { id: 'Heading1', name: 'Heading 1', basedOn: 'Normal', next: 'Normal', quickFormat: true, run: { size: 32, bold: true, color: '0969DA', font: fontConfig }, paragraph: { spacing: { before: 360, after: 200 }, outlineLevel: 0 } }, { id: 'Heading2', name: 'Heading 2', basedOn: 'Normal', next: 'Normal', quickFormat: true, run: { size: 28, bold: true, color: '1B232E', font: fontConfig }, paragraph: { spacing: { before: 280, after: 160 }, outlineLevel: 1 } }, { id: 'Heading3', name: 'Heading 3', basedOn: 'Normal', next: 'Normal', quickFormat: true, run: { size: 24, bold: true, color: '3D4D5C', font: fontConfig }, paragraph: { spacing: { before: 200, after: 120 }, outlineLevel: 2 } }, ], }, numbering: { config: [ { reference: 'bullets', levels: [{ level: 0, format: LevelFormat.BULLET, text: '\u2022', alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] }, { reference: 'bullets2', levels: [{ level: 0, format: LevelFormat.BULLET, text: '\u25E6', alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 1080, hanging: 360 } } } }] }, ], }, sections: [{ properties: { page: { size: { width: 11906, height: 16838 }, margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 }, }, }, headers: { default: new Header({ children: [new Paragraph({ alignment: AlignmentType.RIGHT, children: [new TextRun({ text: '智慧运维系统 · 月度工作总结报告', size: 16, color: '999999', font: fontConfig })], })], }), }, footers: { default: new Footer({ children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [ new TextRun({ text: '第 ', size: 16, color: '999999', font: fontConfig }), new TextRun({ children: [PageNumber.CURRENT], size: 16, color: '999999' }), new TextRun({ text: ' 页', size: 16, color: '999999', font: fontConfig }), ], })], }), }, children: [ // === 封面 === new Paragraph({ spacing: { before: 2400 } }), new Paragraph({ alignment: AlignmentType.CENTER, spacing: { after: 240 }, children: [new TextRun({ text: '智慧运维系统平台', size: 56, bold: true, color: '0969DA', font: fontConfig })] }), new Paragraph({ alignment: AlignmentType.CENTER, spacing: { after: 320 }, children: [new TextRun({ text: '月度工作总结报告', size: 44, bold: true, color: '3D4D5C', font: fontConfig })] }), new Paragraph({ alignment: AlignmentType.CENTER, spacing: { after: 200 }, children: [new TextRun({ text: '( 2026年8月 )', size: 28, color: '6B7785', font: fontConfig })] }), new Paragraph({ spacing: { before: 1600 } }), // 信息表 new Table({ width: { size: 60, type: WidthType.PERCENTAGE }, alignment: AlignmentType.CENTER, columnWidths: [2250, 4050], rows: [ new TableRow({ children: [ new TableCell({ borders: { top: { style: BorderStyle.NONE }, bottom: { style: BorderStyle.SINGLE, size: 4, color: 'D6DEE8' }, left: { style: BorderStyle.NONE }, right: { style: BorderStyle.NONE } }, shading: { fill: 'F5F8FC', type: ShadingType.CLEAR }, margins: { top: 120, bottom: 120, left: 200, right: 200 }, children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: '汇 报 人', bold: true, size: 24, color: '3D4D5C', font: fontConfig })] })], }), new TableCell({ borders: { top: { style: BorderStyle.NONE }, bottom: { style: BorderStyle.SINGLE, size: 4, color: 'D6DEE8' }, left: { style: BorderStyle.NONE }, right: { style: BorderStyle.NONE } }, margins: { top: 120, bottom: 120, left: 200, right: 200 }, children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: '葌 昀', size: 24, color: '1B232E', font: fontConfig })] })], }), ], }), new TableRow({ children: [ new TableCell({ borders: { top: { style: BorderStyle.NONE }, bottom: { style: BorderStyle.SINGLE, size: 4, color: 'D6DEE8' }, left: { style: BorderStyle.NONE }, right: { style: BorderStyle.NONE } }, shading: { fill: 'F5F8FC', type: ShadingType.CLEAR }, margins: { top: 120, bottom: 120, left: 200, right: 200 }, children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: '汇报周期', bold: true, size: 24, color: '3D4D5C', font: fontConfig })] })], }), new TableCell({ borders: { top: { style: BorderStyle.NONE }, bottom: { style: BorderStyle.SINGLE, size: 4, color: 'D6DEE8' }, left: { style: BorderStyle.NONE }, right: { style: BorderStyle.NONE } }, margins: { top: 120, bottom: 120, left: 200, right: 200 }, children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: '2026年8月1日 — 2026年8月31日', size: 24, color: '1B232E', font: fontConfig })] })], }), ], }), new TableRow({ children: [ new TableCell({ borders: { top: { style: BorderStyle.NONE }, bottom: { style: BorderStyle.SINGLE, size: 4, color: 'D6DEE8' }, left: { style: BorderStyle.NONE }, right: { style: BorderStyle.NONE } }, shading: { fill: 'F5F8FC', type: ShadingType.CLEAR }, margins: { top: 120, bottom: 120, left: 200, right: 200 }, children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: '所属项目', bold: true, size: 24, color: '3D4D5C', font: fontConfig })] })], }), new TableCell({ borders: { top: { style: BorderStyle.NONE }, bottom: { style: BorderStyle.SINGLE, size: 4, color: 'D6DEE8' }, left: { style: BorderStyle.NONE }, right: { style: BorderStyle.NONE } }, margins: { top: 120, bottom: 120, left: 200, right: 200 }, children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: '机器人智慧服务系统', size: 24, color: '1B232E', font: fontConfig })] })], }), ], }), new TableRow({ children: [ new TableCell({ borders: { top: { style: BorderStyle.NONE }, bottom: { style: BorderStyle.SINGLE, size: 4, color: 'D6DEE8' }, left: { style: BorderStyle.NONE }, right: { style: BorderStyle.NONE } }, shading: { fill: 'F5F8FC', type: ShadingType.CLEAR }, margins: { top: 120, bottom: 120, left: 200, right: 200 }, children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: '提交日期', bold: true, size: 24, color: '3D4D5C', font: fontConfig })] })], }), new TableCell({ borders: { top: { style: BorderStyle.NONE }, bottom: { style: BorderStyle.SINGLE, size: 4, color: 'D6DEE8' }, left: { style: BorderStyle.NONE }, right: { style: BorderStyle.NONE } }, margins: { top: 120, bottom: 120, left: 200, right: 200 }, children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: '2026年9月1日', size: 24, color: '1B232E', font: fontConfig })] })], }), ], }), ], }), new Paragraph({ spacing: { before: 1600 } }), new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: '二〇二六年九月', size: 22, color: '999999', font: fontConfig })] }), new Paragraph({ children: [new PageBreak()] }), // === 目录 === h1('目 录'), p('本文档为智慧运维系统平台 2026 年 8 月份工作总结月报,汇总当月在 WebSocket 通信机制优化、控制权限重构、路径规划联调、路由架构升级、设备参数开发、国际化适配、AI 模型升级、APP 端指导测试、软著申报等方面的核心工作成果,并附系统功能截图。'), new Paragraph({ spacing: { after: 200 } }), // 目录列表 (() => { function tocItem(num, title) { return new Paragraph({ spacing: { after: 120, line: 360 }, indent: { left: 200 }, children: [ new TextRun({ text: num + ' ', bold: true, size: 24, color: '0969DA', font: fontConfig }), new TextRun({ text: title, size: 24, color: '1B232E', font: fontConfig }), ], }); } return [ tocItem('第一章', '本月工作总览'), tocItem('第二章', '智慧运维平台底层机制优化'), tocItem('第三章', '苏州算法联调与路径规划'), tocItem('第四章', '控制权限体系重构与闭环'), tocItem('第五章', '路由架构升级与组件迭代'), tocItem('第六章', '设备参数与定时任务功能'), tocItem('第七章', '视频与日志管理模块'), tocItem('第八章', '国际化适配与 AI 大模型升级'), tocItem('第九章', '基础功能模块完善'), tocItem('第十章', 'APP 端优化指导与测试'), tocItem('第十一章', '全业务链路闭环测试'), tocItem('第十二章', '软著申报与文档沉淀'), tocItem('第十三章', 'Git 提交记录统计'), tocItem('第十四章', '本月小结与下月计划'), ]; })().reduce((acc, cur) => acc.concat([cur]), []), new Paragraph({ children: [new PageBreak()] }), // === 第一章 本月工作总览 === h1('第一章 本月工作总览'), p('2026 年 8 月,围绕智慧运维系统平台稳定性、控制安全性、业务完整性与移动端联调适配四大方向开展系统性工作,持续推进苏州算法团队的路径规划联调,完成 WebSocket 通信机制与控制权限架构的底层重构,落地路由体系升级、设备参数功能、视频日志模块、中英文国际化、AI 模型升级等多项功能迭代,同步指导 APP 端核心功能开发与测试验收,并完成软件著作权申报材料撰写。'), h2('1.1 核心数据概览'), new Table({ width: { size: 100, type: WidthType.PERCENTAGE }, columnWidths: [2256, 2256, 2256, 2258], rows: [new TableRow({ cantSplit: true, children: [ statCard('Git 提交次数', '58', '0969DA'), statCard('功能模块迭代', '10+', '28A745'), statCard('核心联调里程碑', '3', 'FF8C00'), statCard('系统界面截图', '18', '8B5CF6'), ], })], }), new Paragraph({ spacing: { after: 200 } }), h2('1.2 本月工作主线'), bullet('底层通信机制优化:WebSocket 单页面单连接 + 路由切换自动销毁,彻底解决多页面重复连接、消息错乱、后台心跳堆积'), bullet('控制权限体系重构:单设备单 Token 唯一占用机制 + 主动释放权限功能,完成 Web/APP 跨端权限交替抢占与释放闭环测试'), bullet('苏州算法联调:路径规划全流程打通,覆盖设备打点、路径保存、后台规划指令下发、算法回执、地图可视化轨迹绘制'), bullet('路由架构升级:一级路由整体改造为二级路由体系,完成路由框架适配与跳转逻辑修复'), bullet('设备参数与定时任务:双端参数修改功能开发与测试、APP 蓝牙模式参数修改、Web 定时任务全流程测试'), bullet('视频与日志模块:视频批量下载 Node 脚本重构为 Java 接口、日志权限区分展示'), bullet('国际化与 AI 升级:中英文双语切换覆盖高频业务页面、AI 大模型统一升级为 GPT-5.6'), bullet('APP 端指导与测试:扫码绑定、蓝牙/非蓝牙模式、参数修改授权管控、视频推拉流、无人机数据展示'), bullet('软著与文档沉淀:软件著作权申报材料撰写与迭代、iOS 适配技术文档、Web 端路径规划 SOP 文档'), new Paragraph({ children: [new PageBreak()] }), // === 第二章 底层机制优化 === h1('第二章 智慧运维平台底层机制优化'), h2('2.1 WebSocket 连接机制优化'), p('针对系统原有 WebSocket 连接逻辑存在多页面重复连接、消息错乱、后台心跳堆积等问题,本月对 WS 连接逻辑进行深度优化:'), bullet('实现单页面仅维持一次 WS 连接,避免多页面重复创建连接'), bullet('页面路由切换时自动销毁当前 WS 连接,杜绝旧连接残留'), bullet('解决 WS 切换时序差导致的历史数据残留与数据展示异常问题'), bullet('退出路由时不订阅消息,提升系统整体通信稳定性与性能'), callout('优化价值', 'WebSocket 机制优化后,系统通信链路更加稳定,消息推送实时性与准确性显著提升,为多端协同、实时监控、告警推送等业务场景提供可靠的底层通信支撑。'), h2('2.2 实时监控与消息订阅'), p('结合 WebSocket 机制优化,实时监控页面能够稳定接收设备状态、告警事件、机器位置等实时数据,为运维人员提供准确的一线态势感知。'), createImage('07_realtime.png'), caption('图 2-1 实时监控页面 - 实时功率与设备在线率'), new Paragraph({ children: [new PageBreak()] }), // === 第三章 苏州算法联调 === h1('第三章 苏州算法联调与路径规划'), h2('3.1 联调背景与目标'), p('本月持续对接苏州算法团队,开展机器路径规划功能的全流程联调工作。受展会演示设备资源短缺影响,优先完成核心基础联调内容,并支撑苏州现场机器演示调试与保障。'), h2('3.2 联调里程碑'), h3('3.2.1 第一步:设备状态界面打点联调成功'), p('与算法团队完成设备状态界面机器打点功能调试,实现:'), bullet('机器在线状态正常上报'), bullet('经纬度数据正常上报与展示'), bullet('机器实时轨迹打点功能运行正常'), bullet('设备位置状态精准展示,保障联调基础能力闭环'), createImage('03_device_status.png'), caption('图 3-1 设备状态详情页 - 机器经纬度与打点数据'), h3('3.2.2 第二步:路径规划全链路打通'), p('完整打通业务链路,实现路径规划功能全流程:'), bullet('设备打点:在地图上完成机器位置打点与清除打点标志'), bullet('路径数据保存:将打点数据上传至后台保存'), bullet('后台规划指令下发:平台向算法端下发路径规划指令'), bullet('接收算法端回执:接收算法端规划结果回执'), bullet('地图可视化绘制:在地图上同时绘制规划轨迹与机器实时行走路径'), p('指令下发成功后,地图上可清晰看到规划路径与机器实时行走轨迹,路径规划功能整体流程跑通、状态正常。'), h3('3.2.3 第三步:模式适配与显示优化'), p('根据不同模式显示区域或线段,优化一加载时显示的地图内容,并支持在地图上鼠标悬浮显示机器信息、优化登录用户角色显示等细节体验。'), createImage('04_wayline.png'), caption('图 3-2 航线任务页 - 路径规划与可视化'), callout('联调成果', '路径规划全链路打通,覆盖设备打点、数据保存、指令下发、回执接收、地图可视化绘制五大环节,并支撑苏州现场机器演示顺利落地。'), new Paragraph({ children: [new PageBreak()] }), // === 第四章 控制权限体系重构 === h1('第四章 控制权限体系重构与闭环'), h2('4.1 权限架构升级背景'), p('原有"单用户单设备控制"模式存在多端抢占、权限混乱、权限滞留等问题,无法满足跨端协同控制与设备安全管控需求。本月重构设备抢占控制逻辑,从底层保证设备控制唯一性与安全性。'), h2('4.2 单设备单 Token 唯一占用机制'), p('将原有控制模式升级为单设备单 Token 唯一占用机制:'), bullet('一台设备同一时间仅被一个有效连接控制,彻底解决多端抢占问题'), bullet('控制权限修改不再需要判断 Web 是否有权限,简化权限判定逻辑'), bullet('新增主动释放权限功能,支持用户主动让出设备控制权'), bullet('页面切换/杀死页面时自动释放控制权限,避免权限滞留'), h2('4.3 跨端闭环测试'), p('完成权限逻辑的全场景闭环测试,验证权限释放与抢占逻辑准确、稳定、无残留占用:'), bullet('Web 不同账号切换场景:权限正确释放与抢占'), bullet('Web 同账号页面切换场景:权限随路由切换自动释放'), bullet('Web 与 APP 跨端权限交替抢占与释放场景:跨端协同正常'), p('控制权限重构为后续与苏州团队深度联调、实现跨端权限联动与设备协同控制筑牢了基础。'), createImage('14_system.png'), caption('图 4-1 系统设置 - 权限管控与基础配置'), new Paragraph({ children: [new PageBreak()] }), // === 第五章 路由架构升级与组件迭代 === h1('第五章 路由架构升级与组件迭代'), h2('5.1 路由架构整体优化升级'), p('根据团队优化建议,完成系统路由结构重构:'), bullet('将原有一级路由改造为二级路由体系,页面层级结构更加清晰规范'), bullet('完成二级菜单初步实现、配置与机器人路由适配'), bullet('针对性修复更换路由框架带来的适配问题'), bullet('重点优化设备总览、设备状态详情页面路由跳转逻辑,解决跳转异常、页面定位不准等问题'), createImage('02_device_overview.png'), caption('图 5-1 设备总览页 - 二级路由体系下的设备管理'), h2('5.2 路由组件拆分与性能优化'), p('完成路由组件拆分优化,精简冗余代码、优化加载逻辑:'), bullet('路由组件按需拆分,提升页面路由跳转速度'), bullet('优化整体页面访问流畅度'), bullet('登录默认选中机制,提升首次访问体验'), bullet('优化设备管理界面,将 5 个子页面抽离为独立组件,实现组件轻量化'), bullet('优化设备参数弹窗 loading 效果与两个组件内弹窗的数据影响'), h2('5.3 设备管理子模块重构'), p('完成设备管理 tab 重构,针对状态界面视频停止与状态信息解耦进行优化,让数据展示更清晰,业务解耦更彻底。'), createImage('05_robot_task.png'), caption('图 5-2 机器人任务页 - 设备任务调度与管理'), new Paragraph({ children: [new PageBreak()] }), // === 第六章 设备参数与定时任务 === h1('第六章 设备参数与定时任务功能'), h2('6.1 设备参数编辑功能迭代开发与测试'), p('完成 Web 端与 APP 端设备参数修改功能开发及测试工作:'), h3('6.1.1 权限管控机制'), bullet('双端新增设备参数修改能力,支持通过授权机制管控参数修改权限'), bullet('Web 端可自定义配置设备参数可修改时长'), bullet('双端根据授权信息自动判断用户操作权限,精准控制参数编辑功能可用性'), bullet('根据身份判断能不能选中相关参数项,权限不足时不可编辑'), h3('6.1.2 交互体验优化'), bullet('参数滑块联动展示效果,操作更直观'), bullet('设备参数组件抽离重构,实现组件轻量化,优化页面加载性能'), bullet('新增 loading 加载状态,完善交互体验'), bullet('派单流程优化:派单时选择接收人员,根据身份判断能不能选中'), h3('6.1.3 APP 端蓝牙模式适配'), bullet('完成 APP 端蓝牙模式修改设备参数功能开发与测试'), bullet('适配不同设备操作场景,保障无网络/弱网环境下的设备管控能力'), createImage('06_video.png'), caption('图 6-1 视频管理页 - 设备视频文件批量下载'), h2('6.2 定时任务功能测试'), p('完成 Web 端定时任务功能全流程测试:'), bullet('任务创建与配置流程校验'), bullet('任务执行逻辑验证'), bullet('任务启停控制测试'), bullet('周期运行逻辑校验'), bullet('保障定时任务功能稳定可用,满足平台自动化运维需求'), new Paragraph({ children: [new PageBreak()] }), // === 第七章 视频与日志管理模块 === h1('第七章 视频与日志管理模块'), h2('7.1 视频管理模块改造升级'), p('完成视频管理界面功能开发,支持批量下载设备本地存储视频文件。本次改造重点包括:'), bullet('将原有 Node 脚本实现的下载逻辑重构为 Java 接口,统一后端技术栈'), bullet('提升服务统一性、稳定性和可维护性'), bullet('完成视频接入接口对接'), bullet('设备管理 tab 重构,加上 flv 预览能力(仅供测试,正式建议下载使用)'), h2('7.2 日志管理模块开发'), p('完成日志管理界面功能开发,实现权限区分展示:'), bullet('管理员可查看服务端运行日志'), bullet('便于后续问题排查与系统运维'), bullet('目前相关界面已完成开发,待后续对接完整接口'), createImage('17_profile.png'), caption('图 7-1 个人中心 - 用户权限与日志查看入口'), new Paragraph({ children: [new PageBreak()] }), // === 第八章 国际化与 AI 升级 === h1('第八章 国际化适配与 AI 大模型升级'), h2('8.1 系统中英文国际化适配'), p('完成平台核心业务界面的中英文双语切换功能开发:'), bullet('覆盖日常使用高频页面,满足多语言使用场景'), bullet('登录页右上角支持中英文一键切换'), bullet('针对静态页面暂未做国际化接入,考虑到后续静态页面结构和内容仍会频繁调整,暂不提前适配,避免重复开发与无效迭代,合理节约开发成本'), createImage('00_login.png'), caption('图 8-1 登录页 - 中英文切换入口'), h2('8.2 AI 大模型版本迭代升级'), p('根据郭老师工作部署及项目智能化迭代要求,完成项目 AI 大模型版本升级替换:'), bullet('将原有模型统一更新为 GPT-5.6 版本'), bullet('新版本模型有效优化推理精度、交互响应效果与业务适配性'), bullet('进一步提升平台智能化服务能力'), bullet('为后续各类智能业务场景落地提供可靠的技术支撑'), createImage('10_ai.png'), caption('图 8-2 AI 诊断分析页 - 大模型升级后的智能分析能力'), new Paragraph({ children: [new PageBreak()] }), // === 第九章 基础功能模块完善 === h1('第九章 基础功能模块完善'), h2('9.1 用户与角色管理优化'), p('优化用户与角色模块,根据管理员的角色获取名下用户,让权限管理、用户管理体系更清晰规整:'), bullet('用户角色概览功能开发'), bullet('角色权限概览功能开发'), bullet('优化页面展示逻辑与数据渲染效果'), bullet('修复 admin 可以看到所有用户的问题,按角色严格管控可见范围'), bullet('地图中鼠标悬浮显示机器信息时,优化显示登录用户的角色'), createImage('15_users.png'), caption('图 9-1 用户管理页 - 用户体系与权限概览'), createImage('16_roles.png'), caption('图 9-2 角色管理页 - 角色权限概览'), h2('9.2 电站地址功能接入'), p('完成电站地址功能接入,适配多场站运维管理场景:'), bullet('支持自定义修改场站地址'), bullet('切换不同电站时可精准匹配、展示对应场站位置'), bullet('修复地图地址显示相关问题'), bullet('修改名称和电站地址,让场站标识更清晰'), h2('9.3 控制台报错信息清理'), p('针对性优化代码消除控制台的报错信息:'), bullet('修复地图图标大小在初始化时长宽 -1 的警告'), bullet('优化 mqtt 退出路由时不订阅消息,避免不必要的报错'), bullet('提升整体代码质量与运行稳定性'), new Paragraph({ children: [new PageBreak()] }), // === 第十章 APP 端优化指导 === h1('第十章 APP 端优化指导与测试'), h2('10.1 APP 端功能优化指导'), p('本月持续跟进机器 APP 端优化迭代与测试工作,全程指导 APP 端完成核心功能适配:'), bullet('路径规划全套业务流程适配与调试,保证移动端与 Web 端业务逻辑统一、交互闭环'), bullet('扫码绑定设备功能优化整改'), bullet('蓝牙/非蓝牙模式适配'), bullet('授权管控设备参数修改功能开发'), bullet('视频推拉流控制功能开发与调试,完善设备视频实时操控能力'), bullet('无人机实时数据展示逻辑优化,提升数据刷新实时性与页面展示效果'), h2('10.2 APP 端测试验收情况'), p('对优化后的功能进行全面测试,校验场景适配性、权限逻辑及操作流畅度:'), bullet('本月针对本月遗留问题进行专项攻坚,绝大部分测试点已完成验证,整体功能基本达标'), bullet('剩余约 10% 测试内容仍存在轻微问题,后续将持续跟进排查、优化修复,完成全量测试闭环'), bullet('及时发现问题并反馈、跟进整改落地,保障 APP 端各项核心功能正常运行'), bullet('进一步提升移动端设备运维操作的便捷性与稳定性'), callout('移动端价值', 'APP 端作为现场运维人员的随身工具,承担扫码绑定、蓝牙管控、视频操控、数据展示等核心能力,本月完成全部核心功能指导与 90% 测试验证。'), new Paragraph({ children: [new PageBreak()] }), // === 第十一章 全业务链路闭环测试 === h1('第十一章 全业务链路闭环测试'), h2('11.1 告警工单全流程链路测试'), p('完成系统告警、工单、任务全流程链路逻辑测试:'), bullet('依据系统配置规则,校验告警触发后自动生成工单的准确性'), bullet('核对告警列表与工单列表的数据一致性'), bullet('告警闭环逻辑验证:关联告警的工单完成或关闭后,对应告警自动消除、停止持续触发'), bullet('若设备仍存在异常、处于告警状态,系统可重新触发告警,逻辑符合业务预期'), createImage('09_alerts.png'), caption('图 11-1 告警中心 - 告警列表与工单联动'), h2('11.2 告警钉钉推送测试'), p('完成告警钉钉推送功能测试:'), bullet('支持各场站独立配置开启/关闭钉钉推送权限'), bullet('实现告警消息灵活推送,满足多场站差异化通知需求'), h2('11.3 工单派发功能迭代优化'), p('新增平台工单手动派发逻辑:'), bullet('支持管理员将各类运维工单定向指派给指定用户'), bullet('用户端可正常展示、接收被派发的工单'), bullet('完善了平台工单分配管理机制'), bullet('手动派发功能已调试完成,后续将持续迭代开发工单自动派发功能'), createImage('12_workorder.png'), caption('图 11-2 工单任务页 - 工单派发与全生命周期管理'), h2('11.4 设备参数配置功能测试'), p('完成平台设备参数配置功能测试:'), bullet('系统支持自定义配置设备轮胎增益系数、运行速度等核心设备参数'), bullet('页面配置逻辑、参数保存功能运行正常'), bullet('受下位机未完成全量测试影响,该模块整体联调工作暂未完成,待下位机测试收尾后继续完善'), h2('11.5 剩余待测试工作'), p('当前平台核心链路测试基本完成,后续需结合实际工单场景,完成平台向机器下发任务的全流程测试,补齐业务链路测试闭环。'), new Paragraph({ children: [new PageBreak()] }), // === 第十二章 软著申报与文档沉淀 === h1('第十二章 软著申报与文档沉淀'), h2('12.1 软件著作权申报材料撰写'), p('结合智慧运维平台现有功能、业务架构与技术实现,独立完成软件著作权申报材料的撰写:'), bullet('梳理系统创新点、功能架构与应用场景'), bullet('根据审核要求及修改建议持续迭代优化内容'), bullet('推进软著申报进度,助力后续顺利审核通过'), callout('知识产权价值', '软件著作权申报是平台技术成果的重要知识产权沉淀,有助于提升项目技术壁垒,保护核心代码资产。'), h2('12.2 iOS 适配技术文档'), p('协助指导 APP 苹果端相关功能实现:'), bullet('梳理 iOS 端调试要点'), bullet('独立整理并输出 ios.md 技术文档'), bullet('统一调试规范、记录适配细节'), bullet('方便后续迭代对接、问题复盘与维护调试'), bullet('有效降低后续对接成本'), h2('12.3 Web 端路径规划 SOP 文档'), p('梳理 Web 端路径规划完整操作流程,编写标准化 SOP 操作文档:'), bullet('统一操作规范'), bullet('便于后续迭代维护、人员交接与业务落地'), h2('12.4 新增 TodoList 页面建设'), p('完成平台 TodoList 页面的搭建建设工作:'), bullet('在日常测试与功能迭代过程中,系统梳理汇总各类待优化、待开发、待测试的后续任务点'), bullet('统一录入 TodoList 页面进行集中管理'), bullet('通过该页面可清晰沉淀后续迭代需求、未完成工作及长期优化规划'), bullet('实现任务可视化、条理化管理,为后续工作推进、任务落地、迭代规划提供清晰的参考依据'), bullet('有效提升工作统筹效率'), new Paragraph({ children: [new PageBreak()] }), // === 第十三章 Git 提交记录统计 === h1('第十三章 Git 提交记录统计'), p('本月(2026-08-01 至 2026-08-31)项目代码仓库共提交 58 次,提交者覆盖项目主体开发人员。以下为按时间倒序的关键提交记录摘要,反映本月功能开发与修复节奏。'), h2('13.1 关键提交节点摘录'), bullet('2026-08-31:修复地图鼠标悬浮显示机器、admin 用户可见范围、控制台警告信息、地图地址显示等多项问题'), bullet('2026-08-31:优化 mqtt 退出路由不订阅消息,消除控制台报错信息'), bullet('2026-08-28:和算法联调显示规划路径并显示实时路径成功;根据模式显示区域还是线;优化一加载显示的地图内容'), bullet('2026-08-25:地图打点和清除打点标志;测权限控制释放权限,优化 WS 连接'), bullet('2026-08-21:用户角色概览;基础设置中角色概览;修改名称和电站地址;电站地址接入'), bullet('2026-08-20:杀死页面和切换页面释放控制权限;控制权限修改,不需要判断 Web 是否有权限'), bullet('2026-08-20:优化 WS 切换时候的时序差导致遗留上次的消息'), bullet('2026-08-19:和算法测试成功第一步,状态界面看到经纬度信息和保存可以成功;中英文优化;路由组件拆分;登录默认选中'), bullet('2026-08-14:中英文切换根据已有功能已经基本完善'), bullet('2026-08-12:中英文切换初始化;软著文档;设备管理 tab 重构,加上 flv 预览'), bullet('2026-08-10:视频接入接口;增加视频管理和日志管理;文档增加'), bullet('2026-08-07:优化设备管理界面将 5 个子页面抽离出组件轻量化,优化设备参数弹窗 loading 效果'), bullet('2026-08-06:优化用户与角色模块根据管理员角色获取名下用户;优化状态界面视频停止和状态信息解耦;增加推拉流播放和停止;优化派单选择接收人员;两个地方的设备参数组件加上授权功能'), bullet('2026-08-05:设备参数需要滑块'), bullet('2026-08-04:所有传 orgId 的地方修改;优化详情跳转'), bullet('2026-08-03:根据二级路由优化控制状态界面;二级菜单优化完成;二级菜单配置;机器人的路由 OK 了;二级菜单初步实现'), h2('13.2 提交记录反映的工作主线'), p('从提交时间线可以看出本月工作呈现以下节奏:'), bullet('8 月上旬(8/3-8/12):路由架构升级、用户角色模块优化、设备参数滑块与授权、视频日志管理模块、中英文切换、软著文档'), bullet('8 月中旬(8/14-8/21):中英文完善、路由组件拆分、WS 时序差优化、权限控制重构、电站地址接入、角色概览'), bullet('8 月下旬(8/25-8/31):权限释放测试与 WS 连接优化、地图打点与算法联调、地图显示与机器悬浮显示优化、控制台报错清理'), createImage('01_home.png'), caption('图 13-1 系统总览首页 - 平台整体运行态势'), new Paragraph({ children: [new PageBreak()] }), // === 第十四章 本月小结与下月计划 === h1('第十四章 本月小结与下月计划'), h2('14.1 本月工作小结'), p('本月工作覆盖智慧运维系统平台的底层机制、业务功能、移动端协同、知识产权四大维度,整体呈现"底座加固、业务闭环、移动协同、知识产权沉淀"四大特征。'), h3('14.1.1 底座加固'), bullet('WebSocket 单页面单连接 + 路由切换自动销毁,通信稳定性显著提升'), bullet('控制权限单设备单 Token 唯一占用,跨端协同与权限释放机制完善'), bullet('路由架构升级为二级路由体系,页面层级更清晰、跳转更顺畅'), h3('14.1.2 业务闭环'), bullet('路径规划全链路打通,与苏州算法团队联调成功'), bullet('设备参数双端开发完成、APP 蓝牙模式适配'), bullet('视频管理 Java 接口重构、日志权限区分展示'), bullet('告警工单全流程闭环测试通过、工单手动派发功能上线'), h3('14.1.3 移动协同'), bullet('APP 端路径规划、扫码绑定、蓝牙/非蓝牙模式、参数授权、视频推拉流、无人机数据展示等核心功能指导与 90% 测试验证'), bullet('iOS 适配技术文档沉淀,降低后续对接成本'), h3('14.1.4 知识产权与智能化'), bullet('软件著作权申报材料撰写与迭代'), bullet('AI 大模型统一升级至 GPT-5.6,智能化能力进一步提升'), bullet('中英文国际化覆盖高频业务页面'), bullet('Web 端路径规划 SOP 文档与 TodoList 任务管理页面建设'), h2('14.2 下月工作计划'), p('基于本月工作成果与遗留事项,下月将重点推进以下方向:'), bullet('路径规划联调收尾:完成与苏州团队的剩余联调内容,覆盖更多业务场景'), bullet('设备参数联调:等待下位机完成全量测试后,继续完善设备参数配置模块整体联调'), bullet('APP 端剩余 10% 测试:完成 APP 端全量测试闭环,保障移动端稳定可用'), bullet('平台下发任务全流程测试:结合实际工单场景,完成平台向机器下发任务的全流程测试'), bullet('工单自动派发功能:在手动派发基础上迭代开发自动派发能力,提升运维自动化效率'), bullet('国际化覆盖扩展:根据静态页面调整情况,逐步推进静态页面国际化适配'), bullet('软著申报跟进:根据审核反馈持续优化申报材料,推进顺利审核通过'), callout('结语', '本月围绕"稳定、安全、协同、闭环"四大关键词开展工作,平台底座更加稳固、业务链路更加完整、移动协同更加顺畅、知识产权沉淀更加扎实。后续将持续以业务价值为导向,推进各项功能迭代落地,持续提升智慧运维平台的综合能力。'), // 附录:更多系统截图 new Paragraph({ children: [new PageBreak()] }), h1('附录 系统功能截图集'), p('以下为本月工作过程中涉及的系统功能截图集,作为本月工作产出的可视化补充材料。'), h2('A.1 总览与监控'), createImage('08_monitor.png'), caption('图 A-1 监控中心 - 设备实时监控视图'), h2('A.2 设备管理'), createImage('11_clean.png'), caption('图 A-2 清洗优化页 - 智能清洗策略'), h2('A.3 报表与系统'), createImage('13_report.png'), caption('图 A-3 报表中心 - 多维度报表输出'), createImage('14_system.png'), caption('图 A-4 系统设置 - 基础设置入口'), ], }], }); Packer.toBuffer(doc).then((buffer) => { const outPath = path.join(__dirname, '智慧运维系统平台-月度工作总结报告-2026年8月-葌昀.docx'); fs.writeFileSync(outPath, buffer); console.log('✓ 月度报告已生成:', outPath); const stats = fs.statSync(outPath); console.log(' 文件大小:', (stats.size / 1024).toFixed(2), 'KB'); }).catch((err) => { console.error('✗ 生成失败:', err); process.exit(1); });