From 0398fa3fb05315e35c49bb2e73ec22e7dbe59665 Mon Sep 17 00:00:00 2001 From: wangwei Date: Wed, 27 May 2026 18:16:19 +0800 Subject: [PATCH] docs: add team-report PPT implementation plan --- .../plans/2026-05-27-team-report-ppt.md | 1328 +++++++++++++++++ 1 file changed, 1328 insertions(+) create mode 100644 docs/superpowers/plans/2026-05-27-team-report-ppt.md diff --git a/docs/superpowers/plans/2026-05-27-team-report-ppt.md b/docs/superpowers/plans/2026-05-27-team-report-ppt.md new file mode 100644 index 0000000..7faf8c7 --- /dev/null +++ b/docs/superpowers/plans/2026-05-27-team-report-ppt.md @@ -0,0 +1,1328 @@ +# 团队阶段性汇报 PPT 实现计划 + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 生成 `team-report.pptx`,一份面向跨团队 Leader / 中层管理者的 10 张幻灯片团队汇报 PPT,浅色专业风格,品牌色 #E20074。 + +**Architecture:** 单文件 Node.js 脚本 `generate-team-ppt.js`,使用 pptxgenjs 库构建所有幻灯片。采用颜色常量对象 `C`、`makeShadow()` 工厂函数、以及 `topBar/sectionLabel/sectionTitle/sectionSub/slideNum/card/badge` 等辅助函数,与现有 `generate-boss-ppt.js` 保持一致的编码模式。 + +**Tech Stack:** Node.js,pptxgenjs(全局安装于 `C:/nvm4w/nodejs/node_modules/pptxgenjs`),LAYOUT_WIDE 13.33"×7.5" + +--- + +## 文件结构 + +| 文件 | 操作 | 说明 | +|------|------|------| +| `generate-team-ppt.js` | **新建** | 主生成脚本,10 张幻灯片全部内容 | +| `team-report.pptx` | **输出** | 最终产物 | + +**重要约束(来自已有项目经验):** +- `require("C:/nvm4w/nodejs/node_modules/pptxgenjs")` — 必须用绝对路径,不能用 `require('pptxgenjs')` +- 颜色不加 `#` 前缀(如 `"E20074"` 而非 `"#E20074"`) +- `makeShadow()` 必须是工厂函数,每次调用返回新对象,不能复用同一引用 +- 使用 `RECTANGLE` 不用 `ROUNDED_RECTANGLE`(兼容性问题) +- 渐变色使用 `fill: { type: "grad", stops: [{position:0,color:"..."},{position:100,color:"..."}] }` + +--- + +## 颜色常量(所有任务共用) + +```js +const C = { + accent: "E20074", + accentDk: "BE0060", + bg: "F7F7FA", + bgCard: "FFFFFF", + bgHover: "F0F0F5", + border: "E0E0EA", + text: "1A1A2E", + text2: "4A4A6A", + text3: "8888AA", + green: "00896A", + orange: "CC6200", + blue: "2A68C8", + purple: "5A46B4", + red: "C0392B", + darkBg: "1A1A2E", +}; +``` + +--- + +## 辅助函数(所有任务共用,写在文件顶部) + +```js +const pptx = require("C:/nvm4w/nodejs/node_modules/pptxgenjs"); + +function makeShadow() { + return { type: "outer", color: "000000", opacity: 0.08, blur: 6, offset: 2, angle: 45 }; +} + +function topBar(slide) { + slide.addShape(pptx.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: 0.04, + fill: { type: "grad", stops: [{ position: 0, color: C.accent }, { position: 100, color: C.accentDk }] }, + line: { color: C.accent, width: 0 }, + }); +} + +function sectionLabel(slide, text, x, y) { + slide.addText(text, { + x, y, w: 9, h: 0.25, + fontSize: 9, bold: true, color: C.accent, + charSpacing: 3, fontFace: "Calibri", + }); +} + +function sectionTitle(slide, text, x, y) { + slide.addText(text, { + x, y, w: 9, h: 0.5, + fontSize: 26, bold: true, color: C.text, fontFace: "Calibri", + }); +} + +function sectionSub(slide, text, x, y) { + slide.addText(text, { + x, y, w: 10, h: 0.3, + fontSize: 12, color: C.text3, fontFace: "Calibri", + }); +} + +function slideNum(slide, n, total) { + slide.addText(`${n} / ${total}`, { + x: 12, y: 7.1, w: 1.2, h: 0.25, + fontSize: 9, color: C.text3, align: "right", fontFace: "Calibri Light", + }); +} + +function badge(slide, text, x, y, w, color, bgAlpha) { + // color: hex without #, bgAlpha: "12" means 12% opacity approximated as light fill + slide.addText(text, { + x, y, w, h: 0.22, + fontSize: 9, bold: true, color: color, + fill: { color: color, transparency: 88 }, + line: { color: color, width: 0.5, transparency: 70 }, + align: "center", fontFace: "Calibri", + margin: [2, 6, 2, 6], + }); +} +``` + +--- + +## Task 1: 脚本骨架 + Slide 1 封面 + +**Files:** +- Create: `generate-team-ppt.js` + +- [ ] **Step 1: 创建脚本骨架** + +```js +// generate-team-ppt.js +const pptxgenjs = require("C:/nvm4w/nodejs/node_modules/pptxgenjs"); + +// ── 颜色常量 ────────────────────────────────────────────── +const C = { + accent: "E20074", + accentDk: "BE0060", + bg: "F7F7FA", + bgCard: "FFFFFF", + bgHover: "F0F0F5", + border: "E0E0EA", + text: "1A1A2E", + text2: "4A4A6A", + text3: "8888AA", + green: "00896A", + orange: "CC6200", + blue: "2A68C8", + purple: "5A46B4", + red: "C0392B", + darkBg: "1A1A2E", +}; + +// ── 辅助函数 ───────────────────────────────────────────── +function makeShadow() { + return { type: "outer", color: "000000", opacity: 0.08, blur: 6, offset: 2, angle: 45 }; +} + +function topBar(slide) { + slide.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: 0.04, + fill: { type: "grad", stops: [{ position: 0, color: C.accent }, { position: 100, color: C.accentDk }] }, + line: { color: C.accent, width: 0 }, + }); +} + +function sectionLabel(slide, text, x, y) { + slide.addText(text, { + x, y, w: 9, h: 0.25, + fontSize: 9, bold: true, color: C.accent, + charSpacing: 3, fontFace: "Calibri", + }); +} + +function sectionTitle(slide, text, x, y) { + slide.addText(text, { + x, y, w: 9, h: 0.5, + fontSize: 26, bold: true, color: C.text, fontFace: "Calibri", + }); +} + +function sectionSub(slide, text, x, y) { + slide.addText(text, { + x, y, w: 10, h: 0.3, + fontSize: 12, color: C.text3, fontFace: "Calibri", + }); +} + +function slideNum(slide, n, total) { + slide.addText(`${n} / ${total}`, { + x: 12, y: 7.1, w: 1.2, h: 0.25, + fontSize: 9, color: C.text3, align: "right", fontFace: "Calibri Light", + }); +} + +function badge(slide, text, x, y, w, color) { + slide.addText(text, { + x, y, w, h: 0.22, + fontSize: 9, bold: true, color: color, + fill: { color: color, transparency: 88 }, + line: { color: color, width: 0.5, transparency: 70 }, + align: "center", fontFace: "Calibri", + margin: [2, 6, 2, 6], + }); +} + +// ── 初始化 PPT ─────────────────────────────────────────── +const prs = new pptxgenjs(); +prs.layout = "LAYOUT_WIDE"; // 13.33" x 7.5" +prs.defineLayout({ name: "LAYOUT_WIDE", width: 13.33, height: 7.5 }); + +// ── 幻灯片将在后续 Task 中添加 ────────────────────────── + +// ── 保存 ──────────────────────────────────────────────── +const OUT = "C:/Projects/AIProjects/AIRegulations/AIRegulation-DocAnalysis-Demo/team-report.pptx"; +prs.writeFile({ fileName: OUT }) + .then(() => console.log("✅ 生成完成:", OUT)) + .catch(e => { console.error("❌ 生成失败:", e); process.exit(1); }); +``` + +- [ ] **Step 2: 添加 Slide 1 — 封面** + +在 `// ── 幻灯片将在后续 Task 中添加` 之后、`// ── 保存` 之前插入: + +```js +// ════════════════════════════════════════════════════════ +// Slide 1 — 封面 +// ════════════════════════════════════════════════════════ +{ + const sl = prs.addSlide(); + // 浅色背景 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: "100%", + fill: { color: C.bg }, line: { color: C.bg, width: 0 }, + }); + + // 左侧品牌色竖栏 3.2" + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: 3.2, h: 7.5, + fill: { type: "grad", stops: [{ position: 0, color: "B0005A" }, { position: 100, color: C.accent }] }, + line: { color: C.accent, width: 0 }, + }); + + // 左栏:英文副标题 + sl.addText("EMS & EHS Compliance\nIntelligence Hub", { + x: 0.3, y: 1.8, w: 2.6, h: 0.7, + fontSize: 11, italic: true, color: "FFFFFF", + fontFace: "Calibri Light", align: "center", + }); + + // 左栏:项目大标题 + sl.addText("AI + 合规\n智能中枢", { + x: 0.2, y: 2.6, w: 2.8, h: 1.2, + fontSize: 24, bold: true, color: "FFFFFF", + fontFace: "Calibri", align: "center", + }); + + // 左栏:分隔线 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0.6, y: 3.9, w: 2.0, h: 0.02, + fill: { color: "FFFFFF", transparency: 60 }, + line: { color: "FFFFFF", width: 0 }, + }); + + // 左栏:团队 + 日期 + sl.addText("T-Systems · AI 合规项目组", { + x: 0.2, y: 4.0, w: 2.8, h: 0.28, + fontSize: 10, color: "FFFFFF", fontFace: "Calibri Light", align: "center", + }); + sl.addText("2026 年 05 月", { + x: 0.2, y: 4.28, w: 2.8, h: 0.28, + fontSize: 10, color: "FFFFFF", fontFace: "Calibri Light", align: "center", + transparency: 20, + }); + + // 右侧:标签 + sl.addText("TEAM PROGRESS REPORT", { + x: 3.6, y: 1.2, w: 6, h: 0.25, + fontSize: 9, bold: true, color: C.accent, + charSpacing: 3, fontFace: "Calibri", + }); + + // 右侧:汇报标题 + sl.addText("团队阶段性汇报", { + x: 3.6, y: 1.5, w: 9, h: 0.65, + fontSize: 34, bold: true, color: C.text, fontFace: "Calibri", + }); + + // 右侧:说明文字 + sl.addText("基于 Agent 协同的多模块法规合规智能平台\n多团队协作 · 阶段成果汇报 · 分工与规划", { + x: 3.6, y: 2.25, w: 9, h: 0.6, + fontSize: 12, color: C.text2, fontFace: "Calibri Light", + }); + + // 右侧:3个数字指标卡 + const stats = [ + { num: "5", label: "功能模块\n已完成/开发中", color: C.accent }, + { num: "17+", label: "REST API 接口\n已设计并文档化", color: C.green }, + { num: "6+", label: "法规来源\n接入覆盖", color: C.orange }, + ]; + stats.forEach((s, i) => { + const sx = 3.6 + i * 2.8; + sl.addShape(pptxgenjs.ShapeType.rect, { + x: sx, y: 3.1, w: 2.5, h: 1.4, + fill: { color: C.bgCard }, line: { color: C.border, width: 0.5 }, + shadow: makeShadow(), + }); + // 顶部彩色细条 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: sx, y: 3.1, w: 2.5, h: 0.05, + fill: { color: s.color }, line: { color: s.color, width: 0 }, + }); + sl.addText(s.num, { + x: sx + 0.15, y: 3.2, w: 2.2, h: 0.65, + fontSize: 40, bold: true, color: s.color, fontFace: "Calibri", + }); + sl.addText(s.label, { + x: sx + 0.15, y: 3.85, w: 2.2, h: 0.55, + fontSize: 10, color: C.text3, fontFace: "Calibri Light", + }); + }); + + // 底部机密标注 + sl.addText("INTERNAL · CONFIDENTIAL", { + x: 3.6, y: 7.1, w: 6, h: 0.25, + fontSize: 9, color: C.text3, fontFace: "Calibri", + }); +} +``` + +- [ ] **Step 3: 运行验证** + +```bash +node C:/Projects/AIProjects/AIRegulations/AIRegulation-DocAnalysis-Demo/generate-team-ppt.js +``` + +期望输出:`✅ 生成完成: C:/Projects/.../team-report.pptx` + +- [ ] **Step 4: 提交** + +```bash +git add generate-team-ppt.js +git commit -m "feat: add team-report PPT generator - slide 1 cover" +``` + +--- + +## Task 2: Slide 2 — 项目背景 & Slide 3 — 工作总览 + +**Files:** +- Modify: `generate-team-ppt.js` (在 Slide 1 代码块之后追加) + +- [ ] **Step 1: 添加 Slide 2 — 项目背景** + +```js +// ════════════════════════════════════════════════════════ +// Slide 2 — 项目背景 +// ════════════════════════════════════════════════════════ +{ + const sl = prs.addSlide(); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: "100%", + fill: { color: C.bg }, line: { color: C.bg, width: 0 }, + }); + topBar(sl); + sectionLabel(sl, "项目背景", 0.5, 0.55); + sectionTitle(sl, "为什么要做这个系统?", 0.5, 0.85); + sectionSub(sl, "汽车行业合规管理三大核心痛点,传统人工方式已无法满足需求", 0.5, 1.4); + slideNum(sl, 2, 10); + + const painPoints = [ + { + topColor: ["B0005A", C.accent], + icon: "📋", + title: "法规碎片化", + body: "GB、MIIT、UN-ECE、IATF 16949、ISO 45001、EUR-Lex 等多源法规并存,更新频繁,人工跟踪极易遗漏,合规窗口期短。", + }, + { + topColor: ["C05000", "FF8800"], + icon: "⏱", + title: "响应周期长", + body: "从法规发布到内部解读、影响评估、整改计划,人工流程往往需要数周,无法满足快速迭代的合规要求。", + }, + { + topColor: ["00A080", "00D4AA"], + icon: "💼", + title: "人工成本高", + body: "合规专家大量时间消耗在文档检索、条款比对、报告撰写等重复性工作上,高价值判断时间被严重压缩。", + }, + ]; + + painPoints.forEach((p, i) => { + const cx = 0.5 + i * 4.22; + // 卡片底 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: cx, y: 1.9, w: 4.0, h: 4.8, + fill: { color: C.bgCard }, line: { color: C.border, width: 0.5 }, + shadow: makeShadow(), + }); + // 顶部彩条 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: cx, y: 1.9, w: 4.0, h: 0.07, + fill: { type: "grad", stops: [{ position: 0, color: p.topColor[0] }, { position: 100, color: p.topColor[1] }] }, + line: { color: p.topColor[0], width: 0 }, + }); + // 图标 + sl.addText(p.icon, { + x: cx + 0.25, y: 2.1, w: 0.7, h: 0.6, + fontSize: 28, fontFace: "Segoe UI Emoji", + }); + // 标题 + sl.addText(p.title, { + x: cx + 0.25, y: 2.75, w: 3.5, h: 0.4, + fontSize: 16, bold: true, color: C.text, fontFace: "Calibri", + }); + // 正文 + sl.addText(p.body, { + x: cx + 0.25, y: 3.25, w: 3.5, h: 2.8, + fontSize: 12, color: C.text2, fontFace: "Calibri Light", + paraSpaceAfter: 4, lineSpacingMultiple: 1.4, + }); + }); +} +``` + +- [ ] **Step 2: 添加 Slide 3 — 本阶段工作总览** + +```js +// ════════════════════════════════════════════════════════ +// Slide 3 — 本阶段工作总览 +// ════════════════════════════════════════════════════════ +{ + const sl = prs.addSlide(); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: "100%", + fill: { color: C.bg }, line: { color: C.bg, width: 0 }, + }); + topBar(sl); + sectionLabel(sl, "阶段成果", 0.5, 0.55); + sectionTitle(sl, "本阶段工作总览", 0.5, 0.85); + sectionSub(sl, "5 个功能模块 · 核心 Agent 问答链路全通 · 角色分工一览", 0.5, 1.4); + slideNum(sl, 3, 10); + + const modules = [ + { + icon: "📡", num: "01", name: "法规智能感知", + desc: "六大法规源事件流,影响分级过滤,SSE 流式 AI 影响解读", + status: "⟳ 进行中", statusColor: C.orange, + role: "前端工程师 / 后端工程师", + }, + { + icon: "📚", num: "02", name: "文档知识库管理", + desc: "PDF/Word 入库,5 步 Pipeline 可视化,双引擎 OCR 解析", + status: "⟳ 进行中", statusColor: C.orange, + role: "后端工程师 / AI 工程师", + }, + { + icon: "🔍", num: "03", name: "合规分析审查", + desc: "逐段风险评分,内嵌 Agent 对话,风险聚合仪表盘", + status: "⟳ 进行中", statusColor: C.orange, + role: "全栈工程师", + }, + { + icon: "💬", num: "04", name: "法规 Agent 对话", + desc: "Milvus 向量检索 + LLM 全链路贯通,多轮追问,来源归因", + status: "✓ 核心链路已通", statusColor: C.green, + role: "AI 工程师 / 后端工程师", + }, + { + icon: "🖥️", num: "05", name: "系统状态监控", + desc: "五项基础设施健康检查,17+ API,系统配置总览", + status: "✓ 已完成", statusColor: C.green, + role: "后端工程师 / 运维", + }, + ]; + + modules.forEach((m, i) => { + const ry = 1.85 + i * 1.02; + // 行卡片 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0.5, y: ry, w: 12.3, h: 0.9, + fill: { color: C.bgCard }, line: { color: C.border, width: 0.5 }, + shadow: makeShadow(), + }); + // 图标 + sl.addText(m.icon, { + x: 0.7, y: ry + 0.18, w: 0.55, h: 0.55, + fontSize: 20, fontFace: "Segoe UI Emoji", + }); + // 编号 + sl.addText(m.num, { + x: 1.3, y: ry + 0.28, w: 0.4, h: 0.28, + fontSize: 8, color: C.text3, fontFace: "Calibri", bold: true, + }); + // 模块名 + sl.addText(m.name, { + x: 1.7, y: ry + 0.12, w: 2.8, h: 0.3, + fontSize: 13, bold: true, color: C.text, fontFace: "Calibri", + }); + // 描述 + sl.addText(m.desc, { + x: 1.7, y: ry + 0.46, w: 5.8, h: 0.28, + fontSize: 10, color: C.text2, fontFace: "Calibri Light", + }); + // 状态 badge + sl.addText(m.status, { + x: 7.7, y: ry + 0.26, w: 2.2, h: 0.28, + fontSize: 9, bold: true, color: m.statusColor, + fill: { color: m.statusColor, transparency: 88 }, + line: { color: m.statusColor, width: 0.5, transparency: 70 }, + align: "center", margin: [2, 6, 2, 6], fontFace: "Calibri", + }); + // 负责角色 + sl.addText(m.role, { + x: 10.1, y: ry + 0.26, w: 2.5, h: 0.28, + fontSize: 9, color: C.text3, fontFace: "Calibri Light", align: "right", + }); + }); +} +``` + +- [ ] **Step 3: 运行验证** + +```bash +node C:/Projects/AIProjects/AIRegulations/AIRegulation-DocAnalysis-Demo/generate-team-ppt.js +``` + +期望:`✅ 生成完成`,打开 team-report.pptx 确认前 3 张幻灯片布局正常。 + +- [ ] **Step 4: 提交** + +```bash +git add generate-team-ppt.js +git commit -m "feat: team-report PPT slides 2-3 background and progress overview" +``` + +--- + +## Task 3: Slide 4 & 5 — 核心功能演示 + +**Files:** +- Modify: `generate-team-ppt.js` + +- [ ] **Step 1: 添加 Slide 4 — 核心功能 1/2** + +```js +// ════════════════════════════════════════════════════════ +// Slide 4 — 核心功能演示 1/2 +// ════════════════════════════════════════════════════════ +{ + const sl = prs.addSlide(); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: "100%", + fill: { color: C.bg }, line: { color: C.bg, width: 0 }, + }); + topBar(sl); + sectionLabel(sl, "产品演示", 0.5, 0.55); + sectionTitle(sl, "核心功能一览(1/2)", 0.5, 0.85); + sectionSub(sl, "前 3 个模块已上线,功能可演示", 0.5, 1.4); + slideNum(sl, 4, 10); + + const features = [ + { + bg: ["FCE8F3", "FCD5E8"], icon: "📡", name: "法规智能感知", + tags: [{ t: "高影响", c: C.accent }, { t: "中影响", c: C.orange }, { t: "低影响", c: C.green }], + badge: "LIVE", badgeC: C.green, + desc: "六大法规源实时事件流,影响等级分级过滤,选中事件触发 SSE 流式 AI 影响分析", + }, + { + bg: ["EEF2FD", "DCE8FB"], icon: "📚", name: "文档知识库管理", + tags: [{ t: "LOAD", c: C.blue }, { t: "PARSE", c: C.blue }, { t: "EMBED", c: C.blue }, { t: "STORE", c: C.green }], + badge: null, + desc: "PDF/Word 上传入库,5 步 Pipeline 可视化进度,双引擎解析,文档列表管理", + }, + { + bg: ["FFF5E8", "FDE8CC"], icon: "🔍", name: "合规分析审查", + tags: [{ t: "⚠ 高风险", c: C.red }, { t: "✓ 合规", c: C.green }], + badge: null, + desc: "上传文件逐段风险评分,内嵌 Agent 对话针对具体条款实时问答,风险聚合仪表盘", + }, + ]; + + features.forEach((f, i) => { + const cx = 0.5 + i * 4.22; + // 卡片底 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: cx, y: 1.85, w: 4.0, h: 5.0, + fill: { color: C.bgCard }, line: { color: C.border, width: 0.5 }, + shadow: makeShadow(), + }); + // 缩略图区背景 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: cx, y: 1.85, w: 4.0, h: 2.0, + fill: { type: "grad", stops: [{ position: 0, color: f.bg[0] }, { position: 100, color: f.bg[1] }] }, + line: { color: C.border, width: 0 }, + }); + // 图标 + sl.addText(f.icon, { + x: cx + 1.4, y: 2.0, w: 1.2, h: 0.9, + fontSize: 32, align: "center", fontFace: "Segoe UI Emoji", + }); + // tags + let tx = cx + 0.15; + f.tags.forEach(tag => { + sl.addText(tag.t, { + x: tx, y: 3.05, w: (tag.t.length > 4 ? 0.8 : 0.65), h: 0.22, + fontSize: 8, bold: true, color: tag.c, + fill: { color: tag.c, transparency: 88 }, + line: { color: tag.c, width: 0.4, transparency: 70 }, + align: "center", margin: [2, 4, 2, 4], fontFace: "Calibri", + }); + tx += (tag.t.length > 4 ? 0.85 : 0.7); + }); + // LIVE badge + if (f.badge) { + sl.addText(f.badge, { + x: cx + 3.15, y: 1.95, w: 0.65, h: 0.22, + fontSize: 8, bold: true, color: f.badgeC, + fill: { color: f.badgeC, transparency: 88 }, + line: { color: f.badgeC, width: 0.4, transparency: 70 }, + align: "center", margin: [2, 4, 2, 4], fontFace: "Calibri", + }); + } + // 模块名 + sl.addText(f.name, { + x: cx + 0.15, y: 3.45, w: 3.7, h: 0.35, + fontSize: 13, bold: true, color: C.text, fontFace: "Calibri", + }); + // 描述 + sl.addText(f.desc, { + x: cx + 0.15, y: 3.85, w: 3.7, h: 2.7, + fontSize: 11, color: C.text2, fontFace: "Calibri Light", + lineSpacingMultiple: 1.4, + }); + }); +} +``` + +- [ ] **Step 2: 添加 Slide 5 — 核心功能 2/2** + +```js +// ════════════════════════════════════════════════════════ +// Slide 5 — 核心功能演示 2/2 +// ════════════════════════════════════════════════════════ +{ + const sl = prs.addSlide(); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: "100%", + fill: { color: C.bg }, line: { color: C.bg, width: 0 }, + }); + topBar(sl); + sectionLabel(sl, "产品演示", 0.5, 0.55); + sectionTitle(sl, "核心功能一览(2/2)", 0.5, 0.85); + sectionSub(sl, "Agent 对话核心链路真实运行(Milvus + LLM)· 监控模块已完成", 0.5, 1.4); + slideNum(sl, 5, 10); + + // 左宽卡 — Agent 对话 (w=8.3) + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0.5, y: 1.85, w: 8.3, h: 5.0, + fill: { color: C.bgCard }, line: { color: C.green, width: 1 }, + shadow: makeShadow(), + }); + // 缩略图 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0.5, y: 1.85, w: 8.3, h: 1.8, + fill: { type: "grad", stops: [{ position: 0, color: "E8F5EF" }, { position: 100, color: "D0EDE2" }] }, + line: { color: C.border, width: 0 }, + }); + sl.addText("💬", { + x: 0.8, y: 1.95, w: 0.8, h: 0.7, + fontSize: 26, fontFace: "Segoe UI Emoji", + }); + sl.addText('"GB 18384 对我们的 BMS 设计有什么影响?" → Agent 检索 Milvus → 流式回答 + 来源引用', { + x: 0.8, y: 2.75, w: 7.7, h: 0.5, + fontSize: 10, color: C.green, + fill: { color: C.green, transparency: 90 }, + line: { color: C.green, width: 0.5, transparency: 70 }, + margin: [4, 8, 4, 8], fontFace: "Calibri Light", + }); + // 组件 badges(右侧竖排) + const agentBadges = ["Milvus 向量库", "MinIO 对象库", "Embedding 引擎", "Reranker", "Sessions 会话"]; + agentBadges.forEach((b, i) => { + sl.addText(b, { + x: 6.65, y: 1.93 + i * 0.3, w: 1.95, h: 0.24, + fontSize: 8, color: C.green, + fill: { color: C.green, transparency: 90 }, + line: { color: C.green, width: 0.4, transparency: 60 }, + align: "center", margin: [2, 4, 2, 4], fontFace: "Calibri", + }); + }); + sl.addText("法规 Agent 对话", { + x: 0.7, y: 3.42, w: 5, h: 0.35, + fontSize: 14, bold: true, color: C.text, fontFace: "Calibri", + }); + sl.addText("● 核心链路已通", { + x: 4.3, y: 3.46, w: 2.0, h: 0.28, + fontSize: 10, color: C.green, fontFace: "Calibri", + }); + sl.addText("真实 Milvus 向量检索 + LLM 流式输出全链路贯通\n会话管理、来源归因卡片、多轮追问、法规类型筛选", { + x: 0.7, y: 3.85, w: 7.8, h: 0.9, + fontSize: 11, color: C.text2, fontFace: "Calibri Light", lineSpacingMultiple: 1.5, + }); + + // 右窄卡 — 系统监控 (w=3.9) + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 9.0, y: 1.85, w: 3.9, h: 5.0, + fill: { color: C.bgCard }, line: { color: C.border, width: 0.5 }, + shadow: makeShadow(), + }); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 9.0, y: 1.85, w: 3.9, h: 1.8, + fill: { type: "grad", stops: [{ position: 0, color: "F0ECFF" }, { position: 100, color: "E2D8FF" }] }, + line: { color: C.border, width: 0 }, + }); + sl.addText("🖥️", { + x: 9.4, y: 2.0, w: 0.7, h: 0.65, + fontSize: 24, fontFace: "Segoe UI Emoji", + }); + const healthBadges = [ + { t: "Milvus ✓", c: C.green }, { t: "MinIO ✓", c: C.green }, { t: "LLM ✓", c: C.green }, + ]; + healthBadges.forEach((b, i) => { + sl.addText(b.t, { + x: 9.05 + i * 1.25, y: 3.0, w: 1.2, h: 0.22, + fontSize: 8, bold: true, color: b.c, + fill: { color: b.c, transparency: 88 }, + line: { color: b.c, width: 0.4, transparency: 70 }, + align: "center", margin: [2, 4, 2, 4], fontFace: "Calibri", + }); + }); + sl.addText("系统状态监控", { + x: 9.15, y: 3.42, w: 3.5, h: 0.35, + fontSize: 14, bold: true, color: C.text, fontFace: "Calibri", + }); + sl.addText("✓ 已完成", { + x: 9.15, y: 3.82, w: 2, h: 0.25, + fontSize: 10, bold: true, color: C.green, fontFace: "Calibri", + }); + sl.addText("五项基础设施实时健康检查,文档统计,系统配置总览(LLM / Embedding / 解析引擎)", { + x: 9.15, y: 4.15, w: 3.6, h: 2.5, + fontSize: 11, color: C.text2, fontFace: "Calibri Light", lineSpacingMultiple: 1.4, + }); +} +``` + +- [ ] **Step 3: 运行验证并提交** + +```bash +node C:/Projects/AIProjects/AIRegulations/AIRegulation-DocAnalysis-Demo/generate-team-ppt.js +git add generate-team-ppt.js +git commit -m "feat: team-report PPT slides 4-5 feature demos" +``` + +--- + +## Task 4: Slide 6 — 系统架构 & Slide 7 — 业务价值 + +**Files:** +- Modify: `generate-team-ppt.js` + +- [ ] **Step 1: 添加 Slide 6 — 系统分层架构** + +```js +// ════════════════════════════════════════════════════════ +// Slide 6 — 系统分层架构 +// ════════════════════════════════════════════════════════ +{ + const sl = prs.addSlide(); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: "100%", + fill: { color: C.bg }, line: { color: C.bg, width: 0 }, + }); + topBar(sl); + sectionLabel(sl, "技术架构", 0.5, 0.55); + sectionTitle(sl, "系统分层架构", 0.5, 0.85); + sectionSub(sl, "清洁架构 + Ports & Adapters,5 层分离,高内聚低耦合,可独立替换各层实现", 0.5, 1.4); + slideNum(sl, 6, 10); + + const layers = [ + { + grad: ["B0005A", C.accent], icon: "👥", name: "用户层", + sub: "合规专员 / EHS 专员 / 审核员 / 管理员 / 查看员", + tags: ["法规感知", "文档分析", "EHS 合规", "API 集成", "报告生成"], + tagC: C.accent, + }, + { + grad: ["00A080", "00D4AA"], icon: "🖥️", name: "前端层", + sub: "React 19 · TypeScript · Vite · React Router v7", + tags: ["KeepAlive 路由", "三主题系统 (Dark/Dim/Light)", "shadcn/ui 组件库", "Tailwind v4"], + tagC: C.green, + }, + { + grad: ["2060A0", "4A90D9"], icon: "⚡", name: "API 层", + sub: "FastAPI · kbmp-service · mcp-server · Worker 异步", + tags: ["知识库管理 API", "合规检查 API", "文档解析 API", "检索问答 API", "订阅推送 API"], + tagC: C.blue, + }, + { + grad: ["C05000", "FF8800"], icon: "🧠", name: "AI 引擎层", + sub: "Agent Orchestration · LLM · Embedding · Tool Use", + tags: ["Qwen / DeepSeek LLM", "Agent 协同编排", "向量知识检索", "工具调用 (Tool Use)", "阿里云 DocMind OCR"], + tagC: C.orange, + }, + { + grad: ["5040B0", "7B68EE"], icon: "🗄️", name: "基础设施层", + sub: "Milvus · PostgreSQL · MinIO · Prometheus · Grafana", + tags: ["Milvus 向量数据库", "PostgreSQL 结构化存储", "对象存储 (文档/Markdown)", "Prometheus + Grafana"], + tagC: C.purple, + }, + ]; + + const layerH = 0.92; + const gap = 0.08; + layers.forEach((lyr, i) => { + const ly = 1.75 + i * (layerH + gap); + // 外框 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0.5, y: ly, w: 12.3, h: layerH, + fill: { color: "FFFFFF" }, line: { color: lyr.tagC, width: 0.5, transparency: 60 }, + }); + // 左侧 header 色条 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0.5, y: ly, w: 3.2, h: layerH, + fill: { type: "grad", stops: [{ position: 0, color: lyr.grad[0] }, { position: 100, color: lyr.grad[1] }] }, + line: { color: lyr.grad[0], width: 0 }, + }); + // 图标 + sl.addText(lyr.icon, { + x: 0.6, y: ly + 0.2, w: 0.55, h: 0.55, + fontSize: 18, fontFace: "Segoe UI Emoji", + }); + // 层名 + sl.addText(lyr.name, { + x: 1.18, y: ly + 0.12, w: 1.7, h: 0.35, + fontSize: 13, bold: true, color: "FFFFFF", fontFace: "Calibri", + }); + // 副标题 + sl.addText(lyr.sub, { + x: 1.18, y: ly + 0.5, w: 2.3, h: 0.3, + fontSize: 8, color: "FFFFFF", fontFace: "Calibri Light", transparency: 20, + }); + // Tags + let tx = 3.85; + lyr.tags.forEach(tag => { + const tw = Math.max(tag.length * 0.12 + 0.2, 1.1); + sl.addText(tag, { + x: tx, y: ly + 0.32, w: tw, h: 0.24, + fontSize: 9, bold: true, color: lyr.tagC, + fill: { color: lyr.tagC, transparency: 88 }, + line: { color: lyr.tagC, width: 0.4, transparency: 70 }, + align: "center", margin: [2, 6, 2, 6], fontFace: "Calibri", + }); + tx += tw + 0.12; + }); + + // 连接箭头(不在最后一层) + if (i < layers.length - 1) { + sl.addText("↕", { + x: 6.3, y: ly + layerH, w: 0.7, h: gap + 0.04, + fontSize: 10, color: C.accent, align: "center", fontFace: "Calibri", + }); + } + }); +} +``` + +- [ ] **Step 2: 添加 Slide 7 — 业务价值** + +```js +// ════════════════════════════════════════════════════════ +// Slide 7 — 业务价值 +// ════════════════════════════════════════════════════════ +{ + const sl = prs.addSlide(); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: "100%", + fill: { color: C.bg }, line: { color: C.bg, width: 0 }, + }); + topBar(sl); + sectionLabel(sl, "业务价值", 0.5, 0.55); + sectionTitle(sl, "有与没有的差距", 0.5, 0.85); + sectionSub(sl, "量化对比:AI 智能中枢 vs 传统人工合规方式", 0.5, 1.4); + slideNum(sl, 7, 10); + + // 左侧:传统方式(浅红背景) + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0.5, y: 1.85, w: 5.6, h: 4.1, + fill: { color: "FDF0F0" }, line: { color: "E8C0C0", width: 0.5 }, + shadow: makeShadow(), + }); + sl.addText("❌ 传统人工方式", { + x: 0.75, y: 2.05, w: 5.1, h: 0.35, + fontSize: 12, bold: true, color: C.red, fontFace: "Calibri", charSpacing: 1, + }); + const before = [ + ["数周", "法规解读 + 影响评估周期"], + ["人工检索", "依赖专家经验,易遗漏"], + ["碎片化", "各系统数据孤岛,无法联动"], + ["高成本", "合规专家时间消耗在重复工作"], + ["被动响应", "法规变化后才开始评估"], + ]; + before.forEach(([kw, txt], i) => { + sl.addText(kw, { + x: 0.75, y: 2.55 + i * 0.6, w: 1.3, h: 0.3, + fontSize: 11, bold: true, color: C.red, fontFace: "Calibri", + }); + sl.addText("— " + txt, { + x: 2.1, y: 2.55 + i * 0.6, w: 3.8, h: 0.3, + fontSize: 11, color: C.text2, fontFace: "Calibri Light", + }); + }); + + // 中间箭头 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 6.15, y: 1.85, w: 0.9, h: 4.1, + fill: { color: C.bgHover }, line: { color: C.border, width: 0.5 }, + }); + sl.addText("→", { + x: 6.15, y: 3.6, w: 0.9, h: 0.5, + fontSize: 22, color: C.accent, align: "center", fontFace: "Calibri", + }); + + // 右侧:AI平台(浅绿背景) + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 7.1, y: 1.85, w: 5.7, h: 4.1, + fill: { color: "F0FAF6" }, line: { color: "A0D8C0", width: 0.5 }, + shadow: makeShadow(), + }); + sl.addText("✅ AI + 合规智能中枢", { + x: 7.35, y: 2.05, w: 5.2, h: 0.35, + fontSize: 12, bold: true, color: C.green, fontFace: "Calibri", charSpacing: 1, + }); + const after = [ + ["分钟级", "法规发布即自动解读,影响秒级评估"], + ["Agent 智能协同", "多步推理,精准定位条款"], + ["统一平台", "多源法规、多系统数据融合"], + ["降低重复劳动 70%+", "专家聚焦高价值判断"], + ["主动预警", "订阅推送,法规变化即刻触达"], + ]; + after.forEach(([kw, txt], i) => { + sl.addText(kw, { + x: 7.35, y: 2.55 + i * 0.6, w: 2.3, h: 0.3, + fontSize: 11, bold: true, color: C.green, fontFace: "Calibri", + }); + sl.addText("— " + txt, { + x: 9.7, y: 2.55 + i * 0.6, w: 2.8, h: 0.3, + fontSize: 11, color: C.text2, fontFace: "Calibri Light", + }); + }); + + // 底部 4 KPI 卡 + const kpis = [ + { num: "70%+", label: "重复性工作减少", color: C.accent }, + { num: "分钟级", label: "法规响应时间", color: C.green }, + { num: "6+", label: "法规源统一管理", color: C.orange }, + { num: "5", label: "业务场景覆盖", color: C.blue }, + ]; + // KPI 区域已由对比框占据,紧跟在对比框后已没有空间, + // 将 KPI 卡放在 y=6.1(压缩高度),4个并排 + // 注意:由于幻灯片总高 7.5,对比框到 y=5.95,KPI 在 6.05 +} +``` + +> ⚠️ **注意**:Slide 7 的布局中,对比框高度加上 KPI 卡会超出幻灯片范围。解决方案:将对比框高度降为 3.7"(y=1.85→5.55),KPI 4 格卡放在 y=5.65,h=1.55,这样总高 7.2" 不超出 7.5" 边界。实现时直接用以下修正后的完整 Slide 7 代码替换上方代码: + +```js +// ════════════════════════════════════════════════════════ +// Slide 7 — 业务价值(最终版,含布局修正) +// ════════════════════════════════════════════════════════ +{ + const sl = prs.addSlide(); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: "100%", + fill: { color: C.bg }, line: { color: C.bg, width: 0 }, + }); + topBar(sl); + sectionLabel(sl, "业务价值", 0.5, 0.55); + sectionTitle(sl, "有与没有的差距", 0.5, 0.85); + sectionSub(sl, "量化对比:AI 智能中枢 vs 传统人工合规方式", 0.5, 1.4); + slideNum(sl, 7, 10); + + // 左侧框 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0.5, y: 1.85, w: 5.6, h: 3.5, + fill: { color: "FDF0F0" }, line: { color: "E8C0C0", width: 0.5 }, shadow: makeShadow(), + }); + sl.addText("❌ 传统人工方式", { + x: 0.75, y: 2.02, w: 5.1, h: 0.32, + fontSize: 12, bold: true, color: C.red, fontFace: "Calibri", + }); + [["数周","法规解读 + 影响评估周期"],["人工检索","依赖专家经验,易遗漏"], + ["碎片化","各系统数据孤岛,无法联动"],["高成本","合规专家时间大量消耗"], + ["被动响应","法规变化后才开始评估"]].forEach(([kw, txt], i) => { + sl.addText(kw, { x: 0.75, y: 2.42 + i * 0.52, w: 1.4, h: 0.28, fontSize: 10, bold: true, color: C.red, fontFace: "Calibri" }); + sl.addText("— " + txt, { x: 2.2, y: 2.42 + i * 0.52, w: 3.7, h: 0.28, fontSize: 10, color: C.text2, fontFace: "Calibri Light" }); + }); + + // 中间 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 6.15, y: 1.85, w: 0.9, h: 3.5, + fill: { color: C.bgHover }, line: { color: C.border, width: 0.5 }, + }); + sl.addText("→", { x: 6.15, y: 3.35, w: 0.9, h: 0.5, fontSize: 22, color: C.accent, align: "center", fontFace: "Calibri" }); + + // 右侧框 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 7.1, y: 1.85, w: 5.7, h: 3.5, + fill: { color: "F0FAF6" }, line: { color: "A0D8C0", width: 0.5 }, shadow: makeShadow(), + }); + sl.addText("✅ AI + 合规智能中枢", { + x: 7.35, y: 2.02, w: 5.2, h: 0.32, + fontSize: 12, bold: true, color: C.green, fontFace: "Calibri", + }); + [["分钟级","法规发布即自动解读,影响秒级评估"],["Agent 智能协同","多步推理,精准定位条款"], + ["统一平台","多源法规、多系统数据融合"],["降低重复劳动 70%+","专家聚焦高价值判断"], + ["主动预警","订阅推送,法规变化即刻触达"]].forEach(([kw, txt], i) => { + sl.addText(kw, { x: 7.35, y: 2.42 + i * 0.52, w: 2.2, h: 0.28, fontSize: 10, bold: true, color: C.green, fontFace: "Calibri" }); + sl.addText("— " + txt, { x: 9.6, y: 2.42 + i * 0.52, w: 2.9, h: 0.28, fontSize: 10, color: C.text2, fontFace: "Calibri Light" }); + }); + + // 底部 4 KPI 卡 + const kpis = [ + { num: "70%+", label: "重复性工作减少", color: C.accent }, + { num: "分钟级", label: "法规响应时间", color: C.green }, + { num: "6+", label: "法规源统一管理", color: C.orange }, + { num: "5", label: "业务场景覆盖", color: C.blue }, + ]; + kpis.forEach((k, i) => { + const kx = 0.5 + i * 3.2; + sl.addShape(pptxgenjs.ShapeType.rect, { + x: kx, y: 5.6, w: 3.0, h: 1.55, + fill: { color: C.bgCard }, line: { color: C.border, width: 0.5 }, shadow: makeShadow(), + }); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: kx, y: 5.6, w: 3.0, h: 0.05, + fill: { color: k.color }, line: { color: k.color, width: 0 }, + }); + sl.addText(k.num, { + x: kx + 0.15, y: 5.72, w: 2.7, h: 0.65, + fontSize: 28, bold: true, color: k.color, fontFace: "Calibri", align: "center", + }); + sl.addText(k.label, { + x: kx + 0.15, y: 6.4, w: 2.7, h: 0.3, + fontSize: 10, color: C.text3, fontFace: "Calibri Light", align: "center", + }); + }); +} +``` + +- [ ] **Step 3: 运行验证并提交** + +```bash +node C:/Projects/AIProjects/AIRegulations/AIRegulation-DocAnalysis-Demo/generate-team-ppt.js +git add generate-team-ppt.js +git commit -m "feat: team-report PPT slides 6-7 architecture and value" +``` + +--- + +## Task 5: Slide 8 — 路线图 & Slide 9 — 分工 & Slide 10 — Q&A + +**Files:** +- Modify: `generate-team-ppt.js` + +- [ ] **Step 1: 添加 Slide 8 — 四阶段路线图** + +```js +// ════════════════════════════════════════════════════════ +// Slide 8 — 四阶段路线图 +// ════════════════════════════════════════════════════════ +{ + const sl = prs.addSlide(); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: "100%", + fill: { color: C.bg }, line: { color: C.bg, width: 0 }, + }); + topBar(sl); + sectionLabel(sl, "发展路线", 0.5, 0.55); + sectionTitle(sl, "四阶段推进计划", 0.5, 0.85); + sectionSub(sl, "当前处于第二阶段"Demo 打磨",核心 Agent 链路已通,正在补全剩余模块", 0.5, 1.4); + slideNum(sl, 8, 10); + + // 时间线底线:左25% green + 右25% accent + 后50% border + sl.addShape(pptxgenjs.ShapeType.rect, { x: 1.5, y: 2.35, w: 2.5, h: 0.05, fill: { color: C.green }, line: { color: C.green, width: 0 } }); + sl.addShape(pptxgenjs.ShapeType.rect, { x: 4.0, y: 2.35, w: 2.5, h: 0.05, fill: { color: C.accent }, line: { color: C.accent, width: 0 } }); + sl.addShape(pptxgenjs.ShapeType.rect, { x: 6.5, y: 2.35, w: 5.3, h: 0.05, fill: { color: C.border }, line: { color: C.border, width: 0 } }); + + const phases = [ + { + icon: "✓", iconBg: C.green, borderC: C.green, borderW: 1, + label: "阶段 01 · 已完成", title: "技术验证 POC", + items: ["清洁架构 + Ports & Adapters", "Agent 协同框架搭建", "Milvus 向量检索链路打通", "前后端项目结构建立"], + cardBg: "F0FAF6", cardBorder: "A0D8C0", + }, + { + icon: "⟳", iconBg: C.accent, borderC: C.accent, borderW: 2, + label: "阶段 02 · 进行中 ◀ 当前", title: "Demo 打磨", + items: ["5 页面前端已上线", "法规 Agent 对话全通", "Pipeline 已通,OCR 联调中", "EHS 合规 & 监控开发中"], + cardBg: "FEF0F6", cardBorder: C.accent, + }, + { + icon: "3", iconBg: C.text3, borderC: C.border, borderW: 1, + label: "阶段 03 · 待启动", title: "生产部署", + items: ["PLM/ERP/MES 集成", "Agent 能力扩展", "Milvus 集群化部署", "合规 & 监控完善"], + cardBg: C.bgCard, cardBorder: C.border, + }, + { + icon: "4", iconBg: C.text3, borderC: C.border, borderW: 1, + label: "阶段 04 · 待启动", title: "规模推广", + items: ["多租户 & 权限体系", "主动预警 & 订阅", "1-2 行业试点推广", "数据治理 & 安全合规"], + cardBg: C.bgCard, cardBorder: C.border, + }, + ]; + + phases.forEach((p, i) => { + const cx = 0.6 + i * 3.1; + // 节点圆圈 + sl.addShape(pptxgenjs.ShapeType.ellipse, { + x: cx + 0.85, y: 2.1, w: 0.55, h: 0.55, + fill: { color: p.iconBg }, line: { color: p.iconBg, width: 0 }, + }); + sl.addText(p.icon, { + x: cx + 0.85, y: 2.12, w: 0.55, h: 0.5, + fontSize: 11, bold: true, color: "FFFFFF", align: "center", fontFace: "Calibri", + }); + // 内容卡片 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: cx, y: 2.75, w: 2.85, h: 4.35, + fill: { color: p.cardBg }, line: { color: p.cardBorder, width: p.borderW }, + shadow: makeShadow(), + }); + sl.addText(p.label, { + x: cx + 0.12, y: 2.9, w: 2.6, h: 0.24, + fontSize: 8, bold: true, color: i === 1 ? C.accent : C.text3, fontFace: "Calibri", + }); + sl.addText(p.title, { + x: cx + 0.12, y: 3.18, w: 2.6, h: 0.38, + fontSize: 14, bold: true, color: C.text, fontFace: "Calibri", + }); + p.items.forEach((item, j) => { + sl.addText("▸ " + item, { + x: cx + 0.12, y: 3.65 + j * 0.6, w: 2.62, h: 0.38, + fontSize: 10, color: C.text2, fontFace: "Calibri Light", + }); + }); + }); +} +``` + +- [ ] **Step 2: 添加 Slide 9 — 下阶段重点 & 分工** + +```js +// ════════════════════════════════════════════════════════ +// Slide 9 — 下阶段重点 & 分工 +// ════════════════════════════════════════════════════════ +{ + const sl = prs.addSlide(); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: "100%", + fill: { color: C.bg }, line: { color: C.bg, width: 0 }, + }); + topBar(sl); + sectionLabel(sl, "下一步", 0.5, 0.55); + sectionTitle(sl, "下阶段重点 & 角色分工", 0.5, 0.85); + sectionSub(sl, "Demo 收尾为核心目标,同步推进业务对齐与技术准备", 0.5, 1.4); + slideNum(sl, 9, 10); + + // 左侧 2×2 行动卡(占 65%宽) + const actions = [ + { icon: "🎯", title: "Demo 收尾", items: ["补全 parse/embed Pipeline", "接入 1-2 个真实文档场景", "Mock 替换为真实 LLM 调用"] }, + { icon: "🤝", title: "业务对齐", items: ["确认演示场景与业务方", "收集业务方反馈", "需求优先级排序"] }, + { icon: "🔧", title: "技术债清理", items: ["RBAC 权限设计实现", "接入 DocMind 正式账号", "前端性能优化 & KeepAlive"] }, + { icon: "📋", title: "资源 & 决策", items: ["GPU / 算力需求评估", "确认生产 LLM 方案", "确定生产环境部署规划"] }, + ]; + + actions.forEach((a, i) => { + const col = i % 2; + const row = Math.floor(i / 2); + const cx = 0.5 + col * 4.25; + const cy = 1.85 + row * 2.65; + + sl.addShape(pptxgenjs.ShapeType.rect, { + x: cx, y: cy, w: 4.0, h: 2.45, + fill: { color: C.bgCard }, line: { color: C.border, width: 0.5 }, shadow: makeShadow(), + }); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: cx, y: cy, w: 4.0, h: 0.05, + fill: { color: C.accent }, line: { color: C.accent, width: 0 }, + }); + sl.addText(a.icon, { + x: cx + 0.18, y: cy + 0.15, w: 0.55, h: 0.5, + fontSize: 18, fontFace: "Segoe UI Emoji", + }); + sl.addText(a.title, { + x: cx + 0.75, y: cy + 0.2, w: 3.1, h: 0.38, + fontSize: 13, bold: true, color: C.text, fontFace: "Calibri", + }); + a.items.forEach((item, j) => { + sl.addText("▸ " + item, { + x: cx + 0.18, y: cy + 0.7 + j * 0.52, w: 3.6, h: 0.35, + fontSize: 10, color: C.text2, fontFace: "Calibri Light", + }); + }); + }); + + // 右侧角色分工栏 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 9.1, y: 1.85, w: 3.8, h: 5.25, + fill: { color: C.bgCard }, line: { color: C.border, width: 0.5 }, shadow: makeShadow(), + }); + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 9.1, y: 1.85, w: 3.8, h: 0.05, + fill: { color: C.blue }, line: { color: C.blue, width: 0 }, + }); + sl.addText("角色分工", { + x: 9.3, y: 2.0, w: 3.4, h: 0.35, + fontSize: 13, bold: true, color: C.text, fontFace: "Calibri", + }); + + const roles = [ + { role: "前端工程师", tasks: "法规感知 UI / 文档管理 / 性能优化" }, + { role: "后端工程师", tasks: "Pipeline 补全 / API 稳定性 / RBAC" }, + { role: "AI 工程师", tasks: "Agent 调优 / LLM 接入 / Embedding" }, + { role: "全栈 / 架构", tasks: "合规分析模块 / 系统集成 / 文档" }, + ]; + roles.forEach((r, i) => { + const ry = 2.55 + i * 1.12; + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 9.25, y: ry, w: 3.5, h: 0.9, + fill: { color: C.bgHover }, line: { color: C.border, width: 0.4 }, + }); + sl.addText(r.role, { + x: 9.4, y: ry + 0.1, w: 3.2, h: 0.28, + fontSize: 10, bold: true, color: C.blue, fontFace: "Calibri", + }); + sl.addText(r.tasks, { + x: 9.4, y: ry + 0.42, w: 3.2, h: 0.36, + fontSize: 9, color: C.text2, fontFace: "Calibri Light", + }); + }); +} +``` + +- [ ] **Step 3: 添加 Slide 10 — 结语 & Q&A** + +```js +// ════════════════════════════════════════════════════════ +// Slide 10 — 结语 & Q&A +// ════════════════════════════════════════════════════════ +{ + const sl = prs.addSlide(); + // 深色背景 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: "100%", + fill: { color: C.darkBg }, line: { color: C.darkBg, width: 0 }, + }); + // 品牌色顶条 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 0, y: 0, w: "100%", h: 0.06, + fill: { type: "grad", stops: [{ position: 0, color: C.accent }, { position: 100, color: C.accentDk }] }, + line: { color: C.accent, width: 0 }, + }); + + // 主文字 + sl.addText("感谢聆听", { + x: 1.5, y: 1.8, w: 10.3, h: 1.0, + fontSize: 48, bold: true, color: "FFFFFF", align: "center", fontFace: "Calibri", + }); + sl.addText("AI + 合规智能中枢 · 团队阶段性汇报", { + x: 1.5, y: 2.9, w: 10.3, h: 0.4, + fontSize: 14, color: C.text3, align: "center", fontFace: "Calibri Light", + }); + + // 分隔线 + sl.addShape(pptxgenjs.ShapeType.rect, { + x: 4.5, y: 3.5, w: 4.33, h: 0.02, + fill: { color: C.accent, transparency: 40 }, line: { color: C.accent, width: 0 }, + }); + + // Q&A + sl.addText("Q & A", { + x: 1.5, y: 3.7, w: 10.3, h: 0.85, + fontSize: 44, bold: true, color: C.accent, align: "center", fontFace: "Calibri", + }); + sl.addText("欢迎提问与交流", { + x: 1.5, y: 4.6, w: 10.3, h: 0.4, + fontSize: 15, color: "FFFFFF", align: "center", fontFace: "Calibri Light", + }); + + // 底部信息 + sl.addText("T-Systems · AI 合规项目组 · 2026.05 · INTERNAL CONFIDENTIAL", { + x: 1.0, y: 6.9, w: 11.33, h: 0.28, + fontSize: 9, color: C.text3, align: "center", fontFace: "Calibri Light", + }); +} +``` + +- [ ] **Step 4: 最终运行验证** + +```bash +node C:/Projects/AIProjects/AIRegulations/AIRegulation-DocAnalysis-Demo/generate-team-ppt.js +``` + +期望输出:`✅ 生成完成: C:/Projects/.../team-report.pptx` + +打开 team-report.pptx,确认: +- 共 10 张幻灯片 +- Slide 1 左侧品牌色竖栏正常 +- Slide 3 模块表格有"负责角色"列 +- Slide 7 KPI 卡在幻灯片内(不超出边界) +- Slide 9 右侧有角色分工栏 +- Slide 10 为深色 Q&A 页 + +- [ ] **Step 5: 最终提交** + +```bash +git add generate-team-ppt.js +git commit -m "feat: complete team-report PPT - slides 8-10 roadmap, assignments, QA" +``` + +--- + +## 自检清单 + +- [x] Slide 1: 封面,左侧品牌色竖栏 + 右侧 3 个数字指标卡 +- [x] Slide 2: 项目背景,3 痛点卡片,顶部彩条 +- [x] Slide 3: 工作总览,5 模块行,含状态 badge + 负责角色列 +- [x] Slide 4: 核心功能 1/2,3 列功能卡 + 缩略图区 +- [x] Slide 5: 核心功能 2/2,左宽(Agent 对话)+ 右窄(监控) +- [x] Slide 6: 系统架构,5 层堆叠图,左侧渐变 header +- [x] Slide 7: 业务价值,左右对比框 + 底部 4 KPI(布局修正,不超出 7.5" 高度) +- [x] Slide 8: 路线图,时间线 + 4 阶段节点卡 +- [x] Slide 9: 分工,2×2 行动卡 + 右侧角色分工栏(boss-report 无此页,团队汇报新增) +- [x] Slide 10: Q&A 深色封底(区别于 boss-report 的闭幕页) +- [x] 所有颜色不含 `#` 前缀 +- [x] `makeShadow()` 每次返回新对象 +- [x] 使用绝对路径 `require("C:/nvm4w/nodejs/node_modules/pptxgenjs")` +- [x] 输出路径正确:`team-report.pptx`