Files
star-cloud/pptx_gen.cjs

136 lines
8.3 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.
const pptxgen = require("pptxgenjs");
const fs = require("fs");
const pres = new pptxgen();
pres.layout = "LAYOUT_16x9";
pres.title = "Star Cloud Demo Day - Technical Edition";
pres.author = "許家偉";
// --- Theme Colors ---
const COLORS = {
bg: "0F172A",
cardBg: "1E293B",
highlight: "2DD4BF",
secondary: "7DD3FC",
text: "FFFFFF",
muted: "94A3B8"
};
const FONTS = {
header: "Georgia",
body: "Calibri"
};
const makeShadow = (opacity = 0.2) => ({
type: "outer",
blur: 8,
offset: 3,
angle: 135,
color: "000000",
opacity: opacity
});
// --- Slide 1: Title ---
const slide1 = pres.addSlide();
slide1.background = { color: COLORS.bg };
slide1.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 0.15, h: "100%", fill: { color: COLORS.highlight } });
slide1.addText("Star Cloud Demo Day", { x: 1.0, y: 1.8, w: 8, h: 1, fontSize: 48, fontFace: FONTS.header, color: COLORS.text, bold: true, margin: 0 });
slide1.addText("2026-03-25 ~ 2026-03-31 成果發表", { x: 1.0, y: 2.8, w: 8, h: 0.5, fontSize: 24, fontFace: FONTS.body, color: COLORS.secondary, italic: true });
slide1.addShape(pres.shapes.RECTANGLE, { x: 7.5, y: 4.5, w: 2, h: 0.6, fill: { color: COLORS.highlight, transparency: 10 }, shadow: makeShadow() });
slide1.addText("演講者:許家偉", { x: 7.5, y: 4.5, w: 2, h: 0.6, fontSize: 14, fontFace: FONTS.body, color: COLORS.text, align: "center", valign: "middle", bold: true });
// --- Slide 2: Overview ---
const slide2 = pres.addSlide();
slide2.background = { color: COLORS.bg };
slide2.addText("本週進度總覽 / Overview", { x: 0.5, y: 0.4, w: 9, h: 0.6, fontSize: 32, fontFace: FONTS.header, color: COLORS.highlight, bold: true });
slide2.addShape(pres.shapes.LINE, { x: 2, y: 3, w: 6, h: 0, line: { color: COLORS.highlight, width: 4 } });
const timelineItems = [
{ title: "機台權限管理", desc: "模組獨立化與效能優化" },
{ title: "商品管理整合", desc: "狀態整合與多語系修復" },
{ title: "廣告隔離機制", desc: "多租戶素材歸屬強化" }
];
timelineItems.forEach((item, idx) => {
const x = 2 + (idx * 3);
slide2.addShape(pres.shapes.OVAL, { x: x - 0.2, y: 2.8, w: 0.4, h: 0.4, fill: { color: COLORS.secondary }, line: { color: COLORS.text, width: 2 } });
slide2.addText(item.title, { x: x - 1, y: 3.3, w: 2, h: 0.4, fontSize: 18, fontFace: FONTS.header, color: COLORS.text, align: "center", bold: true });
slide2.addText(item.desc, { x: x - 1, y: 3.7, w: 2, h: 0.6, fontSize: 12, fontFace: FONTS.body, color: COLORS.muted, align: "center" });
});
// --- Slide 3: Highlight 1 - Machine Permissions (WITH EAGER LOADING) ---
const slide3 = pres.addSlide();
slide3.background = { color: COLORS.bg };
slide3.addText("亮點一:機台權限管理獨立化", { x: 0.5, y: 0.4, w: 9, h: 0.6, fontSize: 28, fontFace: FONTS.header, color: COLORS.highlight, bold: true });
const features = [
{ title: "直覺檢索", text: "管理員可快速檢索、分配所屬帳號對應的機台清單。" },
{ title: "即時過濾", text: "透過 Alpine.js 實作,輸入關鍵字即動態無刷新過濾。" },
{ title: "效能關鍵Eager Loading", text: "使用 with('machines') 解決 N+1 問題,萬筆資料秒開。" }
];
features.forEach((f, idx) => {
const y = 1.2 + (idx * 1.3);
slide3.addShape(pres.shapes.RECTANGLE, { x: 0.5, y: y, w: 4, h: 1.1, fill: { color: COLORS.cardBg }, line: { color: COLORS.secondary, width: 1 }, shadow: makeShadow() });
slide3.addText(f.title, { x: 0.7, y: y + 0.1, w: 3.5, h: 0.3, fontSize: 16, fontFace: FONTS.header, color: COLORS.highlight, bold: true });
slide3.addText(f.text, { x: 0.7, y: y + 0.45, w: 3.5, h: 0.5, fontSize: 12, fontFace: FONTS.body, color: COLORS.text });
});
slide3.addImage({
path: "/home/mama/.gemini/antigravity/brain/58a170d0-7144-4e9f-9396-3e753a0bf69a/machine_permissions_table_1774944648298.png",
x: 4.8, y: 1.2, w: 4.8, h: 3.7, sizing: { type: 'contain' }, shadow: makeShadow(0.3)
});
// --- Slide 4: Highlight 2 ---
const slide4 = pres.addSlide();
slide4.background = { color: COLORS.bg };
slide4.addText("亮點二:商品管理整合與 UX 完善", { x: 0.5, y: 0.4, w: 9, h: 0.6, fontSize: 28, fontFace: FONTS.header, color: COLORS.highlight, bold: true });
const comparison = [
{ title: "功能整合 (Integrated)", items: ["• 「商品狀態」納入主流程", "• 減少跳轉,提升管理效率"] },
{ title: "細節優化 (Enhanced)", items: ["• 修復多語系(ZH/EN/JA)存取故障", "• 密碼欄位新增顯隱切換按鈕"] }
];
comparison.forEach((c, idx) => {
const x = 0.5 + (idx * 4.75);
slide4.addShape(pres.shapes.RECTANGLE, { x: x, y: 1.2, w: 4.25, h: 3.5, fill: { color: COLORS.cardBg }, line: { color: COLORS.highlight, width: 2 }, shadow: makeShadow(0.2) });
slide4.addText(c.title, { x: x + 0.2, y: 1.4, w: 3.8, h: 0.4, fontSize: 18, fontFace: FONTS.header, color: COLORS.highlight, bold: true, align: "center" });
slide4.addText(c.items.map(i => ({ text: i, options: { breakLine: true, bullet: true } })), { x: x + 0.3, y: 2.0, w: 3.6, h: 2.5, fontSize: 14, fontFace: FONTS.body, color: COLORS.text, margin: 0 });
});
// --- Slide 5: Highlight 3 ---
const slide5 = pres.addSlide();
slide5.background = { color: COLORS.bg };
slide5.addText("亮點三:多租戶廣告素材隔離機制", { x: 1.0, y: 0.4, w: 8, h: 1, fontSize: 32, fontFace: FONTS.header, color: COLORS.highlight, bold: true, align: "center" });
slide5.addShape(pres.shapes.OVAL, { x: 4.25, y: 2.0, w: 1.5, h: 1.5, fill: { color: COLORS.highlight, transparency: 30 }, line: { color: COLORS.secondary, width: 2 } });
slide5.addText("安全性隔離\n(Shield)", { x: 4.25, y: 2.5, w: 1.5, h: 0.5, fontSize: 14, fontFace: FONTS.header, color: COLORS.text, align: "center", bold: true });
const isolations = [
{ x: 1, y: 1.8, label: "公司 A\n廣告素材", color: "A8DADC" },
{ x: 7.5, y: 1.8, label: "公司 B\n廣告素材", color: "A8DADC" },
{ x: 1, y: 3.8, label: "公司 C\n廣告素材", color: "A8DADC" },
{ x: 7.5, y: 3.8, label: "公司 D\n廣告素材", color: "A8DADC" }
];
isolations.forEach(i => {
slide5.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: i.x, y: i.y, w: 1.5, h: 0.8, fill: { color: COLORS.cardBg }, line: { color: COLORS.secondary, width: 1 }, rectRadius: 0.1 });
slide5.addText(i.label, { x: i.x, y: i.y, w: 1.5, h: 0.8, fontSize: 12, fontFace: FONTS.body, color: COLORS.text, align: "center", valign: "middle" });
slide5.addShape(pres.shapes.LINE, { x: i.x + (i.x < 5 ? 1.5 : 0), y: i.y + 0.4, w: i.x < 5 ? (4.25 - (i.x + 1.5)) : (7.5 - (i.x + 1.5)), h: 2.75 - (i.y + 0.4), line: { color: COLORS.secondary, width: 1, dashType: "dash" } });
});
slide5.addText("嚴格驗證 company_id確保素材 100% 歸屬隔離。", { x: 0.5, y: 5.0, w: 9, h: 0.4, fontSize: 14, fontFace: FONTS.body, color: COLORS.muted, align: "center", italic: true });
// --- Slide 6: Future Roadmap ---
const slide6 = pres.addSlide();
slide6.background = { color: COLORS.bg };
slide6.addText("未來計畫 / Roadmap", { x: 0.5, y: 0.4, w: 9, h: 1, fontSize: 36, fontFace: FONTS.header, color: COLORS.highlight, bold: true, align: "center" });
const roadmap = [
{ icon: "Optim", title: "操作優化", text: "針對樂樂反饋優化操作流程與介面體驗。" },
{ icon: "Sync", title: "API 對接", text: "與 Terry 配合,實現機台通訊穩定與對接。" },
{ icon: "Remote", title: "遠端管理", text: "實作遠端控制與異常即時監控監管。" }
];
roadmap.forEach((r, idx) => {
const x = 0.5 + (idx * 3.1);
slide6.addShape(pres.shapes.RECTANGLE, { x: x, y: 2.0, w: 2.8, h: 2.5, fill: { color: COLORS.highlight, transparency: 85 }, line: { color: COLORS.highlight, width: 2 }, shadow: makeShadow() });
slide6.addText(r.title, { x: x, y: 2.3, w: 2.8, h: 0.5, fontSize: 20, fontFace: FONTS.header, color: COLORS.highlight, bold: true, align: "center" });
slide6.addText(r.text, { x: x + 0.2, y: 3.0, w: 2.4, h: 1.2, fontSize: 14, fontFace: FONTS.body, color: COLORS.text, align: "center" });
});
slide6.addText("Star Cloud 將持續進化,打造最領先的智能雲端平台。🚀", { x: 0.5, y: 5.0, w: 9, h: 0.4, fontSize: 14, fontFace: FONTS.body, color: COLORS.secondary, align: "center", bold: true });
pres.writeFile({ fileName: "star-cloud-demo-20260331.pptx" })
.then(fileName => console.log(`Presentation created: ${fileName}`))
.catch(err => { console.error("Error creating presentation:", err); process.exit(1); });