Files
AIRegulation-DocAnalysis/generate-team-ppt.js

327 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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("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",
});
}
// ── 初始化 PPT ───────────────────────────────────────────
const prs = new pptxgenjs();
prs.layout = "LAYOUT_WIDE";
prs.defineLayout({ name: "LAYOUT_WIDE", width: 13.33, height: 7.5 });
// ════════════════════════════════════════════════════════
// Slide 1 — 封面
// ════════════════════════════════════════════════════════
{
const sl = prs.addSlide();
// 浅色背景
sl.addShape("rect", {
x: 0, y: 0, w: "100%", h: "100%",
fill: { color: C.bg }, line: { color: C.bg, width: 0 },
});
// 左侧品牌色竖栏 3.2"
sl.addShape("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("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.3, w: 2.8, h: 0.28,
fontSize: 10, color: "FFFFFF", fontFace: "Calibri Light", align: "center",
});
// 右侧:标签
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("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("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",
});
}
// ════════════════════════════════════════════════════════
// Slide 2 — 项目背景
// ════════════════════════════════════════════════════════
{
const sl = prs.addSlide();
sl.addShape("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", "E20074"],
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("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("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,
});
});
}
// ════════════════════════════════════════════════════════
// Slide 3 — 本阶段工作总览
// ════════════════════════════════════════════════════════
{
const sl = prs.addSlide();
sl.addShape("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("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",
});
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",
});
});
}
// ── 保存 ────────────────────────────────────────────────
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); });