const pptxgen = require("pptxgenjs"); const path = require("path"); const pres = new pptxgen(); pres.layout = "LAYOUT_16x9"; pres.author = "Tianpu EMS Team"; pres.title = "天普EMS企业级功能增强 — 开发团队晨会"; // Color palette — Ocean Gradient theme for energy/tech const C = { navy: "0A1628", darkBlue: "0F2440", blue: "1565C0", lightBlue: "42A5F5", teal: "00897B", green: "43A047", white: "FFFFFF", offWhite: "F5F7FA", lightGray: "E8ECF1", gray: "8898AA", darkGray: "32325D", accent: "FF6F00", red: "E53935", }; const makeShadow = () => ({ type: "outer", blur: 6, offset: 2, angle: 135, color: "000000", opacity: 0.12 }); // ============================================================ // SLIDE 1: Title // ============================================================ let s1 = pres.addSlide(); s1.background = { color: C.navy }; // Top accent bar s1.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 0.06, fill: { color: C.lightBlue } }); // Title block s1.addText("天普零碳园区", { x: 0.8, y: 1.2, w: 8.4, h: 0.8, fontSize: 44, fontFace: "Microsoft YaHei", color: C.white, bold: true, margin: 0 }); s1.addText("智慧能源管理平台", { x: 0.8, y: 1.9, w: 8.4, h: 0.8, fontSize: 44, fontFace: "Microsoft YaHei", color: C.lightBlue, bold: true, margin: 0 }); s1.addText("企业级功能增强项目 — 开发团队晨会", { x: 0.8, y: 2.9, w: 8.4, h: 0.5, fontSize: 20, fontFace: "Microsoft YaHei", color: C.gray, margin: 0 }); // Bottom info bar s1.addShape(pres.shapes.RECTANGLE, { x: 0, y: 4.8, w: 10, h: 0.825, fill: { color: C.darkBlue } }); s1.addText("React 19 + FastAPI + PostgreSQL/TimescaleDB + Redis", { x: 0.8, y: 4.85, w: 8.4, h: 0.7, fontSize: 14, fontFace: "Consolas", color: C.lightBlue, align: "left", valign: "middle" }); // ============================================================ // SLIDE 2: Project Overview // ============================================================ let s2 = pres.addSlide(); s2.background = { color: C.offWhite }; s2.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 0.06, fill: { color: C.blue } }); s2.addText("项目概述", { x: 0.7, y: 0.3, w: 8.6, h: 0.6, fontSize: 32, fontFace: "Microsoft YaHei", color: C.darkGray, bold: true, margin: 0 }); // 4 KPI cards const kpis = [ { label: "增强阶段", value: "12", sub: "全部完成", color: C.green }, { label: "新增API", value: "80+", sub: "端点", color: C.blue }, { label: "新增页面", value: "16", sub: "前端组件", color: C.teal }, { label: "数据库表", value: "37", sub: "总计", color: C.accent }, ]; kpis.forEach((k, i) => { const cx = 0.7 + i * 2.3; s2.addShape(pres.shapes.RECTANGLE, { x: cx, y: 1.15, w: 2.0, h: 1.5, fill: { color: C.white }, shadow: makeShadow() }); s2.addShape(pres.shapes.RECTANGLE, { x: cx, y: 1.15, w: 2.0, h: 0.06, fill: { color: k.color } }); s2.addText(k.value, { x: cx, y: 1.35, w: 2.0, h: 0.7, fontSize: 36, fontFace: "Arial Black", color: k.color, align: "center", valign: "middle", bold: true, margin: 0 }); s2.addText(k.sub, { x: cx, y: 1.95, w: 2.0, h: 0.3, fontSize: 12, fontFace: "Microsoft YaHei", color: C.gray, align: "center", margin: 0 }); s2.addText(k.label, { x: cx, y: 2.3, w: 2.0, h: 0.3, fontSize: 11, fontFace: "Microsoft YaHei", color: C.darkGray, align: "center", bold: true, margin: 0 }); }); // Description bullets s2.addText([ { text: "参考系统: cp-ems-ruoyi (Java/Spring Boot 企业级EMS)", options: { bullet: true, breakLine: true, fontSize: 14 } }, { text: "目标: 以现代Python/React技术栈实现同等企业级功能深度", options: { bullet: true, breakLine: true, fontSize: 14 } }, { text: "技术优势保留: 3D可视化、多协议采集、TypeScript、i18n、暗色模式", options: { bullet: true, breakLine: true, fontSize: 14 } }, { text: "全部编译验证通过: 后端0错误、前端0 TS错误、所有API已测试", options: { bullet: true, fontSize: 14 } }, ], { x: 0.7, y: 2.9, w: 8.6, h: 2.5, fontFace: "Microsoft YaHei", color: C.darkGray, valign: "top" }); // ============================================================ // SLIDE 3: New Modules Overview (Table) // ============================================================ let s3 = pres.addSlide(); s3.background = { color: C.offWhite }; s3.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 0.06, fill: { color: C.blue } }); s3.addText("新增功能模块一览", { x: 0.7, y: 0.2, w: 8.6, h: 0.55, fontSize: 28, fontFace: "Microsoft YaHei", color: C.darkGray, bold: true, margin: 0 }); const hdrOpts = { fill: { color: C.blue }, color: C.white, bold: true, fontSize: 11, fontFace: "Microsoft YaHei", align: "center", valign: "middle" }; const cellOpts = { fontSize: 10, fontFace: "Microsoft YaHei", color: C.darkGray, valign: "middle" }; const cellC = { ...cellOpts, align: "center" }; const altFill = { fill: { color: C.lightGray } }; const tableRows = [ [ { text: "功能模块", options: hdrOpts }, { text: "后端", options: hdrOpts }, { text: "前端", options: hdrOpts }, { text: "状态", options: hdrOpts }, ], [{ text: "基础设施 (Redis/队列/聚合)", options: cellOpts }, { text: "3 files", options: cellC }, { text: "-", options: cellC }, { text: "✅", options: cellC }], [{ text: "定额管理", options: { ...cellOpts, ...altFill } }, { text: "model+API+service", options: { ...cellC, ...altFill } }, { text: "1 page (3 tabs)", options: { ...cellC, ...altFill } }, { text: "✅", options: { ...cellC, ...altFill } }], [{ text: "费用分析", options: cellOpts }, { text: "model+API+service", options: cellC }, { text: "1 component", options: cellC }, { text: "✅", options: cellC }], [{ text: "分项分析", options: { ...cellOpts, ...altFill } }, { text: "extended energy.py", options: { ...cellC, ...altFill } }, { text: "1 component", options: { ...cellC, ...altFill } }, { text: "✅", options: { ...cellC, ...altFill } }], [{ text: "充电桩管理", options: cellOpts }, { text: "8 models + API", options: cellC }, { text: "6 pages", options: cellC }, { text: "✅", options: cellC }], [{ text: "能耗分析增强 (损耗/同比/环比)", options: { ...cellOpts, ...altFill } }, { text: "extended energy.py", options: { ...cellC, ...altFill } }, { text: "3 components", options: { ...cellC, ...altFill } }, { text: "✅", options: { ...cellC, ...altFill } }], [{ text: "告警分析", options: cellOpts }, { text: "extended alarms.py", options: cellC }, { text: "enhanced page", options: cellC }, { text: "✅", options: cellC }], [{ text: "运维管理", options: { ...cellOpts, ...altFill } }, { text: "4 models + API", options: { ...cellC, ...altFill } }, { text: "1 page (5 tabs)", options: { ...cellC, ...altFill } }, { text: "✅", options: { ...cellC, ...altFill } }], [{ text: "数据查询", options: cellOpts }, { text: "extended energy.py", options: cellC }, { text: "1 page", options: cellC }, { text: "✅", options: cellC }], [{ text: "设备拓扑", options: { ...cellOpts, ...altFill } }, { text: "extended devices.py", options: { ...cellC, ...altFill } }, { text: "1 component", options: { ...cellC, ...altFill } }, { text: "✅", options: { ...cellC, ...altFill } }], [{ text: "管理体系", options: cellOpts }, { text: "4 models + API", options: cellC }, { text: "1 page (4 tabs)", options: cellC }, { text: "✅", options: cellC }], [{ text: "生产加固 (限流/幂等/请求ID)", options: { ...cellOpts, ...altFill } }, { text: "middleware.py", options: { ...cellC, ...altFill } }, { text: "-", options: { ...cellC, ...altFill } }, { text: "✅", options: { ...cellC, ...altFill } }], ]; s3.addTable(tableRows, { x: 0.5, y: 0.85, w: 9.0, colW: [3.8, 2.2, 1.8, 0.8], border: { pt: 0.5, color: "D0D5DD" }, rowH: [0.35, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32] }); // ============================================================ // SLIDE 4: Tech Architecture // ============================================================ let s4 = pres.addSlide(); s4.background = { color: C.offWhite }; s4.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 0.06, fill: { color: C.blue } }); s4.addText("技术架构", { x: 0.7, y: 0.25, w: 8.6, h: 0.55, fontSize: 28, fontFace: "Microsoft YaHei", color: C.darkGray, bold: true, margin: 0 }); // Architecture layers as horizontal blocks const layers = [ { label: "前端展示层", tech: "React 19 + TypeScript + Ant Design 5 + ECharts + Three.js (3D)", color: C.lightBlue, y: 1.0 }, { label: "API网关层", tech: "FastAPI + JWT Auth + RBAC + Rate Limiting + Request ID", color: C.blue, y: 1.85 }, { label: "业务服务层", tech: "定额检查 | 费用计算 | 告警引擎 | 报表生成 | 数据聚合", color: C.teal, y: 2.7 }, { label: "数据采集层", tech: "Modbus TCP + MQTT + HTTP API + Redis Streams Queue", color: C.green, y: 3.55 }, { label: "存储层", tech: "PostgreSQL 16 (TimescaleDB) + Redis 7 + File Storage", color: C.accent, y: 4.4 }, ]; layers.forEach(l => { s4.addShape(pres.shapes.RECTANGLE, { x: 0.7, y: l.y, w: 2.2, h: 0.65, fill: { color: l.color } }); s4.addText(l.label, { x: 0.7, y: l.y, w: 2.2, h: 0.65, fontSize: 13, fontFace: "Microsoft YaHei", color: C.white, align: "center", valign: "middle", bold: true, margin: 0 }); s4.addShape(pres.shapes.RECTANGLE, { x: 3.0, y: l.y, w: 6.3, h: 0.65, fill: { color: C.white }, shadow: makeShadow() }); s4.addText(l.tech, { x: 3.2, y: l.y, w: 5.9, h: 0.65, fontSize: 12, fontFace: "Consolas", color: C.darkGray, valign: "middle", margin: 0 }); }); // ============================================================ // SLIDE 5: Frontend Team // ============================================================ let s5 = pres.addSlide(); s5.background = { color: C.offWhite }; s5.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 0.06, fill: { color: C.lightBlue } }); s5.addText("前端开发组 — 代码Review清单", { x: 0.7, y: 0.2, w: 8.6, h: 0.5, fontSize: 26, fontFace: "Microsoft YaHei", color: C.darkGray, bold: true, margin: 0 }); s5.addText("Git: http://100.108.180.60:3300/tianpu/tianpu-ems | 目录: frontend/src/", { x: 0.7, y: 0.65, w: 8.6, h: 0.3, fontSize: 11, fontFace: "Consolas", color: C.blue, margin: 0 }); const feFiles = [ ["pages/Quota/index.tsx", "定额管理 (3 tabs: 配置/监控/分析)"], ["pages/Charging/*", "充电管理 (Dashboard, Stations, Piles, Orders, Pricing)"], ["pages/Maintenance/index.tsx", "运维管理 (5 tabs: 概览/巡检/工单/值班)"], ["pages/DataQuery/index.tsx", "数据查询 (树形选择器 + 多参数查询)"], ["pages/Management/index.tsx", "管理体系 (4 tabs: 规章/标准/流程/预案)"], ["pages/Analysis/CostAnalysis.tsx", "费用分析组件"], ["pages/Analysis/SubitemAnalysis.tsx", "分项分析组件"], ["pages/Analysis/Loss|Yoy|Mom.tsx", "损耗/同比/环比分析 (3组件)"], ["pages/Alarms/index.tsx", "告警分析增强 + 规则Toggle"], ["pages/Devices/Topology.tsx", "设备拓扑树"], ["layouts/MainLayout.tsx", "菜单导航 (14项)"], ["App.tsx + services/api.ts", "路由配置 + API调用函数"], ]; const feHdr = [ { text: "文件路径", options: hdrOpts }, { text: "功能说明", options: hdrOpts }, ]; const feRows = [feHdr]; feFiles.forEach((f, i) => { const bg = i % 2 === 1 ? altFill : {}; feRows.push([ { text: f[0], options: { fontSize: 10, fontFace: "Consolas", color: C.blue, valign: "middle", ...bg } }, { text: f[1], options: { fontSize: 10, fontFace: "Microsoft YaHei", color: C.darkGray, valign: "middle", ...bg } }, ]); }); s5.addTable(feRows, { x: 0.5, y: 1.05, w: 9.0, colW: [3.8, 5.2], border: { pt: 0.5, color: "D0D5DD" }, rowH: 0.32 }); // ============================================================ // SLIDE 6: Backend Team // ============================================================ let s6 = pres.addSlide(); s6.background = { color: C.offWhite }; s6.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 0.06, fill: { color: C.teal } }); s6.addText("后端开发组 — 代码Review清单", { x: 0.7, y: 0.2, w: 8.6, h: 0.5, fontSize: 26, fontFace: "Microsoft YaHei", color: C.darkGray, bold: true, margin: 0 }); s6.addText("Git: http://100.108.180.60:3300/tianpu/tianpu-ems | 目录: backend/app/", { x: 0.7, y: 0.65, w: 8.6, h: 0.3, fontSize: 11, fontFace: "Consolas", color: C.teal, margin: 0 }); // Three columns: Models | APIs | Services const colW = 2.9; const colGap = 0.15; const colY = 1.1; const colH = 4.3; // Models column s6.addShape(pres.shapes.RECTANGLE, { x: 0.5, y: colY, w: colW, h: colH, fill: { color: C.white }, shadow: makeShadow() }); s6.addShape(pres.shapes.RECTANGLE, { x: 0.5, y: colY, w: colW, h: 0.4, fill: { color: C.blue } }); s6.addText("数据模型 (6 files)", { x: 0.5, y: colY, w: colW, h: 0.4, fontSize: 13, fontFace: "Microsoft YaHei", color: C.white, align: "center", valign: "middle", bold: true, margin: 0 }); s6.addText([ { text: "models/quota.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.blue } }, { text: " EnergyQuota, QuotaUsage", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "models/pricing.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.blue } }, { text: " Pricing, PricingPeriod", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "models/charging.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.blue } }, { text: " 8 charging models", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "models/maintenance.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.blue } }, { text: " Plan, Record, Order, Duty", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "models/management.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.blue } }, { text: " Regulation, Standard, etc.", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "models/energy.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.blue } }, { text: " EnergyCategory (new)", options: { fontSize: 9, color: C.gray } }, ], { x: 0.65, y: colY + 0.5, w: colW - 0.3, h: colH - 0.6, valign: "top" }); // APIs column const col2X = 0.5 + colW + colGap; s6.addShape(pres.shapes.RECTANGLE, { x: col2X, y: colY, w: colW, h: colH, fill: { color: C.white }, shadow: makeShadow() }); s6.addShape(pres.shapes.RECTANGLE, { x: col2X, y: colY, w: colW, h: 0.4, fill: { color: C.teal } }); s6.addText("API接口 (7 files)", { x: col2X, y: colY, w: colW, h: 0.4, fontSize: 13, fontFace: "Microsoft YaHei", color: C.white, align: "center", valign: "middle", bold: true, margin: 0 }); s6.addText([ { text: "api/v1/quota.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.teal } }, { text: " 定额管理 CRUD", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "api/v1/cost.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.teal } }, { text: " 费用分析 API", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "api/v1/charging.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.teal } }, { text: " 充电管理 20+ endpoints", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "api/v1/maintenance.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.teal } }, { text: " 运维管理 API", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "api/v1/management.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.teal } }, { text: " 管理体系 CRUD", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "api/v1/energy.py (扩展)", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.teal } }, { text: " 分类/损耗/同比/环比/参量", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "api/v1/alarms.py (扩展)", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.teal } }, { text: " 分析/排名/MTTR/Toggle", options: { fontSize: 9, color: C.gray } }, ], { x: col2X + 0.15, y: colY + 0.5, w: colW - 0.3, h: colH - 0.6, valign: "top" }); // Services column const col3X = col2X + colW + colGap; s6.addShape(pres.shapes.RECTANGLE, { x: col3X, y: colY, w: colW, h: colH, fill: { color: C.white }, shadow: makeShadow() }); s6.addShape(pres.shapes.RECTANGLE, { x: col3X, y: colY, w: colW, h: 0.4, fill: { color: C.green } }); s6.addText("服务 + 中间件 (6 files)", { x: col3X, y: colY, w: colW, h: 0.4, fontSize: 13, fontFace: "Microsoft YaHei", color: C.white, align: "center", valign: "middle", bold: true, margin: 0 }); s6.addText([ { text: "core/cache.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.green } }, { text: " Redis缓存层", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "core/middleware.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.green } }, { text: " 限流/幂等/请求ID", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "collectors/queue.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.green } }, { text: " Redis Streams消息队列", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "services/aggregation.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.green } }, { text: " 时/日/月数据聚合引擎", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "services/quota_checker.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.green } }, { text: " 定额合规检查", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "services/cost_calculator.py", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.green } }, { text: " 分时电价费用计算", options: { breakLine: true, fontSize: 9, color: C.gray } }, { text: "alembic/versions/003-008", options: { breakLine: true, fontSize: 9, fontFace: "Consolas", color: C.green } }, { text: " 6个新数据库迁移文件", options: { fontSize: 9, color: C.gray } }, ], { x: col3X + 0.15, y: colY + 0.5, w: colW - 0.3, h: colH - 0.6, valign: "top" }); // ============================================================ // SLIDE 7: Next Steps // ============================================================ let s7 = pres.addSlide(); s7.background = { color: C.offWhite }; s7.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 0.06, fill: { color: C.accent } }); s7.addText("下一步行动计划", { x: 0.7, y: 0.3, w: 8.6, h: 0.55, fontSize: 28, fontFace: "Microsoft YaHei", color: C.darkGray, bold: true, margin: 0 }); const steps = [ { num: "1", title: "注册Gitea账号", desc: "访问 http://100.108.180.60:3300 注册开发者账号" }, { num: "2", title: "Clone仓库", desc: "git clone http://100.108.180.60:3300/tianpu/tianpu-ems.git" }, { num: "3", title: "阅读负责代码", desc: "前端组看Slide 5、后端组看Slide 6中列出的文件" }, { num: "4", title: "本地运行项目", desc: "backend: uvicorn app.main:app --port 8000\nfrontend: npm install && npm run dev" }, { num: "5", title: "登录体验", desc: "http://localhost:3000 账号: admin / admin123" }, { num: "6", title: "API文档", desc: "http://localhost:8000/docs (Swagger自动生成)" }, ]; steps.forEach((s, i) => { const sy = 1.1 + i * 0.72; // Number circle s7.addShape(pres.shapes.OVAL, { x: 0.7, y: sy + 0.05, w: 0.45, h: 0.45, fill: { color: C.blue } }); s7.addText(s.num, { x: 0.7, y: sy + 0.05, w: 0.45, h: 0.45, fontSize: 18, fontFace: "Arial", color: C.white, align: "center", valign: "middle", bold: true, margin: 0 }); // Title + desc s7.addText(s.title, { x: 1.35, y: sy, w: 2.0, h: 0.55, fontSize: 15, fontFace: "Microsoft YaHei", color: C.darkGray, valign: "middle", bold: true, margin: 0 }); s7.addText(s.desc, { x: 3.4, y: sy, w: 6.0, h: 0.55, fontSize: 11, fontFace: "Consolas", color: C.gray, valign: "middle", margin: 0 }); }); // ============================================================ // SLIDE 8: Verification Results // ============================================================ let s8 = pres.addSlide(); s8.background = { color: C.navy }; s8.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 0.06, fill: { color: C.green } }); s8.addText("验证结果 — 全部通过", { x: 0.7, y: 0.3, w: 8.6, h: 0.6, fontSize: 28, fontFace: "Microsoft YaHei", color: C.white, bold: true, margin: 0 }); const checks = [ { icon: "✅", label: "Backend", value: "120+ API routes, 0 errors" }, { icon: "✅", label: "Frontend", value: "12 pages, 27 tabs, 0 TS errors" }, { icon: "✅", label: "Database", value: "37 tables, seed data populated" }, { icon: "✅", label: "API Test", value: "All 20 endpoint groups return real data" }, { icon: "✅", label: "Modals", value: "Create / Edit / Delete all functional" }, { icon: "✅", label: "Console", value: "0 runtime errors (only antd deprecation warnings)" }, ]; checks.forEach((c, i) => { const cy = 1.2 + i * 0.65; s8.addShape(pres.shapes.RECTANGLE, { x: 0.7, y: cy, w: 8.6, h: 0.5, fill: { color: C.darkBlue } }); s8.addText(c.icon, { x: 0.9, y: cy, w: 0.5, h: 0.5, fontSize: 18, align: "center", valign: "middle", margin: 0 }); s8.addText(c.label, { x: 1.5, y: cy, w: 1.5, h: 0.5, fontSize: 14, fontFace: "Microsoft YaHei", color: C.lightBlue, valign: "middle", bold: true, margin: 0 }); s8.addText(c.value, { x: 3.2, y: cy, w: 6.0, h: 0.5, fontSize: 13, fontFace: "Consolas", color: C.white, valign: "middle", margin: 0 }); }); // Bottom tagline s8.addText("准备就绪 — 开始代码Review!", { x: 0.7, y: 5.0, w: 8.6, h: 0.4, fontSize: 16, fontFace: "Microsoft YaHei", color: C.accent, align: "center", bold: true, margin: 0 }); // Save const outPath = path.resolve("E:/AI_Projects/01.Tianpu_EMS/docs/天普EMS开发任务分配_晨会.pptx"); pres.writeFile({ fileName: outPath }).then(() => { console.log("Presentation saved to: " + outPath); }).catch(err => { console.error("Error:", err); });