#!/usr/bin/env python3 """Generate investor pitch deck for 数字能量学智能体平台.""" from pptx import Presentation from pptx.util import Inches, Pt, Emu from pptx.dml.color import RGBColor from pptx.enum.text import PP_ALIGN, MSO_ANCHOR from pptx.enum.shapes import MSO_SHAPE import os # ── Colour palette ── DEEP_PURPLE = RGBColor(0x4A, 0x14, 0x8C) # 深紫 — 主色 MEDIUM_PURPLE = RGBColor(0x7B, 0x2D, 0xC8) # 中紫 LIGHT_PURPLE = RGBColor(0xE1, 0xBE, 0xF5) # 浅紫 GOLD = RGBColor(0xDB, 0xB4, 0x2A) # 金色 — 强调 WHITE = RGBColor(0xFF, 0xFF, 0xFF) DARK = RGBColor(0x1A, 0x1A, 0x2E) GREY = RGBColor(0x66, 0x66, 0x66) LIGHT_GREY = RGBColor(0xF3, 0xEE, 0xF9) GREEN = RGBColor(0x2E, 0x7D, 0x32) ORANGE = RGBColor(0xF5, 0x7C, 0x00) RED = RGBColor(0xC6, 0x28, 0x28) TEAL = RGBColor(0x00, 0x96, 0x88) prs = Presentation() prs.slide_width = Inches(13.333) prs.slide_height = Inches(7.5) W = prs.slide_width H = prs.slide_height def add_bg(slide, color): """Fill slide background.""" bg = slide.background fill = bg.fill fill.solid() fill.fore_color.rgb = color def rect(slide, left, top, width, height, color, opacity=None): """Add a coloured rectangle.""" shape = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, left, top, width, height) shape.fill.solid() shape.fill.fore_color.rgb = color shape.line.fill.background() return shape def text_box(slide, left, top, width, height, text, font_size=18, color=DARK, bold=False, alignment=PP_ALIGN.LEFT, font_name="Microsoft YaHei"): """Add a text box.""" txBox = slide.shapes.add_textbox(left, top, width, height) tf = txBox.text_frame tf.word_wrap = True p = tf.paragraphs[0] p.text = text p.font.size = Pt(font_size) p.font.color.rgb = color p.font.bold = bold p.font.name = font_name p.alignment = alignment return txBox def multi_text(slide, left, top, width, height, lines, default_size=16, default_color=DARK): """Add text box with multiple formatted lines. lines = [(text, size, color, bold), ...] or just str """ txBox = slide.shapes.add_textbox(left, top, width, height) tf = txBox.text_frame tf.word_wrap = True for i, line in enumerate(lines): if i == 0: p = tf.paragraphs[0] else: p = tf.add_paragraph() if isinstance(line, str): p.text = line p.font.size = Pt(default_size) p.font.color.rgb = default_color p.font.name = "Microsoft YaHei" else: text, size, color, bold = line[0], line[1], line[2], line[3] if len(line) > 3 else False p.text = text p.font.size = Pt(size) p.font.color.rgb = color p.font.bold = bold p.font.name = "Microsoft YaHei" return txBox def circle(slide, left, top, size, color, text="", font_size=12, font_color=WHITE): """Add a circle with optional centered text.""" shape = slide.shapes.add_shape(MSO_SHAPE.OVAL, left, top, size, size) shape.fill.solid() shape.fill.fore_color.rgb = color shape.line.fill.background() if text: tf = shape.text_frame tf.word_wrap = True p = tf.paragraphs[0] p.text = text p.font.size = Pt(font_size) p.font.color.rgb = font_color p.font.bold = True p.font.name = "Microsoft YaHei" p.alignment = PP_ALIGN.CENTER tf.paragraphs[0].space_before = Pt(0) tf.paragraphs[0].space_after = Pt(0) return shape def accent_bar(slide, left, top, width=Inches(0.6), height=Inches(0.06), color=GOLD): return rect(slide, left, top, width, height, color) # ═══════════════════════════════════════════════════════ # SLIDE 1: Cover # ═══════════════════════════════════════════════════════ slide = prs.slides.add_slide(prs.slide_layouts[6]) # blank add_bg(slide, DEEP_PURPLE) # Decorative circles circle(slide, Inches(-1.5), Inches(-1.5), Inches(4), MEDIUM_PURPLE) circle(slide, Inches(10.5), Inches(4.5), Inches(5), MEDIUM_PURPLE) text_box(slide, Inches(1.5), Inches(1.8), Inches(10), Inches(1), "数字能量学智能体平台", 44, WHITE, True, PP_ALIGN.LEFT) accent_bar(slide, Inches(1.5), Inches(2.8)) text_box(slide, Inches(1.5), Inches(3.1), Inches(8), Inches(0.8), "以生日为入口 · AI 为引擎 · 数字能量学为语言", 22, LIGHT_PURPLE, False, PP_ALIGN.LEFT) multi_text(slide, Inches(1.5), Inches(4.2), Inches(8), Inches(1.2), [ ("帮助每个人认识自己、匹配他人", 28, WHITE, True), ("", 12, WHITE, False), ("投资方案 | 2026", 18, LIGHT_PURPLE, False), ]) # ═══════════════════════════════════════════════════════ # SLIDE 2: 市场机会 # ═══════════════════════════════════════════════════════ slide = prs.slides.add_slide(prs.slide_layouts[6]) add_bg(slide, WHITE) accent_bar(slide, Inches(0.8), Inches(0.6), Inches(0.6), Inches(0.06)) text_box(slide, Inches(0.8), Inches(0.8), Inches(6), Inches(0.7), "市场机会", 32, DEEP_PURPLE, True) # Market data cards data = [ ("数字命理赛道已验证", "灵机文化年营收过亿\n星座/塔罗 App 千万级用户", GREEN), ("行业痛点", "仍处于\"师傅接散客\"的原始状态\n没有标准化、平台化产品", RED), ("对标", "美国 astrology.com\n月活 2000 万+,订阅制成熟", TEAL), ] for i, (title, desc, color) in enumerate(data): x = Inches(0.8 + i * 4.1) y = Inches(2.0) card = rect(slide, x, y, Inches(3.7), Inches(2.8), LIGHT_GREY) # Top color strip rect(slide, x, y, Inches(3.7), Inches(0.08), color) text_box(slide, x + Inches(0.3), y + Inches(0.4), Inches(3.2), Inches(0.5), title, 18, color, True) text_box(slide, x + Inches(0.3), y + Inches(1.1), Inches(3.2), Inches(1.5), desc, 14, DARK, False) text_box(slide, Inches(0.8), Inches(5.3), Inches(11), Inches(0.8), "我们的定位:比八字简单、比星座有据、比纯社交有深度——数字能量学的中国版 astrology.com", 16, DEEP_PURPLE, True, PP_ALIGN.LEFT) # ═══════════════════════════════════════════════════════ # SLIDE 3: 三重价值引擎 # ═══════════════════════════════════════════════════════ slide = prs.slides.add_slide(prs.slide_layouts[6]) add_bg(slide, WHITE) accent_bar(slide, Inches(0.8), Inches(0.6)) text_box(slide, Inches(0.8), Inches(0.8), Inches(8), Inches(0.7), "三重价值引擎", 32, DEEP_PURPLE, True) engines = [ ("🎯 大众用户", "3 秒生成命盘 + AI 解读\n人格匹配交友\n→ VIP 月卡/年卡订阅", DEEP_PURPLE), ("🔧 能量师", "客户管理 + 批量工具\n平台获客 + 线上咨询\n→ 年费 + 每单抽佣 20%", GOLD), ("🧠 平台自身", "海量命盘数据\n训练专属 AI 模型\n→ 数据壁垒 + B 端 API", TEAL), ] for i, (title, desc, color) in enumerate(engines): x = Inches(0.8 + i * 4.1) y = Inches(2.0) card = rect(slide, x, y, Inches(3.7), Inches(4.0), LIGHT_GREY) rect(slide, x, y, Inches(3.7), Inches(0.08), color) # Circle icon circle(slide, x + Inches(1.35), y + Inches(0.3), Inches(0.8), color) # Title above the circle text_box(slide, x + Inches(0.3), y + Inches(0.35), Inches(3.2), Inches(0.5), title.split(" ")[0] if " " in title else title, 11, WHITE, True, PP_ALIGN.CENTER) # Title below circle text_box(slide, x + Inches(0.3), y + Inches(1.3), Inches(3.2), Inches(0.5), title, 17, color, True, PP_ALIGN.CENTER) text_box(slide, x + Inches(0.3), y + Inches(2.0), Inches(3.2), Inches(1.8), desc, 14, DARK, False, PP_ALIGN.CENTER) # ═══════════════════════════════════════════════════════ # SLIDE 4: 数字人格匹配 — 创新社交场景 # ═══════════════════════════════════════════════════════ slide = prs.slides.add_slide(prs.slide_layouts[6]) add_bg(slide, WHITE) accent_bar(slide, Inches(0.8), Inches(0.6)) text_box(slide, Inches(0.8), Inches(0.8), Inches(10), Inches(0.7), "最大的创新:数字人格匹配 → 陌生交友", 32, DEEP_PURPLE, True) # Left: matching logic rect(slide, Inches(0.8), Inches(1.8), Inches(5.8), Inches(4.8), LIGHT_GREY) text_box(slide, Inches(1.1), Inches(2.0), Inches(5.2), Inches(0.5), "匹配逻辑", 20, DEEP_PURPLE, True) multi_text(slide, Inches(1.1), Inches(2.6), Inches(5.2), Inches(3.5), [ ("用户 A 的人格数字组合 ↔ 用户 B 的人格数字组合", 15, DARK, False), ("", 8, DARK, False), ("数字能量匹配算法", 16, DEEP_PURPLE, True), ("", 8, DARK, False), ("匹配度评分 + 合理解读", 16, GOLD, True), (" 感情匹配 | 合作匹配 | 友缘匹配", 14, GREY, False), ("", 8, DARK, False), ("基于主性格数字相生/相克 + 五区互补模型", 14, DARK, False), ("", 8, DARK, False), ("→ 匹配卡片可分享微信,天然社交裂变", 15, DEEP_PURPLE, True), ("→ 远期: 陌生人社交,把低频算命变成高频匹配互动", 15, DEEP_PURPLE, True), ]) # Right: comparison table rect(slide, Inches(7.0), Inches(1.8), Inches(5.5), Inches(4.8), LIGHT_GREY) text_box(slide, Inches(7.3), Inches(2.0), Inches(5.0), Inches(0.5), "为什么数字能量学适合做匹配", 20, DEEP_PURPLE, True) rows = [ ("传统社交 App", "我们的方案"), ("照片 + 标签 + 算法黑盒", "生辰数字 + 性格理论,有据可依"), ("\"你好\" 尴尬开场", "\"你是 5 号人?我也 5 号!\""), ("信任门槛高", "数字命理给出认识对方的框架"), ("刷到匹配即走", "持续关注运势、流年、匹配更新"), ] for i, (a, b) in enumerate(rows): y = Inches(2.7 + i * 0.72) if i == 0: text_box(slide, Inches(7.3), y, Inches(2.3), Inches(0.4), a, 12, DEEP_PURPLE, True) text_box(slide, Inches(9.6), y, Inches(2.6), Inches(0.4), b, 12, DEEP_PURPLE, True) rect(slide, Inches(7.3), y + Inches(0.35), Inches(4.8), Inches(0.02), DEEP_PURPLE) else: text_box(slide, Inches(7.3), y, Inches(2.3), Inches(0.4), a, 11, GREY, False) text_box(slide, Inches(9.6), y, Inches(2.6), Inches(0.4), b, 11, DARK, True) # ═══════════════════════════════════════════════════════ # SLIDE 5: 数字调理 + 电商 # ═══════════════════════════════════════════════════════ slide = prs.slides.add_slide(prs.slide_layouts[6]) add_bg(slide, WHITE) accent_bar(slide, Inches(0.8), Inches(0.6)) text_box(slide, Inches(0.8), Inches(0.8), Inches(10), Inches(0.7), "持续变现:数字调理 + 电商闭环", 32, DEEP_PURPLE, True) # Left: adjustment categories rect(slide, Inches(0.8), Inches(1.8), Inches(5.8), Inches(5.0), LIGHT_GREY) text_box(slide, Inches(1.1), Inches(2.0), Inches(5.2), Inches(0.5), "调理方案覆盖范围", 18, DEEP_PURPLE, True) items = [ ("命名用数", "改名/用名建议", "¥9.9-¥99"), ("号码能量", "手机号/车牌号优化", "¥9.9-¥49"), ("色彩调理", "穿搭/家居色彩方案", "¥29-¥99"), ("配饰能量", "水晶/饰品补充建议", "¥39-¥399"), ("方位建议", "朝向/城市选择", "¥49-¥199"), ("流年调理", "年度运势调整方案", "¥199-¥499"), ] for i, (name, desc, price) in enumerate(items): y = Inches(2.6 + i * 0.68) rect(slide, Inches(1.1), y, Inches(0.08), Inches(0.5), GOLD) text_box(slide, Inches(1.4), y, Inches(1.8), Inches(0.4), name, 14, DEEP_PURPLE, True) text_box(slide, Inches(3.2), y, Inches(2.0), Inches(0.4), desc, 12, GREY, False) text_box(slide, Inches(5.0), y, Inches(1.2), Inches(0.4), price, 12, GOLD, True) # Right: revenue sharing model rect(slide, Inches(7.0), Inches(1.8), Inches(5.5), Inches(5.0), LIGHT_GREY) text_box(slide, Inches(7.3), Inches(2.0), Inches(5.0), Inches(0.5), "电商运营与分成", 18, DEEP_PURPLE, True) ecom = [ ("数字产品", "平台自营", "100% 平台"), ("能量师供货", "实物商品", "平台抽佣 20-30%"), ("第三方入驻", "品牌商家", "平台抽佣 15-25%"), ("AI 推荐带货", "精准推荐", "平台抽佣 30-40%"), ] for i, (mode, detail, split) in enumerate(ecom): y = Inches(2.7 + i * 0.9) rect(slide, Inches(7.3), y, Inches(4.8), Inches(0.7), WHITE) text_box(slide, Inches(7.5), y + Inches(0.05), Inches(2.0), Inches(0.3), mode, 14, DEEP_PURPLE, True) text_box(slide, Inches(7.5), y + Inches(0.35), Inches(2.0), Inches(0.3), detail, 11, GREY, False) text_box(slide, Inches(9.8), y + Inches(0.1), Inches(2.2), Inches(0.5), split, 15, DEEP_PURPLE, True, PP_ALIGN.RIGHT) # Bottom: conversion loop text_box(slide, Inches(0.8), Inches(5.5), Inches(11), Inches(0.8), "AI 根据命盘缺失数字精准推荐 → 每人推荐不同 → 天然个性化电商 → 退货率 < 5%", 14, DARK, False, PP_ALIGN.CENTER) # ═══════════════════════════════════════════════════════ # SLIDE 6: 商业模式 # ═══════════════════════════════════════════════════════ slide = prs.slides.add_slide(prs.slide_layouts[6]) add_bg(slide, WHITE) accent_bar(slide, Inches(0.8), Inches(0.6)) text_box(slide, Inches(0.8), Inches(0.8), Inches(8), Inches(0.7), "商业模式 — 五条收入线", 32, DEEP_PURPLE, True) income = [ ("① VIP 订阅", "C 端月卡/年卡", "35%", DEEP_PURPLE), ("② 电商收入", "数字产品 + 实物抽佣", "30%", GOLD), ("③ 咨询抽佣", "每笔 20%", "15%", TEAL), ("④ 专业版年费", "B 端能量师", "10%", ORANGE), ("⑤ API 服务", "企业输出(远期)", "10%", RGBColor(0x7B, 0x1F, 0xA2)), ] for i, (name, desc, pct, color) in enumerate(income): x = Inches(0.8 + i * 2.45) y = Inches(1.9) card = rect(slide, x, y, Inches(2.15), Inches(3.5), LIGHT_GREY) rect(slide, x, y, Inches(2.15), Inches(0.08), color) text_box(slide, x + Inches(0.15), y + Inches(0.3), Inches(1.85), Inches(0.5), name, 17, color, True, PP_ALIGN.CENTER) text_box(slide, x + Inches(0.15), y + Inches(0.9), Inches(1.85), Inches(0.4), desc, 12, GREY, False, PP_ALIGN.CENTER) # Percentage circle circle(slide, x + Inches(0.5), y + Inches(1.5), Inches(1.15), color, pct, 22, WHITE) # Bottom: flywheel rect(slide, Inches(0.8), Inches(5.8), Inches(11.7), Inches(1.0), DEEP_PURPLE) text_box(slide, Inches(1.0), Inches(5.95), Inches(11.3), Inches(0.7), "增长飞轮:免费工具 → 裂变传播 → 海量用户 → 数据积累 → AI 更强 → 体验更好 → 更多用户", 16, WHITE, True, PP_ALIGN.CENTER) # ═══════════════════════════════════════════════════════ # SLIDE 7: 数据飞轮 = 护城河 # ═══════════════════════════════════════════════════════ slide = prs.slides.add_slide(prs.slide_layouts[6]) add_bg(slide, DEEP_PURPLE) circle(slide, Inches(10.5), Inches(-1), Inches(5), MEDIUM_PURPLE) circle(slide, Inches(-1), Inches(5), Inches(4), MEDIUM_PURPLE) accent_bar(slide, Inches(0.8), Inches(0.6), color=GOLD) text_box(slide, Inches(0.8), Inches(0.8), Inches(10), Inches(0.7), "数据飞轮 = 真正的护城河", 32, WHITE, True) # Center flywheel # Arrow flow in center flywheel_items = [ "更多用户", "更多命盘数据", "AI 解读更准", "体验更好", "匹配更准", "留存更高", ] for i, item in enumerate(flywheel_items): angle = i * 60 import math cx, cy = Inches(6.5), Inches(3.8) radius = Inches(2.2) rad = math.radians(angle - 90) x = cx + radius * math.cos(rad) - Inches(0.55) y = cy + radius * math.sin(rad) - Inches(0.25) shape = rect(slide, int(x), int(y), Inches(1.6), Inches(0.55), GOLD) text_box(slide, int(x), int(y), Inches(1.6), Inches(0.55), item, 12, DARK, True, PP_ALIGN.CENTER) # Center circle circle(slide, Inches(5.65), Inches(3.0), Inches(1.7), GOLD, "数据飞轮", 16, DARK) # Bottom text text_box(slide, Inches(0.8), Inches(5.5), Inches(11.5), Inches(1.2), "数据越多,壁垒越厚。\n远期可输出:企业用人测评、婚恋平台接口、营销人群画像等 B 端能力", 18, LIGHT_PURPLE, False, PP_ALIGN.CENTER) # ═══════════════════════════════════════════════════════ # SLIDE 8: 阶段规划 # ═══════════════════════════════════════════════════════ slide = prs.slides.add_slide(prs.slide_layouts[6]) add_bg(slide, WHITE) accent_bar(slide, Inches(0.8), Inches(0.6)) text_box(slide, Inches(0.8), Inches(0.8), Inches(8), Inches(0.7), "阶段规划", 32, DEEP_PURPLE, True) phases = [ ("Phase 1", "MVP 上线", "命盘 + 免费解读 + VIP 支付\n验证核心转化链路", DEEP_PURPLE), ("Phase 2", "建立飞轮", "AI 对话 + 能量师入驻\n轻量人格匹配", MEDIUM_PURPLE), ("Phase 3", "社交爆发", "陌生人匹配 + 社区\n冲击月活 10 万", GOLD), ("Phase 4", "平台化", "知识库 API + 企业服务\nB 端营收 30%", TEAL), ] for i, (phase, title, desc, color) in enumerate(phases): x = Inches(0.8 + i * 3.15) y = Inches(2.0) card = rect(slide, x, y, Inches(2.85), Inches(3.5), LIGHT_GREY) rect(slide, x, y, Inches(2.85), Inches(0.08), color) circle(slide, x + Inches(0.85), y + Inches(0.3), Inches(0.9), color, phase, 12, WHITE) text_box(slide, x + Inches(0.15), y + Inches(1.4), Inches(2.55), Inches(0.5), title, 18, color, True, PP_ALIGN.CENTER) text_box(slide, x + Inches(0.15), y + Inches(2.0), Inches(2.55), Inches(1.4), desc, 13, DARK, False, PP_ALIGN.CENTER) # ═══════════════════════════════════════════════════════ # SLIDE 9: 现状 & 行动 # ═══════════════════════════════════════════════════════ slide = prs.slides.add_slide(prs.slide_layouts[6]) add_bg(slide, DEEP_PURPLE) circle(slide, Inches(-1.5), Inches(-1.5), Inches(4.5), MEDIUM_PURPLE) circle(slide, Inches(10), Inches(4.5), Inches(5.5), MEDIUM_PURPLE) accent_bar(slide, Inches(0.8), Inches(0.6), color=GOLD) text_box(slide, Inches(0.8), Inches(0.8), Inches(10), Inches(0.7), "当前进展 & 下一步", 32, WHITE, True) text_box(slide, Inches(0.8), Inches(1.8), Inches(5.5), Inches(0.5), "已完成", 20, GOLD, True) done_items = [ "✅ 产品方向探索完成", "✅ 三角形命盘方案确认(Classic A)", "✅ 用户流程与功能分层定型", "✅ 完整商业模型设计(5 条收入线)", "✅ 投资人价值说明书就绪", ] for i, item in enumerate(done_items): text_box(slide, Inches(1.0), Inches(2.4 + i * 0.45), Inches(5.5), Inches(0.4), item, 15, WHITE, False) text_box(slide, Inches(7.5), Inches(1.8), Inches(5.0), Inches(0.5), "下一步", 20, GOLD, True) next_items = [ "▶ 技术选型最终确认", "▶ MVP 研发启动(微信小程序)", "▶ AI 模型接入与测试", "▶ 种子用户内测", "▶ 正式上线运营", ] for i, item in enumerate(next_items): text_box(slide, Inches(7.7), Inches(2.4 + i * 0.45), Inches(4.5), Inches(0.4), item, 15, WHITE, False) # Call to action rect(slide, Inches(3.5), Inches(5.3), Inches(6.3), Inches(1.0), GOLD) text_box(slide, Inches(3.7), Inches(5.45), Inches(5.9), Inches(0.7), "我们要建的不是算命工具,而是通过数字认识人、连接人的智慧平台", 16, DARK, True, PP_ALIGN.CENTER) # ═══════════════════════════════════════════════════════ # Save # ═══════════════════════════════════════════════════════ output_path = "/mnt/e/workspace/dan/num/docs/investor-deck.pptx" prs.save(output_path) print(f"PPT saved to: {output_path}") print(f"Slides: {len(prs.slides)}")