generate_ppt.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. #!/usr/bin/env python3
  2. """Generate investor pitch deck for 数字能量学智能体平台."""
  3. from pptx import Presentation
  4. from pptx.util import Inches, Pt, Emu
  5. from pptx.dml.color import RGBColor
  6. from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
  7. from pptx.enum.shapes import MSO_SHAPE
  8. import os
  9. # ── Colour palette ──
  10. DEEP_PURPLE = RGBColor(0x4A, 0x14, 0x8C) # 深紫 — 主色
  11. MEDIUM_PURPLE = RGBColor(0x7B, 0x2D, 0xC8) # 中紫
  12. LIGHT_PURPLE = RGBColor(0xE1, 0xBE, 0xF5) # 浅紫
  13. GOLD = RGBColor(0xDB, 0xB4, 0x2A) # 金色 — 强调
  14. WHITE = RGBColor(0xFF, 0xFF, 0xFF)
  15. DARK = RGBColor(0x1A, 0x1A, 0x2E)
  16. GREY = RGBColor(0x66, 0x66, 0x66)
  17. LIGHT_GREY = RGBColor(0xF3, 0xEE, 0xF9)
  18. GREEN = RGBColor(0x2E, 0x7D, 0x32)
  19. ORANGE = RGBColor(0xF5, 0x7C, 0x00)
  20. RED = RGBColor(0xC6, 0x28, 0x28)
  21. TEAL = RGBColor(0x00, 0x96, 0x88)
  22. prs = Presentation()
  23. prs.slide_width = Inches(13.333)
  24. prs.slide_height = Inches(7.5)
  25. W = prs.slide_width
  26. H = prs.slide_height
  27. def add_bg(slide, color):
  28. """Fill slide background."""
  29. bg = slide.background
  30. fill = bg.fill
  31. fill.solid()
  32. fill.fore_color.rgb = color
  33. def rect(slide, left, top, width, height, color, opacity=None):
  34. """Add a coloured rectangle."""
  35. shape = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, left, top, width, height)
  36. shape.fill.solid()
  37. shape.fill.fore_color.rgb = color
  38. shape.line.fill.background()
  39. return shape
  40. def text_box(slide, left, top, width, height, text, font_size=18,
  41. color=DARK, bold=False, alignment=PP_ALIGN.LEFT, font_name="Microsoft YaHei"):
  42. """Add a text box."""
  43. txBox = slide.shapes.add_textbox(left, top, width, height)
  44. tf = txBox.text_frame
  45. tf.word_wrap = True
  46. p = tf.paragraphs[0]
  47. p.text = text
  48. p.font.size = Pt(font_size)
  49. p.font.color.rgb = color
  50. p.font.bold = bold
  51. p.font.name = font_name
  52. p.alignment = alignment
  53. return txBox
  54. def multi_text(slide, left, top, width, height, lines, default_size=16, default_color=DARK):
  55. """Add text box with multiple formatted lines.
  56. lines = [(text, size, color, bold), ...] or just str
  57. """
  58. txBox = slide.shapes.add_textbox(left, top, width, height)
  59. tf = txBox.text_frame
  60. tf.word_wrap = True
  61. for i, line in enumerate(lines):
  62. if i == 0:
  63. p = tf.paragraphs[0]
  64. else:
  65. p = tf.add_paragraph()
  66. if isinstance(line, str):
  67. p.text = line
  68. p.font.size = Pt(default_size)
  69. p.font.color.rgb = default_color
  70. p.font.name = "Microsoft YaHei"
  71. else:
  72. text, size, color, bold = line[0], line[1], line[2], line[3] if len(line) > 3 else False
  73. p.text = text
  74. p.font.size = Pt(size)
  75. p.font.color.rgb = color
  76. p.font.bold = bold
  77. p.font.name = "Microsoft YaHei"
  78. return txBox
  79. def circle(slide, left, top, size, color, text="", font_size=12, font_color=WHITE):
  80. """Add a circle with optional centered text."""
  81. shape = slide.shapes.add_shape(MSO_SHAPE.OVAL, left, top, size, size)
  82. shape.fill.solid()
  83. shape.fill.fore_color.rgb = color
  84. shape.line.fill.background()
  85. if text:
  86. tf = shape.text_frame
  87. tf.word_wrap = True
  88. p = tf.paragraphs[0]
  89. p.text = text
  90. p.font.size = Pt(font_size)
  91. p.font.color.rgb = font_color
  92. p.font.bold = True
  93. p.font.name = "Microsoft YaHei"
  94. p.alignment = PP_ALIGN.CENTER
  95. tf.paragraphs[0].space_before = Pt(0)
  96. tf.paragraphs[0].space_after = Pt(0)
  97. return shape
  98. def accent_bar(slide, left, top, width=Inches(0.6), height=Inches(0.06), color=GOLD):
  99. return rect(slide, left, top, width, height, color)
  100. # ═══════════════════════════════════════════════════════
  101. # SLIDE 1: Cover
  102. # ═══════════════════════════════════════════════════════
  103. slide = prs.slides.add_slide(prs.slide_layouts[6]) # blank
  104. add_bg(slide, DEEP_PURPLE)
  105. # Decorative circles
  106. circle(slide, Inches(-1.5), Inches(-1.5), Inches(4), MEDIUM_PURPLE)
  107. circle(slide, Inches(10.5), Inches(4.5), Inches(5), MEDIUM_PURPLE)
  108. text_box(slide, Inches(1.5), Inches(1.8), Inches(10), Inches(1),
  109. "数字能量学智能体平台", 44, WHITE, True, PP_ALIGN.LEFT)
  110. accent_bar(slide, Inches(1.5), Inches(2.8))
  111. text_box(slide, Inches(1.5), Inches(3.1), Inches(8), Inches(0.8),
  112. "以生日为入口 · AI 为引擎 · 数字能量学为语言", 22, LIGHT_PURPLE, False, PP_ALIGN.LEFT)
  113. multi_text(slide, Inches(1.5), Inches(4.2), Inches(8), Inches(1.2), [
  114. ("帮助每个人认识自己、匹配他人", 28, WHITE, True),
  115. ("", 12, WHITE, False),
  116. ("投资方案 | 2026", 18, LIGHT_PURPLE, False),
  117. ])
  118. # ═══════════════════════════════════════════════════════
  119. # SLIDE 2: 市场机会
  120. # ═══════════════════════════════════════════════════════
  121. slide = prs.slides.add_slide(prs.slide_layouts[6])
  122. add_bg(slide, WHITE)
  123. accent_bar(slide, Inches(0.8), Inches(0.6), Inches(0.6), Inches(0.06))
  124. text_box(slide, Inches(0.8), Inches(0.8), Inches(6), Inches(0.7),
  125. "市场机会", 32, DEEP_PURPLE, True)
  126. # Market data cards
  127. data = [
  128. ("数字命理赛道已验证", "灵机文化年营收过亿\n星座/塔罗 App 千万级用户", GREEN),
  129. ("行业痛点", "仍处于\"师傅接散客\"的原始状态\n没有标准化、平台化产品", RED),
  130. ("对标", "美国 astrology.com\n月活 2000 万+,订阅制成熟", TEAL),
  131. ]
  132. for i, (title, desc, color) in enumerate(data):
  133. x = Inches(0.8 + i * 4.1)
  134. y = Inches(2.0)
  135. card = rect(slide, x, y, Inches(3.7), Inches(2.8), LIGHT_GREY)
  136. # Top color strip
  137. rect(slide, x, y, Inches(3.7), Inches(0.08), color)
  138. text_box(slide, x + Inches(0.3), y + Inches(0.4), Inches(3.2), Inches(0.5),
  139. title, 18, color, True)
  140. text_box(slide, x + Inches(0.3), y + Inches(1.1), Inches(3.2), Inches(1.5),
  141. desc, 14, DARK, False)
  142. text_box(slide, Inches(0.8), Inches(5.3), Inches(11), Inches(0.8),
  143. "我们的定位:比八字简单、比星座有据、比纯社交有深度——数字能量学的中国版 astrology.com",
  144. 16, DEEP_PURPLE, True, PP_ALIGN.LEFT)
  145. # ═══════════════════════════════════════════════════════
  146. # SLIDE 3: 三重价值引擎
  147. # ═══════════════════════════════════════════════════════
  148. slide = prs.slides.add_slide(prs.slide_layouts[6])
  149. add_bg(slide, WHITE)
  150. accent_bar(slide, Inches(0.8), Inches(0.6))
  151. text_box(slide, Inches(0.8), Inches(0.8), Inches(8), Inches(0.7),
  152. "三重价值引擎", 32, DEEP_PURPLE, True)
  153. engines = [
  154. ("🎯 大众用户", "3 秒生成命盘 + AI 解读\n人格匹配交友\n→ VIP 月卡/年卡订阅", DEEP_PURPLE),
  155. ("🔧 能量师", "客户管理 + 批量工具\n平台获客 + 线上咨询\n→ 年费 + 每单抽佣 20%", GOLD),
  156. ("🧠 平台自身", "海量命盘数据\n训练专属 AI 模型\n→ 数据壁垒 + B 端 API", TEAL),
  157. ]
  158. for i, (title, desc, color) in enumerate(engines):
  159. x = Inches(0.8 + i * 4.1)
  160. y = Inches(2.0)
  161. card = rect(slide, x, y, Inches(3.7), Inches(4.0), LIGHT_GREY)
  162. rect(slide, x, y, Inches(3.7), Inches(0.08), color)
  163. # Circle icon
  164. circle(slide, x + Inches(1.35), y + Inches(0.3), Inches(0.8), color)
  165. # Title above the circle
  166. text_box(slide, x + Inches(0.3), y + Inches(0.35), Inches(3.2), Inches(0.5),
  167. title.split(" ")[0] if " " in title else title, 11, WHITE, True, PP_ALIGN.CENTER)
  168. # Title below circle
  169. text_box(slide, x + Inches(0.3), y + Inches(1.3), Inches(3.2), Inches(0.5),
  170. title, 17, color, True, PP_ALIGN.CENTER)
  171. text_box(slide, x + Inches(0.3), y + Inches(2.0), Inches(3.2), Inches(1.8),
  172. desc, 14, DARK, False, PP_ALIGN.CENTER)
  173. # ═══════════════════════════════════════════════════════
  174. # SLIDE 4: 数字人格匹配 — 创新社交场景
  175. # ═══════════════════════════════════════════════════════
  176. slide = prs.slides.add_slide(prs.slide_layouts[6])
  177. add_bg(slide, WHITE)
  178. accent_bar(slide, Inches(0.8), Inches(0.6))
  179. text_box(slide, Inches(0.8), Inches(0.8), Inches(10), Inches(0.7),
  180. "最大的创新:数字人格匹配 → 陌生交友", 32, DEEP_PURPLE, True)
  181. # Left: matching logic
  182. rect(slide, Inches(0.8), Inches(1.8), Inches(5.8), Inches(4.8), LIGHT_GREY)
  183. text_box(slide, Inches(1.1), Inches(2.0), Inches(5.2), Inches(0.5),
  184. "匹配逻辑", 20, DEEP_PURPLE, True)
  185. multi_text(slide, Inches(1.1), Inches(2.6), Inches(5.2), Inches(3.5), [
  186. ("用户 A 的人格数字组合 ↔ 用户 B 的人格数字组合", 15, DARK, False),
  187. ("", 8, DARK, False),
  188. ("数字能量匹配算法", 16, DEEP_PURPLE, True),
  189. ("", 8, DARK, False),
  190. ("匹配度评分 + 合理解读", 16, GOLD, True),
  191. (" 感情匹配 | 合作匹配 | 友缘匹配", 14, GREY, False),
  192. ("", 8, DARK, False),
  193. ("基于主性格数字相生/相克 + 五区互补模型", 14, DARK, False),
  194. ("", 8, DARK, False),
  195. ("→ 匹配卡片可分享微信,天然社交裂变", 15, DEEP_PURPLE, True),
  196. ("→ 远期: 陌生人社交,把低频算命变成高频匹配互动", 15, DEEP_PURPLE, True),
  197. ])
  198. # Right: comparison table
  199. rect(slide, Inches(7.0), Inches(1.8), Inches(5.5), Inches(4.8), LIGHT_GREY)
  200. text_box(slide, Inches(7.3), Inches(2.0), Inches(5.0), Inches(0.5),
  201. "为什么数字能量学适合做匹配", 20, DEEP_PURPLE, True)
  202. rows = [
  203. ("传统社交 App", "我们的方案"),
  204. ("照片 + 标签 + 算法黑盒", "生辰数字 + 性格理论,有据可依"),
  205. ("\"你好\" 尴尬开场", "\"你是 5 号人?我也 5 号!\""),
  206. ("信任门槛高", "数字命理给出认识对方的框架"),
  207. ("刷到匹配即走", "持续关注运势、流年、匹配更新"),
  208. ]
  209. for i, (a, b) in enumerate(rows):
  210. y = Inches(2.7 + i * 0.72)
  211. if i == 0:
  212. text_box(slide, Inches(7.3), y, Inches(2.3), Inches(0.4),
  213. a, 12, DEEP_PURPLE, True)
  214. text_box(slide, Inches(9.6), y, Inches(2.6), Inches(0.4),
  215. b, 12, DEEP_PURPLE, True)
  216. rect(slide, Inches(7.3), y + Inches(0.35), Inches(4.8), Inches(0.02), DEEP_PURPLE)
  217. else:
  218. text_box(slide, Inches(7.3), y, Inches(2.3), Inches(0.4),
  219. a, 11, GREY, False)
  220. text_box(slide, Inches(9.6), y, Inches(2.6), Inches(0.4),
  221. b, 11, DARK, True)
  222. # ═══════════════════════════════════════════════════════
  223. # SLIDE 5: 数字调理 + 电商
  224. # ═══════════════════════════════════════════════════════
  225. slide = prs.slides.add_slide(prs.slide_layouts[6])
  226. add_bg(slide, WHITE)
  227. accent_bar(slide, Inches(0.8), Inches(0.6))
  228. text_box(slide, Inches(0.8), Inches(0.8), Inches(10), Inches(0.7),
  229. "持续变现:数字调理 + 电商闭环", 32, DEEP_PURPLE, True)
  230. # Left: adjustment categories
  231. rect(slide, Inches(0.8), Inches(1.8), Inches(5.8), Inches(5.0), LIGHT_GREY)
  232. text_box(slide, Inches(1.1), Inches(2.0), Inches(5.2), Inches(0.5),
  233. "调理方案覆盖范围", 18, DEEP_PURPLE, True)
  234. items = [
  235. ("命名用数", "改名/用名建议", "¥9.9-¥99"),
  236. ("号码能量", "手机号/车牌号优化", "¥9.9-¥49"),
  237. ("色彩调理", "穿搭/家居色彩方案", "¥29-¥99"),
  238. ("配饰能量", "水晶/饰品补充建议", "¥39-¥399"),
  239. ("方位建议", "朝向/城市选择", "¥49-¥199"),
  240. ("流年调理", "年度运势调整方案", "¥199-¥499"),
  241. ]
  242. for i, (name, desc, price) in enumerate(items):
  243. y = Inches(2.6 + i * 0.68)
  244. rect(slide, Inches(1.1), y, Inches(0.08), Inches(0.5), GOLD)
  245. text_box(slide, Inches(1.4), y, Inches(1.8), Inches(0.4),
  246. name, 14, DEEP_PURPLE, True)
  247. text_box(slide, Inches(3.2), y, Inches(2.0), Inches(0.4),
  248. desc, 12, GREY, False)
  249. text_box(slide, Inches(5.0), y, Inches(1.2), Inches(0.4),
  250. price, 12, GOLD, True)
  251. # Right: revenue sharing model
  252. rect(slide, Inches(7.0), Inches(1.8), Inches(5.5), Inches(5.0), LIGHT_GREY)
  253. text_box(slide, Inches(7.3), Inches(2.0), Inches(5.0), Inches(0.5),
  254. "电商运营与分成", 18, DEEP_PURPLE, True)
  255. ecom = [
  256. ("数字产品", "平台自营", "100% 平台"),
  257. ("能量师供货", "实物商品", "平台抽佣 20-30%"),
  258. ("第三方入驻", "品牌商家", "平台抽佣 15-25%"),
  259. ("AI 推荐带货", "精准推荐", "平台抽佣 30-40%"),
  260. ]
  261. for i, (mode, detail, split) in enumerate(ecom):
  262. y = Inches(2.7 + i * 0.9)
  263. rect(slide, Inches(7.3), y, Inches(4.8), Inches(0.7), WHITE)
  264. text_box(slide, Inches(7.5), y + Inches(0.05), Inches(2.0), Inches(0.3),
  265. mode, 14, DEEP_PURPLE, True)
  266. text_box(slide, Inches(7.5), y + Inches(0.35), Inches(2.0), Inches(0.3),
  267. detail, 11, GREY, False)
  268. text_box(slide, Inches(9.8), y + Inches(0.1), Inches(2.2), Inches(0.5),
  269. split, 15, DEEP_PURPLE, True, PP_ALIGN.RIGHT)
  270. # Bottom: conversion loop
  271. text_box(slide, Inches(0.8), Inches(5.5), Inches(11), Inches(0.8),
  272. "AI 根据命盘缺失数字精准推荐 → 每人推荐不同 → 天然个性化电商 → 退货率 < 5%",
  273. 14, DARK, False, PP_ALIGN.CENTER)
  274. # ═══════════════════════════════════════════════════════
  275. # SLIDE 6: 商业模式
  276. # ═══════════════════════════════════════════════════════
  277. slide = prs.slides.add_slide(prs.slide_layouts[6])
  278. add_bg(slide, WHITE)
  279. accent_bar(slide, Inches(0.8), Inches(0.6))
  280. text_box(slide, Inches(0.8), Inches(0.8), Inches(8), Inches(0.7),
  281. "商业模式 — 五条收入线", 32, DEEP_PURPLE, True)
  282. income = [
  283. ("① VIP 订阅", "C 端月卡/年卡", "35%", DEEP_PURPLE),
  284. ("② 电商收入", "数字产品 + 实物抽佣", "30%", GOLD),
  285. ("③ 咨询抽佣", "每笔 20%", "15%", TEAL),
  286. ("④ 专业版年费", "B 端能量师", "10%", ORANGE),
  287. ("⑤ API 服务", "企业输出(远期)", "10%", RGBColor(0x7B, 0x1F, 0xA2)),
  288. ]
  289. for i, (name, desc, pct, color) in enumerate(income):
  290. x = Inches(0.8 + i * 2.45)
  291. y = Inches(1.9)
  292. card = rect(slide, x, y, Inches(2.15), Inches(3.5), LIGHT_GREY)
  293. rect(slide, x, y, Inches(2.15), Inches(0.08), color)
  294. text_box(slide, x + Inches(0.15), y + Inches(0.3), Inches(1.85), Inches(0.5),
  295. name, 17, color, True, PP_ALIGN.CENTER)
  296. text_box(slide, x + Inches(0.15), y + Inches(0.9), Inches(1.85), Inches(0.4),
  297. desc, 12, GREY, False, PP_ALIGN.CENTER)
  298. # Percentage circle
  299. circle(slide, x + Inches(0.5), y + Inches(1.5), Inches(1.15), color,
  300. pct, 22, WHITE)
  301. # Bottom: flywheel
  302. rect(slide, Inches(0.8), Inches(5.8), Inches(11.7), Inches(1.0), DEEP_PURPLE)
  303. text_box(slide, Inches(1.0), Inches(5.95), Inches(11.3), Inches(0.7),
  304. "增长飞轮:免费工具 → 裂变传播 → 海量用户 → 数据积累 → AI 更强 → 体验更好 → 更多用户",
  305. 16, WHITE, True, PP_ALIGN.CENTER)
  306. # ═══════════════════════════════════════════════════════
  307. # SLIDE 7: 数据飞轮 = 护城河
  308. # ═══════════════════════════════════════════════════════
  309. slide = prs.slides.add_slide(prs.slide_layouts[6])
  310. add_bg(slide, DEEP_PURPLE)
  311. circle(slide, Inches(10.5), Inches(-1), Inches(5), MEDIUM_PURPLE)
  312. circle(slide, Inches(-1), Inches(5), Inches(4), MEDIUM_PURPLE)
  313. accent_bar(slide, Inches(0.8), Inches(0.6), color=GOLD)
  314. text_box(slide, Inches(0.8), Inches(0.8), Inches(10), Inches(0.7),
  315. "数据飞轮 = 真正的护城河", 32, WHITE, True)
  316. # Center flywheel
  317. # Arrow flow in center
  318. flywheel_items = [
  319. "更多用户",
  320. "更多命盘数据",
  321. "AI 解读更准",
  322. "体验更好",
  323. "匹配更准",
  324. "留存更高",
  325. ]
  326. for i, item in enumerate(flywheel_items):
  327. angle = i * 60
  328. import math
  329. cx, cy = Inches(6.5), Inches(3.8)
  330. radius = Inches(2.2)
  331. rad = math.radians(angle - 90)
  332. x = cx + radius * math.cos(rad) - Inches(0.55)
  333. y = cy + radius * math.sin(rad) - Inches(0.25)
  334. shape = rect(slide, int(x), int(y), Inches(1.6), Inches(0.55), GOLD)
  335. text_box(slide, int(x), int(y), Inches(1.6), Inches(0.55),
  336. item, 12, DARK, True, PP_ALIGN.CENTER)
  337. # Center circle
  338. circle(slide, Inches(5.65), Inches(3.0), Inches(1.7), GOLD, "数据飞轮", 16, DARK)
  339. # Bottom text
  340. text_box(slide, Inches(0.8), Inches(5.5), Inches(11.5), Inches(1.2),
  341. "数据越多,壁垒越厚。\n远期可输出:企业用人测评、婚恋平台接口、营销人群画像等 B 端能力",
  342. 18, LIGHT_PURPLE, False, PP_ALIGN.CENTER)
  343. # ═══════════════════════════════════════════════════════
  344. # SLIDE 8: 阶段规划
  345. # ═══════════════════════════════════════════════════════
  346. slide = prs.slides.add_slide(prs.slide_layouts[6])
  347. add_bg(slide, WHITE)
  348. accent_bar(slide, Inches(0.8), Inches(0.6))
  349. text_box(slide, Inches(0.8), Inches(0.8), Inches(8), Inches(0.7),
  350. "阶段规划", 32, DEEP_PURPLE, True)
  351. phases = [
  352. ("Phase 1", "MVP 上线", "命盘 + 免费解读 + VIP 支付\n验证核心转化链路", DEEP_PURPLE),
  353. ("Phase 2", "建立飞轮", "AI 对话 + 能量师入驻\n轻量人格匹配", MEDIUM_PURPLE),
  354. ("Phase 3", "社交爆发", "陌生人匹配 + 社区\n冲击月活 10 万", GOLD),
  355. ("Phase 4", "平台化", "知识库 API + 企业服务\nB 端营收 30%", TEAL),
  356. ]
  357. for i, (phase, title, desc, color) in enumerate(phases):
  358. x = Inches(0.8 + i * 3.15)
  359. y = Inches(2.0)
  360. card = rect(slide, x, y, Inches(2.85), Inches(3.5), LIGHT_GREY)
  361. rect(slide, x, y, Inches(2.85), Inches(0.08), color)
  362. circle(slide, x + Inches(0.85), y + Inches(0.3), Inches(0.9), color, phase, 12, WHITE)
  363. text_box(slide, x + Inches(0.15), y + Inches(1.4), Inches(2.55), Inches(0.5),
  364. title, 18, color, True, PP_ALIGN.CENTER)
  365. text_box(slide, x + Inches(0.15), y + Inches(2.0), Inches(2.55), Inches(1.4),
  366. desc, 13, DARK, False, PP_ALIGN.CENTER)
  367. # ═══════════════════════════════════════════════════════
  368. # SLIDE 9: 现状 & 行动
  369. # ═══════════════════════════════════════════════════════
  370. slide = prs.slides.add_slide(prs.slide_layouts[6])
  371. add_bg(slide, DEEP_PURPLE)
  372. circle(slide, Inches(-1.5), Inches(-1.5), Inches(4.5), MEDIUM_PURPLE)
  373. circle(slide, Inches(10), Inches(4.5), Inches(5.5), MEDIUM_PURPLE)
  374. accent_bar(slide, Inches(0.8), Inches(0.6), color=GOLD)
  375. text_box(slide, Inches(0.8), Inches(0.8), Inches(10), Inches(0.7),
  376. "当前进展 & 下一步", 32, WHITE, True)
  377. text_box(slide, Inches(0.8), Inches(1.8), Inches(5.5), Inches(0.5),
  378. "已完成", 20, GOLD, True)
  379. done_items = [
  380. "✅ 产品方向探索完成",
  381. "✅ 三角形命盘方案确认(Classic A)",
  382. "✅ 用户流程与功能分层定型",
  383. "✅ 完整商业模型设计(5 条收入线)",
  384. "✅ 投资人价值说明书就绪",
  385. ]
  386. for i, item in enumerate(done_items):
  387. text_box(slide, Inches(1.0), Inches(2.4 + i * 0.45), Inches(5.5), Inches(0.4),
  388. item, 15, WHITE, False)
  389. text_box(slide, Inches(7.5), Inches(1.8), Inches(5.0), Inches(0.5),
  390. "下一步", 20, GOLD, True)
  391. next_items = [
  392. "▶ 技术选型最终确认",
  393. "▶ MVP 研发启动(微信小程序)",
  394. "▶ AI 模型接入与测试",
  395. "▶ 种子用户内测",
  396. "▶ 正式上线运营",
  397. ]
  398. for i, item in enumerate(next_items):
  399. text_box(slide, Inches(7.7), Inches(2.4 + i * 0.45), Inches(4.5), Inches(0.4),
  400. item, 15, WHITE, False)
  401. # Call to action
  402. rect(slide, Inches(3.5), Inches(5.3), Inches(6.3), Inches(1.0), GOLD)
  403. text_box(slide, Inches(3.7), Inches(5.45), Inches(5.9), Inches(0.7),
  404. "我们要建的不是算命工具,而是通过数字认识人、连接人的智慧平台",
  405. 16, DARK, True, PP_ALIGN.CENTER)
  406. # ═══════════════════════════════════════════════════════
  407. # Save
  408. # ═══════════════════════════════════════════════════════
  409. output_path = "/mnt/e/workspace/dan/num/docs/investor-deck.pptx"
  410. prs.save(output_path)
  411. print(f"PPT saved to: {output_path}")
  412. print(f"Slides: {len(prs.slides)}")