generate_aidop_sales_ppt.py 98 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728
  1. #!/usr/bin/env python3
  2. """Generate the Henan Industrial Internet manufacturing operations platform deck."""
  3. from __future__ import annotations
  4. import base64
  5. import re
  6. from io import BytesIO
  7. from pathlib import Path
  8. from PIL import Image
  9. from pptx import Presentation
  10. from pptx.dml.color import RGBColor
  11. from pptx.enum.dml import MSO_LINE_DASH_STYLE
  12. from pptx.enum.shapes import MSO_AUTO_SHAPE_TYPE, MSO_CONNECTOR
  13. from pptx.enum.text import MSO_ANCHOR, PP_ALIGN
  14. from pptx.util import Inches, Pt
  15. ROOT = Path(__file__).resolve().parents[1]
  16. SYSTEM_NAME = "河南产互联制造业数据智能运营平台"
  17. OUTPUT = ROOT / "doc" / f"{SYSTEM_NAME}_系统介绍.pptx"
  18. LOGO_SVG = ROOT / "Web" / "src" / "assets" / "logo-mini.svg"
  19. DASHBOARD_SHOTS = ROOT / "doc" / "plan" / "UAT留证" / "2026-08-15-S2-S7看板刷新重算统一架构" / "screenshots"
  20. FLOW_SHOTS = ROOT / "doc" / "plan" / "UAT留证" / "2026-08-09-S1起真人测试" / "screenshots"
  21. IQC_SHOTS = ROOT / "doc" / "plan" / "UAT留证" / "2026-08-11-IQC-P0取证" / "screenshots"
  22. SYSTEM_SHOTS = ROOT / "doc" / "ppt-assets" / "system-screenshots"
  23. BID_SHOTS = ROOT / "doc" / "_bid_assets"
  24. W = 13.333
  25. H = 7.5
  26. FONT = "Microsoft YaHei"
  27. NAVY = RGBColor(11, 31, 58)
  28. BLUE = RGBColor(35, 105, 190)
  29. CYAN = RGBColor(21, 151, 166)
  30. TEAL = RGBColor(21, 132, 119)
  31. AMBER = RGBColor(226, 155, 45)
  32. RED = RGBColor(196, 65, 79)
  33. GREEN = RGBColor(55, 145, 91)
  34. WHITE = RGBColor(255, 255, 255)
  35. INK = RGBColor(35, 47, 62)
  36. MUTED = RGBColor(98, 111, 126)
  37. LIGHT = RGBColor(244, 247, 250)
  38. PALE_BLUE = RGBColor(231, 240, 250)
  39. PALE_TEAL = RGBColor(230, 244, 242)
  40. PALE_AMBER = RGBColor(250, 241, 221)
  41. PALE_RED = RGBColor(250, 232, 235)
  42. LINE = RGBColor(213, 221, 230)
  43. def logo_stream() -> BytesIO | None:
  44. if not LOGO_SVG.exists():
  45. return None
  46. raw = LOGO_SVG.read_text(encoding="utf-8")
  47. match = re.search(r"base64,([^\"']+)", raw, re.S)
  48. if not match:
  49. return None
  50. return BytesIO(base64.b64decode(re.sub(r"\s+", "", match.group(1))))
  51. def add_rect(slide, x, y, w, h, fill=WHITE, line=None, radius=True):
  52. kind = MSO_AUTO_SHAPE_TYPE.ROUNDED_RECTANGLE if radius else MSO_AUTO_SHAPE_TYPE.RECTANGLE
  53. shp = slide.shapes.add_shape(kind, Inches(x), Inches(y), Inches(w), Inches(h))
  54. shp.fill.solid()
  55. shp.fill.fore_color.rgb = fill
  56. shp.line.color.rgb = line or fill
  57. return shp
  58. def add_text(
  59. slide,
  60. text,
  61. x,
  62. y,
  63. w,
  64. h,
  65. size=18,
  66. color=INK,
  67. bold=False,
  68. align=PP_ALIGN.LEFT,
  69. valign=MSO_ANCHOR.TOP,
  70. margin=0.04,
  71. ):
  72. box = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
  73. tf = box.text_frame
  74. tf.clear()
  75. tf.word_wrap = True
  76. tf.margin_left = Inches(margin)
  77. tf.margin_right = Inches(margin)
  78. tf.margin_top = Inches(margin)
  79. tf.margin_bottom = Inches(margin)
  80. tf.vertical_anchor = valign
  81. p = tf.paragraphs[0]
  82. p.alignment = align
  83. run = p.add_run()
  84. run.text = text
  85. run.font.name = FONT
  86. run.font.size = Pt(size)
  87. run.font.bold = bold
  88. run.font.color.rgb = color
  89. return box
  90. def add_bullets(slide, items, x, y, w, h, size=16, color=INK, spacing=8, accent=CYAN):
  91. box = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
  92. tf = box.text_frame
  93. tf.clear()
  94. tf.word_wrap = True
  95. tf.margin_left = Inches(0.02)
  96. tf.margin_right = Inches(0.02)
  97. tf.margin_top = Inches(0.02)
  98. tf.margin_bottom = Inches(0.02)
  99. for i, item in enumerate(items):
  100. p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
  101. p.space_after = Pt(spacing)
  102. p.level = 0
  103. p.text = f"● {item}"
  104. p.font.name = FONT
  105. p.font.size = Pt(size)
  106. p.font.color.rgb = color
  107. for run in p.runs:
  108. run.font.name = FONT
  109. run.font.size = Pt(size)
  110. run.font.color.rgb = color
  111. if p.runs:
  112. p.runs[0].font.color.rgb = accent
  113. return box
  114. def add_notes(slide, text):
  115. slide.notes_slide.notes_text_frame.text = text
  116. def add_brand(slide, dark=False):
  117. add_text(slide, SYSTEM_NAME, 0.48, 0.26, 4.7, 0.34, 11, WHITE if dark else NAVY, True)
  118. def add_footer(slide, page, source=None, dark=False):
  119. color = RGBColor(190, 202, 214) if dark else MUTED
  120. add_text(slide, SYSTEM_NAME, 0.48, 7.12, 4.8, 0.2, 8, color)
  121. if source:
  122. add_text(slide, source, 4.1, 7.12, 8.2, 0.2, 7, color, align=PP_ALIGN.RIGHT)
  123. add_text(slide, f"{page:02d}", 12.45, 7.08, 0.42, 0.25, 9, color, True, PP_ALIGN.RIGHT)
  124. def base_slide(prs, title, page, subtitle=None, dark=False, source=None):
  125. slide = prs.slides.add_slide(prs.slide_layouts[6])
  126. bg = slide.background.fill
  127. bg.solid()
  128. bg.fore_color.rgb = NAVY if dark else WHITE
  129. add_brand(slide, dark=dark)
  130. add_text(slide, title, 0.48, 0.78, 12.2, 0.62, 25, WHITE if dark else NAVY, True)
  131. if subtitle:
  132. add_text(slide, subtitle, 0.5, 1.39, 12.0, 0.38, 12, RGBColor(206, 218, 231) if dark else MUTED)
  133. add_footer(slide, page, source=source, dark=dark)
  134. return slide
  135. def section_slide(prs, number, title, subtitle, page):
  136. slide = prs.slides.add_slide(prs.slide_layouts[6])
  137. slide.background.fill.solid()
  138. slide.background.fill.fore_color.rgb = NAVY
  139. add_brand(slide, dark=True)
  140. add_text(slide, number, 0.58, 1.55, 2.0, 1.2, 56, CYAN, True)
  141. add_text(slide, title, 2.0, 1.65, 10.3, 0.9, 31, WHITE, True)
  142. add_rect(slide, 2.02, 2.72, 1.2, 0.06, CYAN, CYAN, False)
  143. add_text(slide, subtitle, 2.02, 3.05, 9.8, 1.1, 18, RGBColor(206, 218, 231))
  144. add_footer(slide, page, dark=True)
  145. return slide
  146. def add_pill(slide, text, x, y, w, color=CYAN, text_color=WHITE, size=11):
  147. add_rect(slide, x, y, w, 0.36, color, color)
  148. add_text(slide, text, x + 0.05, y + 0.02, w - 0.1, 0.3, size, text_color, True, PP_ALIGN.CENTER, MSO_ANCHOR.MIDDLE)
  149. def card(slide, title, body, x, y, w, h, accent=CYAN, number=None):
  150. add_rect(slide, x, y, w, h, LIGHT, LINE)
  151. if number is not None:
  152. add_text(slide, str(number), x + 0.18, y + 0.15, 0.5, 0.38, 18, accent, True)
  153. tx = x + 0.72
  154. tw = w - 0.9
  155. else:
  156. add_rect(slide, x + 0.18, y + 0.2, 0.07, 0.42, accent, accent, False)
  157. tx = x + 0.38
  158. tw = w - 0.58
  159. add_text(slide, title, tx, y + 0.13, tw, 0.48, 16, NAVY, True)
  160. add_text(slide, body, x + 0.22, y + 0.72, w - 0.44, h - 0.84, 11.5, MUTED)
  161. def flow(slide, steps, y=3.0, x0=0.65, width=12.0, colors=None, font_size=12):
  162. gap = 0.13
  163. n = len(steps)
  164. step_w = (width - gap * (n - 1)) / n
  165. for i, step in enumerate(steps):
  166. color = (colors or [CYAN, BLUE, TEAL, AMBER])[i % len(colors or [CYAN, BLUE, TEAL, AMBER])]
  167. x = x0 + i * (step_w + gap)
  168. add_rect(slide, x, y, step_w, 0.82, color, color)
  169. add_text(slide, step, x + 0.06, y + 0.08, step_w - 0.12, 0.62, font_size, WHITE, True, PP_ALIGN.CENTER, MSO_ANCHOR.MIDDLE)
  170. if i < n - 1:
  171. add_text(slide, "›", x + step_w - 0.02, y + 0.21, 0.18, 0.34, 18, WHITE, True, PP_ALIGN.CENTER)
  172. def add_image_contain(slide, path, x, y, w, h):
  173. add_rect(slide, x, y, w, h, LIGHT, LINE, False)
  174. with Image.open(path) as image:
  175. ratio = image.width / image.height
  176. box_ratio = w / h
  177. if ratio >= box_ratio:
  178. pw = w - 0.08
  179. ph = pw / ratio
  180. else:
  181. ph = h - 0.08
  182. pw = ph * ratio
  183. px = x + (w - pw) / 2
  184. py = y + (h - ph) / 2
  185. slide.shapes.add_picture(str(path), Inches(px), Inches(py), Inches(pw), Inches(ph))
  186. def screenshot_pair_slide(prs, page, title, subtitle, left, left_caption, right, right_caption, source=None):
  187. slide = base_slide(prs, title, page, subtitle, source=source)
  188. add_image_contain(slide, left, 0.62, 1.82, 6.0, 4.42)
  189. add_image_contain(slide, right, 6.72, 1.82, 6.0, 4.42)
  190. add_pill(slide, left_caption, 1.12, 6.38, 5.0, NAVY, WHITE, 11)
  191. add_pill(slide, right_caption, 7.22, 6.38, 5.0, CYAN, WHITE, 11)
  192. return slide
  193. def screenshot_quad_slide(prs, page, title, subtitle, items, source=None):
  194. """Show four real product screens on one overview slide."""
  195. slide = base_slide(prs, title, page, subtitle, source=source)
  196. positions = [(0.58, 1.72), (6.78, 1.72), (0.58, 4.18), (6.78, 4.18)]
  197. accents = [NAVY, BLUE, CYAN, TEAL]
  198. for i, ((image, caption), (x, y)) in enumerate(zip(items, positions)):
  199. add_image_contain(slide, image, x, y, 5.97, 1.96)
  200. add_pill(slide, caption, x + 0.62, y + 1.68, 4.73, accents[i], WHITE, 10.5)
  201. return slide
  202. def module_slide(prs, page, code, name, tagline, capabilities, values, example, accent):
  203. slide = base_slide(prs, f"{code}|{name}", page, tagline)
  204. add_pill(slide, "核心能力", 0.58, 1.85, 1.25, accent)
  205. add_pill(slide, "客户价值", 6.95, 1.85, 1.25, NAVY)
  206. add_rect(slide, 0.58, 2.35, 5.95, 3.65, LIGHT, LINE)
  207. add_bullets(slide, capabilities, 0.9, 2.7, 5.25, 2.95, 15, accent=accent)
  208. add_rect(slide, 6.8, 2.35, 5.95, 3.65, PALE_BLUE, LINE)
  209. add_bullets(slide, values, 7.12, 2.7, 5.25, 2.95, 15, accent=NAVY)
  210. add_rect(slide, 0.58, 6.2, 12.17, 0.62, WHITE, accent)
  211. add_text(slide, "销售场景", 0.82, 6.34, 1.0, 0.24, 11, accent, True)
  212. add_text(slide, example, 1.85, 6.28, 10.55, 0.36, 12, INK)
  213. add_notes(slide, f"{name}:{tagline}。销售讲解时先讲场景,再选择 2–3 个功能点展开,不需要逐项念菜单。")
  214. return slide
  215. def scenario_value_slide(prs, page, title, values, accent=TEAL):
  216. slide = base_slide(prs, title, page, "把功能翻译成客户能感知、能量化的业务结果")
  217. for i, (head, body) in enumerate(values):
  218. x = 0.72 + (i % 2) * 6.22
  219. y = 1.95 + (i // 2) * 2.15
  220. card(slide, head, body, x, y, 5.65, 1.72, accent, i + 1)
  221. return slide
  222. def scenario_background_slide(prs, page, title, context, traditional, roles, accent=AMBER):
  223. slide = base_slide(prs, title, page, "先让客户代入日常工作,再展示系统如何改变协同方式")
  224. add_pill(slide, "业务背景", 0.62, 1.85, 1.25, accent)
  225. add_rect(slide, 0.62, 2.32, 5.85, 3.7, LIGHT, LINE)
  226. add_bullets(slide, context, 0.92, 2.72, 5.22, 2.9, 15, accent=accent)
  227. add_pill(slide, "传统方式的卡点", 6.86, 1.85, 1.75, RED)
  228. add_rect(slide, 6.72, 2.32, 6.0, 3.7, PALE_RED, LINE)
  229. add_bullets(slide, traditional, 7.05, 2.72, 5.3, 2.9, 15, accent=RED)
  230. add_text(slide, "涉及角色", 0.72, 6.33, 0.85, 0.28, 10, MUTED, True)
  231. x = 1.65
  232. for role in roles:
  233. w = max(0.82, 0.22 + len(role) * 0.19)
  234. add_pill(slide, role, x, 6.28, w, NAVY, WHITE, 10)
  235. x += w + 0.12
  236. return slide
  237. def scenario_flow_slide(prs, page, title, steps, capabilities, result, accent=CYAN):
  238. slide = base_slide(prs, title, page, "让上一步的业务结果成为下一步的输入")
  239. flow(slide, steps, 2.05, 0.58, 12.2, [accent, BLUE, TEAL, AMBER], 10.5)
  240. add_rect(slide, 0.72, 3.45, 7.8, 2.5, LIGHT, LINE)
  241. add_text(slide, "平台在其中做什么", 1.02, 3.72, 3.2, 0.42, 16, NAVY, True)
  242. add_bullets(slide, capabilities, 1.0, 4.22, 7.08, 1.45, 13.5, accent=accent)
  243. add_rect(slide, 8.82, 3.45, 3.9, 2.5, PALE_TEAL, accent)
  244. add_text(slide, "业务结果", 9.12, 3.72, 2.2, 0.42, 16, accent, True)
  245. add_text(slide, result, 9.12, 4.28, 3.28, 1.25, 17, NAVY, True, PP_ALIGN.CENTER, MSO_ANCHOR.MIDDLE)
  246. return slide
  247. def add_metric(slide, value, label, x, y, w, accent=CYAN, note=None):
  248. add_rect(slide, x, y, w, 1.42, LIGHT, LINE)
  249. add_text(slide, value, x + 0.12, y + 0.16, w - 0.24, 0.58, 29, accent, True, PP_ALIGN.CENTER)
  250. add_text(slide, label, x + 0.12, y + 0.82, w - 0.24, 0.28, 11, NAVY, True, PP_ALIGN.CENTER)
  251. if note:
  252. add_text(slide, note, x + 0.12, y + 1.12, w - 0.24, 0.2, 8, MUTED, align=PP_ALIGN.CENTER)
  253. def screenshot_feature_slide(
  254. prs,
  255. page,
  256. title,
  257. subtitle,
  258. image,
  259. capability_title,
  260. capabilities,
  261. value_title,
  262. values,
  263. accent=CYAN,
  264. source=None,
  265. ):
  266. """One-page feature introduction led by a real system screenshot."""
  267. slide = base_slide(prs, title, page, subtitle, source=source)
  268. add_image_contain(slide, image, 0.55, 1.78, 7.35, 4.92)
  269. add_pill(slide, capability_title, 8.18, 1.82, 1.65, accent)
  270. add_bullets(slide, capabilities, 8.18, 2.35, 4.45, 1.62, 12.5, spacing=5, accent=accent)
  271. add_pill(slide, value_title, 8.18, 4.22, 1.42, NAVY)
  272. add_bullets(slide, values, 8.18, 4.74, 4.45, 1.58, 12.5, spacing=5, accent=NAVY)
  273. return slide
  274. def scenario_case_slide(
  275. prs,
  276. page,
  277. title,
  278. subtitle,
  279. image,
  280. problem,
  281. steps,
  282. values,
  283. accent=CYAN,
  284. source=None,
  285. ):
  286. """Combine scenario background, process, screenshot and value on one slide."""
  287. slide = base_slide(prs, title, page, subtitle, source=source)
  288. add_image_contain(slide, image, 0.55, 1.8, 7.15, 4.78)
  289. add_pill(slide, "业务问题", 7.98, 1.82, 1.28, RED)
  290. add_text(slide, problem, 7.98, 2.32, 4.55, 0.78, 12.5, INK, True)
  291. add_pill(slide, "平台闭环", 7.98, 3.25, 1.28, accent)
  292. add_bullets(slide, steps, 7.98, 3.75, 4.55, 1.32, 11.5, spacing=4, accent=accent)
  293. add_pill(slide, "客户价值", 7.98, 5.18, 1.28, NAVY)
  294. add_text(slide, " · ".join(values), 7.98, 5.68, 4.55, 0.68, 12.5, NAVY, True)
  295. return slide
  296. def build():
  297. prs = Presentation()
  298. prs.slide_width = Inches(W)
  299. prs.slide_height = Inches(H)
  300. prs.core_properties.title = f"{SYSTEM_NAME}系统业务价值介绍(销售完整版)"
  301. prs.core_properties.subject = "面向销售、售前与非技术客户的业务介绍"
  302. prs.core_properties.author = SYSTEM_NAME
  303. prs.core_properties.comments = f"{SYSTEM_NAME}制造运营协同与智慧改善业务介绍"
  304. page = 1
  305. # 01 Cover
  306. slide = prs.slides.add_slide(prs.slide_layouts[6])
  307. slide.background.fill.solid()
  308. slide.background.fill.fore_color.rgb = NAVY
  309. add_brand(slide, dark=True)
  310. add_pill(slide, "销售完整版", 0.62, 1.25, 1.35, CYAN)
  311. add_text(slide, SYSTEM_NAME, 0.62, 2.05, 11.4, 0.85, 30, WHITE, True)
  312. add_text(slide, "制造运营协同与智慧改善平台", 0.62, 2.85, 10.8, 0.8, 29, WHITE, True)
  313. add_text(slide, "让订单、计划、供应、生产、质量与交付在同一条运营链上协同", 0.65, 3.86, 10.8, 0.55, 18, RGBColor(204, 219, 234))
  314. add_rect(slide, 0.65, 4.72, 5.95, 0.06, CYAN, CYAN, False)
  315. add_text(slide, "从发现问题,到推动问题解决", 0.65, 5.12, 7.0, 0.55, 20, CYAN, True)
  316. add_text(slide, "面向销售、售前与业务推广人员", 0.65, 6.28, 4.5, 0.3, 11, RGBColor(190, 202, 214))
  317. add_footer(slide, page, dark=True)
  318. add_notes(slide, f"开场不要先讲模块。先说明:{SYSTEM_NAME}解决的不是单点信息化,而是工厂跨部门运营协同和持续改善。")
  319. page += 1
  320. # 02 Pain points
  321. slide = base_slide(prs, "制造企业真正难的,不是“没有系统”", page, "系统很多,但业务仍然靠人把信息串起来")
  322. pains = [
  323. ("信息分散", "订单、计划、采购、仓库、生产、质量各自有数据,管理者看到的却不是同一条业务链。"),
  324. ("风险发现太晚", "缺料、延期、质量和设备问题往往到现场或客户催单时才被发现。"),
  325. ("协同依赖人工", "会议、电话、群聊和 Excel 承担跨部门协调,优先级与责任边界不清。"),
  326. ("看板没有闭环", "红灯能看见,但原因、责任人、行动项和改善效果没有统一跟踪。"),
  327. ]
  328. for i, (head, body) in enumerate(pains):
  329. card(slide, head, body, 0.7 + (i % 2) * 6.2, 1.9 + (i // 2) * 2.2, 5.75, 1.78, [BLUE, AMBER, RED, CYAN][i], i + 1)
  330. add_notes(slide, "这页用客户熟悉的日常问题建立共鸣。重点不是批评客户现有系统,而是指出跨系统、跨部门的运营断点。")
  331. page += 1
  332. # 03 Positioning
  333. slide = base_slide(prs, "平台定位", page, "在业务系统之上,建立工厂运营协同层")
  334. layers = [
  335. ("经营决策", "九宫格 · 我的工作台 · 智慧诊断 · 改善台账", NAVY, WHITE),
  336. ("跨部门协同", "订单 · 计划 · 供应 · 生产 · 质量 · 交付 · 异常", CYAN, WHITE),
  337. ("数据与系统连接", "现有业务系统 · 数据中台 · DWD/KPI", PALE_BLUE, NAVY),
  338. ]
  339. for i, (head, body, color, tc) in enumerate(layers):
  340. x = 1.05 + i * 0.55
  341. y = 1.95 + i * 1.42
  342. w = 11.2 - i * 1.1
  343. add_rect(slide, x, y, w, 1.08, color, color)
  344. add_text(slide, head, x + 0.25, y + 0.14, 2.0, 0.32, 15, tc, True)
  345. add_text(slide, body, x + 2.4, y + 0.12, w - 2.7, 0.55, 15, tc, True, PP_ALIGN.CENTER, MSO_ANCHOR.MIDDLE)
  346. add_text(slide, "不是替代所有系统,而是把现有能力组织成一条可运营、可改善的业务链", 1.15, 6.35, 11.0, 0.36, 16, NAVY, True, PP_ALIGN.CENTER)
  347. add_notes(slide, f"遇到客户问是否替代 ERP/MES 时:{SYSTEM_NAME}可以独立运行,也可以连接现有系统,核心价值是跨系统运营协同。")
  348. page += 1
  349. # 04 End-to-end loop
  350. slide = base_slide(prs, "一条完整的工厂运营闭环", page, "所有业务结果最终都能回到订单、客户与经营指标")
  351. flow(slide, ["运营建模", "订单评审", "工单排程", "物料齐套", "采购到货", "仓储检验", "生产执行"], 2.15, 0.48, 12.4, font_size=10.5)
  352. flow(slide, ["成品检验", "入库发运", "异常处置", "指标诊断", "改善审批", "行动执行", "效果验证"], 3.42, 0.48, 12.4, [TEAL, BLUE, AMBER, RED], 10.5)
  353. add_rect(slide, 1.35, 5.12, 10.65, 1.05, PALE_TEAL, CYAN)
  354. add_text(slide, "上一步的结果成为下一步的输入,现场变化能够反向影响计划和客户承诺", 1.65, 5.4, 10.05, 0.45, 17, NAVY, True, PP_ALIGN.CENTER)
  355. add_notes(slide, "这页是整份 PPT 的主线,后续所有模块和场景都围绕这条链展开。")
  356. page += 1
  357. # 05 S0-S9 grid
  358. slide = base_slide(prs, "系统功能全景:S0–S9", page, "从业务建模到经营改善,覆盖工厂运营主链")
  359. modules = [
  360. ("S0", "运营建模", "主数据 · 规则 · 指标", NAVY),
  361. ("S1", "产销协同", "订单 · 评审 · 交付", BLUE),
  362. ("S2", "制造协同", "排程 · 日计划 · 追踪", CYAN),
  363. ("S3", "供应协同", "需求 · 齐套 · 采购", TEAL),
  364. ("S4", "采购执行", "交货 · 发货 · 退货", AMBER),
  365. ("S5", "物料仓储", "IQC · 库存 · 领退料", BLUE),
  366. ("S6", "生产执行", "投产 · 报工 · IPQC", CYAN),
  367. ("S7", "成品仓储", "FQC · 入库 · 发运", TEAL),
  368. ("S8", "异常监控", "发现 · 分派 · 升级", RED),
  369. ("S9", "智慧运营", "看板 · 诊断 · 改善", NAVY),
  370. ]
  371. for i, (code, name, desc, color) in enumerate(modules):
  372. x = 0.55 + (i % 5) * 2.53
  373. y = 1.85 + (i // 5) * 2.35
  374. add_rect(slide, x, y, 2.26, 1.88, LIGHT, LINE)
  375. add_text(slide, code, x + 0.18, y + 0.15, 0.55, 0.4, 18, color, True)
  376. add_text(slide, name, x + 0.18, y + 0.62, 1.88, 0.36, 15, NAVY, True)
  377. add_text(slide, desc, x + 0.18, y + 1.17, 1.88, 0.44, 10, MUTED)
  378. add_notes(slide, "只用这页讲全景,不逐个念功能。根据客户痛点选择后续重点模块。")
  379. page += 1
  380. # 06-15 Modules
  381. module_slide(
  382. prs, page, "S0", "运营建模", "先把工厂的业务语言、标准和规则统一",
  383. ["客户、供应商、物料与 BOM", "工艺、工序、产线与生产日历", "库位与 IQC/IPQC/FQC 质量规则", "组织、角色与业务权限"],
  384. ["减少部门间口径差异", "让新产品、新产线可复制", "为计划、质量、仓储提供可信基础", "让指标计算有统一来源"],
  385. "新产品导入时,一次建立 BOM、工艺、产线和检验标准,后续评审、排程和质量自动复用。", NAVY,
  386. )
  387. page += 1
  388. module_slide(
  389. prs, page, "S1", "产销协同", "让销售承诺建立在可交付能力之上",
  390. ["产品设计、合同评审、订单评审", "订单优先级与交期评估", "工单下达、需求核验、计划联动", "订单交付跟踪与发货管理"],
  391. ["多部门围绕同一订单协同", "交期承诺有业务依据", "订单状态全过程可追溯", "提前识别交付风险"],
  392. "客户插单时,同步评估设计、物料、产能和现有订单影响,再给出可解释的交期。", BLUE,
  393. )
  394. page += 1
  395. module_slide(
  396. prs, page, "S2", "制造协同", "把订单变成真正可执行的生产计划",
  397. ["生产排程、排产异常、可执行日计划", "产线日历、节假日、加班和休息时间", "工单物料、工序和执行追踪", "制造协同与工单进度看板"],
  398. ["计划考虑产能、工序和日历", "异常有原因、有记录", "看清当前工序、在制与末道完成", "计划变化可追踪、可解释"],
  399. "订单优先级改变后,计划员能看到受影响工单、产线和交期,而不是只改一个日期。", CYAN,
  400. )
  401. page += 1
  402. module_slide(
  403. prs, page, "S3", "供应协同", "把缺料救火前移为供应计划",
  404. ["物料需求计划与交货计划", "工单物料齐套与缺料识别", "采购申请与采购订单", "库存、在途与供应交期协同"],
  405. ["从工单和 BOM 计算真实需求", "缺料追溯到订单、工单和供应商", "计划与采购共享优先级", "提前争取催交、替代与调序窗口"],
  406. "关键物料延期时,按受影响客户订单排序处理,而不是按采购员自己的表格催单。", TEAL,
  407. )
  408. page += 1
  409. module_slide(
  410. prs, page, "S4", "采购执行", "让采购从催单转向供应商交付协同",
  411. ["供应商交货计划与交货管理", "供应商发货、到货与部分到货", "采购收货与 IQC 衔接", "采购退货与延期跟踪"],
  412. ["提前发现延期与关键欠料", "供应风险向订单和计划传导", "质量退货与补货形成闭环", "采购执行状态透明可追踪"],
  413. "同一供应商部分到货时,系统展示剩余量、承诺日以及影响的工单和订单。", AMBER,
  414. )
  415. page += 1
  416. module_slide(
  417. prs, page, "S5", "物料仓储", "让物料数量、批次和质量状态全程可追溯",
  418. ["采购收货、IQC 与待检管理", "合格入库与不合格处置", "库存、批次与库位管理", "生产领料与退料"],
  419. ["数量、批次和质量状态统一", "仓库动作关联采购与生产需求", "避免不合格物料误入生产", "物料流向全程可追溯"],
  420. "来料到厂后,从收货、待检、质量判定到入库和领料,每一步都保留数量、批次和状态。", BLUE,
  421. )
  422. page += 1
  423. module_slide(
  424. prs, page, "S6", "生产执行", "把投产、报工和过程质量及时反馈给计划",
  425. ["生产指令与工单投产", "工序报工与执行实绩", "IPQC 过程检验", "生产异常与恢复反馈"],
  426. ["计划持续获取执行反馈", "生产偏差和质量问题及时暴露", "过程结果可追溯到工单与工序", "进度反向更新交付风险"],
  427. "某工序进度落后或发生质量异常时,计划和交付侧可以及时看到影响并协同处置。", CYAN,
  428. )
  429. page += 1
  430. module_slide(
  431. prs, page, "S7", "成品仓储", "守住成品质量与客户交付的最后关口",
  432. ["成品报检与 FQC 任务", "检验录入、判定与复检", "生产入库与成品库存", "销售发运与订单交付"],
  433. ["不合格产品受控进入交付", "成品库存与客户订单关联", "检验结果与入库数量一致", "发运状态透明可跟踪"],
  434. "客户催发货时,可以同时确认 FQC 结果、成品库存、发运进度和订单状态。", TEAL,
  435. )
  436. page += 1
  437. module_slide(
  438. prs, page, "S8", "异常监控", "把异常变成可管理、可追踪的业务对象",
  439. ["规则持续监控订单、供应、质量、生产和设备", "发现问题后自动生成异常事件", "按场景和等级向责任角色发送预警", "认领、分派、处理、验证、关闭和超时升级"],
  440. ["风险无需等待人工汇报", "在线实时提醒,离线登录仍可恢复", "从异常下钻到订单、工单、物料和产线", "责任、时限和处理记录全程留痕"],
  441. "供应延期、设备停机或质量异常出现后,系统自动建单并向配置的责任角色发送预警。", RED,
  442. )
  443. page += 1
  444. module_slide(
  445. prs, page, "S9", "智慧运营", "从看经营走向改经营",
  446. ["九宫格、个人工作台与模块看板", "红黄绿指标、趋势与业务下钻", "交付、供应、质量、制造智慧诊断", "改善任务、审批、效果评价与台账", "DWD/KPI 构建与五类 ChartBI 看板"],
  447. ["管理者看全局,责任人看自己的任务", "用业务事实解释指标变化", "问题有人负责、有人跟踪", "改善效果可验证、经验可沉淀"],
  448. "厂长发现交付指标转黄,沿指标下钻到缺料工单,直接形成跨部门改善计划。", NAVY,
  449. )
  450. page += 1
  451. # 16 cockpit
  452. slide = base_slide(prs, "不是一块静态大屏,而是可下钻的经营驾驶舱", page, "不同角色看到同一个问题的不同层次")
  453. levels = [
  454. ("全局", "九宫格健康度", "厂长 / 总经理", NAVY),
  455. ("模块", "交付、制造、供应、质量", "运营负责人", BLUE),
  456. ("指标", "目标、现状、趋势、偏差", "部门经理", CYAN),
  457. ("事实", "订单、工单、物料、检验单", "业务人员", TEAL),
  458. ("行动", "责任人、时限、审批、验证", "执行与改善团队", AMBER),
  459. ]
  460. for i, (level, content, role, color) in enumerate(levels):
  461. y = 1.85 + i * 0.93
  462. add_rect(slide, 0.82 + i * 0.42, y, 11.45 - i * 0.84, 0.68, color, color)
  463. add_text(slide, level, 1.05 + i * 0.42, y + 0.11, 1.0, 0.34, 13, WHITE, True)
  464. add_text(slide, content, 2.42 + i * 0.42, y + 0.1, 5.3 - i * 0.25, 0.34, 13, WHITE, True, PP_ALIGN.CENTER)
  465. add_text(slide, role, 9.2, y + 0.11, 2.25 - i * 0.08, 0.34, 10, WHITE, align=PP_ALIGN.RIGHT)
  466. add_notes(slide, "强调同一套数据对不同角色呈现不同粒度,避免管理层看明细、一线只看汇总。")
  467. page += 1
  468. # 17 cockpit + workbench
  469. slide = base_slide(
  470. prs,
  471. "双入口:管理者看全局,每个人办自己的事",
  472. page,
  473. "同一套业务事实,按角色提供经营驾驶舱与个人工作台",
  474. )
  475. add_rect(slide, 0.62, 1.85, 5.72, 2.32, PALE_BLUE, BLUE)
  476. add_pill(slide, "经营视角", 0.92, 2.1, 1.18, BLUE)
  477. add_text(slide, "九宫格经营驾驶舱", 0.92, 2.65, 4.9, 0.46, 20, NAVY, True)
  478. add_bullets(
  479. slide,
  480. ["查看全厂健康与红黄灯", "下钻模块、指标和业务事实", "适合厂长与运营管理层"],
  481. 0.94, 3.18, 4.95, 0.78, 11.5, spacing=3, accent=BLUE,
  482. )
  483. add_rect(slide, 6.98, 1.85, 5.72, 2.32, PALE_TEAL, TEAL)
  484. add_pill(slide, "个人视角", 7.28, 2.1, 1.18, TEAL)
  485. add_text(slide, "我的工作台", 7.28, 2.65, 4.9, 0.46, 20, NAVY, True)
  486. add_bullets(
  487. slide,
  488. ["聚合我的行动项、审批与 S8 任务", "统一显示未读消息和到期提醒", "适合部门长、工程师与业务人员"],
  489. 7.3, 3.18, 4.95, 0.78, 11.5, spacing=3, accent=TEAL,
  490. )
  491. flow(
  492. slide,
  493. ["异常 / 改善 / 审批", "持久化站内信", "在线实时提醒", "工作台同步刷新", "深链直达处理", "结果留痕"],
  494. 4.78, 0.62, 12.08, [RED, AMBER, CYAN, TEAL, BLUE, NAVY], 10.5,
  495. )
  496. add_text(
  497. slide,
  498. "在线时即时提醒,离线后重新登录仍能看到未读与待办;任务只进入明确责任人的工作台。",
  499. 1.05, 5.94, 11.2, 0.52, 13.5, NAVY, True, PP_ALIGN.CENTER, MSO_ANCHOR.MIDDLE,
  500. )
  501. add_notes(
  502. slide,
  503. "不要把两个入口讲成两套系统。九宫格回答“工厂哪里有问题”,我的工作台回答“我现在需要做什么”。",
  504. )
  505. page += 1
  506. screenshot_pair_slide(
  507. prs, page, "实际界面|动态运营看板",
  508. "统一筛选、分层指标、红黄绿状态与智慧诊断入口",
  509. DASHBOARD_SHOTS / "S1-dashboard.png", "S1 产销协同看板",
  510. DASHBOARD_SHOTS / "S3-dashboard.png", "S3 供应协同看板",
  511. )
  512. page += 1
  513. # 17 diagnosis
  514. slide = base_slide(prs, "智慧诊断:用事实解释指标为什么变差", page, "不只告诉客户“红了”,还告诉客户“哪些业务对象造成了影响”")
  515. flow(slide, ["选择指标", "目标与现状", "识别偏差", "下钻事实", "确认根因"], 2.0, 0.72, 11.9, [NAVY, BLUE, CYAN, TEAL, AMBER], 13)
  516. sources = [
  517. ("交付", "订单 / 工单排程"),
  518. ("供应", "供应商交付 / 缺料"),
  519. ("制造", "排程 / 报工 / 在制"),
  520. ("质量", "IQC / FQC"),
  521. ("异常", "S8 事件"),
  522. ]
  523. for i, (head, body) in enumerate(sources):
  524. x = 0.75 + i * 2.5
  525. add_rect(slide, x, 3.48, 2.18, 1.42, LIGHT, LINE)
  526. add_text(slide, head, x + 0.12, 3.7, 1.94, 0.32, 14, NAVY, True, PP_ALIGN.CENTER)
  527. add_text(slide, body, x + 0.12, 4.18, 1.94, 0.36, 10, MUTED, align=PP_ALIGN.CENTER)
  528. add_rect(slide, 1.18, 5.48, 10.95, 0.78, PALE_AMBER, AMBER)
  529. add_text(slide, "每条诊断结论都可回到订单、工单、物料、检验单和异常事件进行验证。", 1.45, 5.7, 10.4, 0.34, 14, NAVY, True, PP_ALIGN.CENTER)
  530. add_notes(slide, "销售讲解重点:指标偏差能够关联到实际业务对象,管理人员可以沿证据链快速确认问题原因。")
  531. page += 1
  532. # 18 improvement loop
  533. slide = base_slide(prs, "改善闭环:从红灯到结果验证", page, "问题不是关闭在会议纪要里,而是沉淀为可审计、可评价的改善记录")
  534. flow(slide, ["发现偏差", "确认事实", "创建计划", "正式审批", "自动派发", "行动执行", "效果评价", "关闭归档"], 2.0, 0.55, 12.25, [RED, AMBER, BLUE, CYAN, TEAL, GREEN, NAVY], 10.5)
  535. features = [
  536. ("分级审批", "黄单、红单、跨部门使用不同审批路径。"),
  537. ("自动派发", "指定责任人后,自动生成任务并发送站内信。"),
  538. ("统一工作台", "行动项、审批、S8 任务与消息集中到个人。"),
  539. ("到期提醒", "临近到期、逾期和状态变化自动提醒。"),
  540. ("验证台账", "改善前后效果、行动和日志集中追溯。"),
  541. ]
  542. for i, (head, body) in enumerate(features):
  543. x = 0.62 + i * 2.52
  544. card(slide, head, body, x, 3.45, 2.22, 2.05, [RED, AMBER, BLUE, TEAL, NAVY][i])
  545. add_notes(slide, "智慧诊断与审批、任务、效果评价连接,让问题从发现、处置到验证形成完整闭环。")
  546. page += 1
  547. # 19 dual mode
  548. slide = base_slide(prs, "双模式:既能独立运行,也能连接现有系统", page, "客户不需要一次性替换全部系统")
  549. add_rect(slide, 0.68, 1.85, 5.85, 3.9, PALE_BLUE, BLUE)
  550. add_text(slide, "独立作业模式", 1.0, 2.12, 5.2, 0.48, 21, BLUE, True, PP_ALIGN.CENTER)
  551. add_bullets(slide, ["在平台内维护主数据与业务规则", "完成计划、协同、执行、异常和改善", "适合新工厂、试点场景和快速上线"], 1.12, 2.88, 4.95, 1.9, 15, accent=BLUE)
  552. add_rect(slide, 6.82, 1.85, 5.85, 3.9, PALE_TEAL, TEAL)
  553. add_text(slide, "集成协同模式", 7.14, 2.12, 5.2, 0.48, 21, TEAL, True, PP_ALIGN.CENTER)
  554. add_bullets(slide, ["连接客户现有业务系统", "汇聚订单、生产、采购、库存和质量数据", "通过数据中台完成标准化、对账与指标构建"], 7.26, 2.88, 4.95, 1.9, 15, accent=TEAL)
  555. add_rect(slide, 2.02, 6.12, 9.3, 0.58, NAVY, NAVY)
  556. add_text(slide, "从一个高价值场景开始,按客户现状逐步连接和扩展", 2.2, 6.25, 8.95, 0.28, 14, WHITE, True, PP_ALIGN.CENTER)
  557. add_notes(slide, "这页用于消除客户对替换现有系统、实施周期过长的顾虑。")
  558. page += 1
  559. # Section 2
  560. slide = section_slide(prs, "02", "用业务场景讲价值", "从客户每天遇到的问题出发,展示功能如何协同,而不是逐页介绍菜单。", page)
  561. add_notes(slide, "进入场景部分。建议根据客户痛点选择其中 1–2 个重点讲,其余快速带过。")
  562. page += 1
  563. # Scenario 1
  564. scenario_background_slide(
  565. prs, page, "场景一|客户插单,能不能承诺交期?",
  566. ["销售接到高优先级订单", "客户要求快速确认交期", "需要同时判断设计、物料、产能和现有订单影响"],
  567. ["多部门分别查表、开会、口头确认", "承诺慢,且很难说明依据", "插单影响到现场才逐步暴露"],
  568. ["销售", "项目经理", "计划", "采购", "生产"], BLUE,
  569. )
  570. page += 1
  571. scenario_flow_slide(
  572. prs, page, "场景一|平台如何协同",
  573. ["客户订单", "多维评审", "需求核验", "工单下达", "产能排程", "物料齐套", "交付跟踪"],
  574. ["S1 统一订单评审、优先级和交期", "S2 根据产线能力和日历形成计划", "S3 提前识别缺料,S8 监控异常", "S9 持续观察准交、周期和达成率"],
  575. "给出有依据的承诺\n变化影响可追踪\n风险提前预警", BLUE,
  576. )
  577. page += 1
  578. screenshot_pair_slide(
  579. prs, page, "实际界面|订单评审与工单执行追踪",
  580. "订单评审生成工单后,可继续追踪当前工序、末道工序与在制数量",
  581. FLOW_SHOTS / "S1-04c-review-with-wo.png", "订单评审与工单生成",
  582. FLOW_SHOTS / "S2-09-aidop-progress-dashboard.png", "工单执行进度看板",
  583. )
  584. page += 1
  585. scenario_value_slide(
  586. prs, page, "场景一|从“拍脑袋承诺”到“有依据交付”",
  587. [("更快承诺", "评审对象和依据集中,不再逐部门追问。"),
  588. ("承诺更可信", "交期同时参考物料、产能、工艺和现有负荷。"),
  589. ("变化可追踪", "插单影响哪些工单、物料和客户一目了然。"),
  590. ("交付可预警", "在客户催单之前,提前看到风险和处置窗口。")], BLUE,
  591. )
  592. page += 1
  593. # Scenario 2
  594. scenario_background_slide(
  595. prs, page, "场景二|关键物料延期,生产会不会停?",
  596. ["关键供应商只能部分到货", "两张工单争用同一种关键物料", "采购已知道延期,但计划尚未调整"],
  597. ["缺料到领料时才暴露", "采购、计划、仓库各有一份清单", "优先级不一致,催交与生产需求脱节"],
  598. ["计划", "采购", "供应商", "仓库", "销售"], AMBER,
  599. )
  600. page += 1
  601. scenario_flow_slide(
  602. prs, page, "场景二|平台如何协同",
  603. ["工单/BOM", "齐套检查", "缺料清单", "采购计划", "供应商交付", "IQC/库存", "排程调整"],
  604. ["从工单和 BOM 计算真实需求", "结合库存、在途和交货计划判断风险", "按订单影响确定催交和替代优先级", "处置结果回到交付风险和经营指标"],
  605. "缺料从现场前移到计划\n供应与订单优先级统一\n减少停线风险", AMBER,
  606. )
  607. page += 1
  608. scenario_value_slide(
  609. prs, page, "场景二|从“缺料救火”到“供应风险前置”",
  610. [("缺料前置", "在仓库无料可发之前,就在计划阶段发现缺口。"),
  611. ("优先级统一", "采购处理顺序与受影响客户订单挂钩。"),
  612. ("协同透明", "供应商、采购、计划、仓库共享同一风险清单。"),
  613. ("减少停线", "用催交、替代、调序争取可执行的处置窗口。")], AMBER,
  614. )
  615. page += 1
  616. # Scenario 3
  617. scenario_background_slide(
  618. prs, page, "场景三|质量异常如何避免重复发生?",
  619. ["关键来料 IQC 不合格", "物料已影响生产齐套", "过程质量偏差与成品 FQC 需要重点关注"],
  620. ["IQC、IPQC、FQC 各自处理", "难以关联供应商、物料、工单和订单", "关闭问题后缺少效果验证,容易重复发生"],
  621. ["质量", "采购", "仓库", "生产", "运营"], RED,
  622. )
  623. page += 1
  624. scenario_flow_slide(
  625. prs, page, "场景三|平台如何形成质量闭环",
  626. ["采购到货", "IQC", "隔离/退货", "生产/IPQC", "FQC", "S8异常", "改善验证"],
  627. ["S0 统一质量标准和抽样规则", "S5/S6/S7 管理来料、过程和成品质量", "S8 汇聚跨阶段异常并分派处置", "S9 关联指标、行动项和改善效果"],
  628. "质量问题可追溯\n库存状态受控\n整改效果可验证", RED,
  629. )
  630. page += 1
  631. screenshot_pair_slide(
  632. prs, page, "实际界面|IQC 检验与质量看板",
  633. "来料检验结果进入审批与关单,质量结果同步进入模块看板和智慧诊断",
  634. IQC_SHOTS / "20260811-2306-提交检验结果合格-IQC202608110002.png", "IQC 检验结果与审批",
  635. DASHBOARD_SHOTS / "S7-dashboard.png", "S7 成品仓储看板",
  636. )
  637. page += 1
  638. scenario_value_slide(
  639. prs, page, "场景三|从“处理一张不合格单”到“降低重复发生”",
  640. [("质量可追溯", "从批次追到供应商、物料、工单和订单。"),
  641. ("库存受控", "待检、不合格、合格状态清晰,避免误领误发。"),
  642. ("责任闭环", "整改有审批、有负责人、有时限和过程记录。"),
  643. ("改善可验证", "用后续质量和交付数据判断整改是否真正有效。")], RED,
  644. )
  645. page += 1
  646. # Scenario 4 management
  647. slide = base_slide(prs, "场景四|指标变红,如何通过智慧诊断找到根因?", page, "平台把“看见问题”升级为“推动问题解决”")
  648. add_text(slide, "传统看板", 0.8, 1.82, 5.2, 0.45, 20, RED, True, PP_ALIGN.CENTER)
  649. add_rect(slide, 0.72, 2.32, 5.55, 3.75, PALE_RED, RED)
  650. add_bullets(slide, ["指标变红", "临时组织会议", "原因和行动散落在纪要", "一段时间后无法确认是否解决"], 1.12, 2.88, 4.75, 2.45, 16, accent=RED)
  651. add_text(slide, "平台闭环", 7.0, 1.82, 5.2, 0.45, 20, TEAL, True, PP_ALIGN.CENTER)
  652. add_rect(slide, 6.82, 2.32, 5.82, 3.75, PALE_TEAL, TEAL)
  653. add_bullets(slide, ["九宫格发现风险", "智慧诊断定位事实", "计划审批与任务分派", "自动评价改善前后效果", "台账沉淀组织经验"], 7.22, 2.78, 5.02, 2.75, 16, accent=TEAL)
  654. add_text(slide, "›", 6.26, 3.72, 0.55, 0.62, 38, NAVY, True, PP_ALIGN.CENTER)
  655. add_notes(slide, "销售收束场景时强调:系统价值不止是可视化,而是运营闭环。")
  656. page += 1
  657. slide = base_slide(prs, "场景四|四类智慧诊断链", page, "同一个红灯,沿不同业务事实找到可验证的原因和行动")
  658. diagnosis_chains = [
  659. ("交付诊断", "准交率下降", "缺料 / 设备异常\n受影响订单与工单", "调整计划 · 催交 · 替代供应", BLUE),
  660. ("供应诊断", "到货及时率下降", "延期 / 部分到货\n供应商与关键物料", "供应协同 · 交货重排", AMBER),
  661. ("质量诊断", "IQC / FQC 合格率下降", "异常批次\n供应商、工单与订单", "隔离退货 · 复检 · 整改", RED),
  662. ("制造诊断", "计划达成率下降", "产线异常 / 进度落后\n工序与在制工单", "恢复生产 · 调整优先级", TEAL),
  663. ]
  664. for i, (head, metric, facts, action, color) in enumerate(diagnosis_chains):
  665. x = 0.7 + (i % 2) * 6.25
  666. y = 1.85 + (i // 2) * 2.42
  667. add_rect(slide, x, y, 5.68, 1.96, LIGHT, LINE)
  668. add_pill(slide, head, x + 0.18, y + 0.16, 1.22, color, WHITE, 10)
  669. add_text(slide, metric, x + 1.58, y + 0.16, 3.82, 0.34, 15, NAVY, True)
  670. add_text(slide, facts, x + 0.22, y + 0.7, 2.65, 0.82, 11, MUTED, align=PP_ALIGN.CENTER, valign=MSO_ANCHOR.MIDDLE)
  671. add_text(slide, "›", x + 2.82, y + 0.94, 0.3, 0.36, 20, color, True, PP_ALIGN.CENTER)
  672. add_text(slide, action, x + 3.18, y + 0.76, 2.2, 0.62, 11.5, color, True, PP_ALIGN.CENTER, MSO_ANCHOR.MIDDLE)
  673. add_notes(slide, "四条诊断链分别对应交付、供应、质量和制造场景,所有结论都能够下钻到业务对象并形成改善行动。")
  674. page += 1
  675. # Data
  676. slide = base_slide(
  677. prs, "业务演示案例数据全景", page,
  678. "覆盖从订单、计划、供应、质量到异常改善的完整制造运营链路",
  679. )
  680. add_metric(slide, "3", "业务场景数据集", 0.62, 1.82, 2.25, NAVY)
  681. add_metric(slide, "169", "每组 KPI 指标", 3.08, 1.82, 2.25, BLUE)
  682. add_metric(slide, "55", "销售订单(约)", 5.54, 1.82, 2.25, CYAN)
  683. add_metric(slide, "238", "工单(约)", 8.0, 1.82, 2.25, TEAL)
  684. add_metric(slide, "55", "采购订单(约)", 10.46, 1.82, 2.25, AMBER)
  685. add_metric(slide, "100+", "生产报工", 0.62, 3.55, 2.25, BLUE)
  686. add_metric(slide, "30+", "质量检验结果", 3.08, 3.55, 2.25, TEAL)
  687. add_metric(slide, "约 40", "S8 异常", 5.54, 3.55, 2.25, RED)
  688. add_metric(slide, "4", "智慧诊断链", 8.0, 3.55, 2.25, NAVY)
  689. add_metric(slide, "5", "ChartBI 主题", 10.46, 3.55, 2.25, CYAN)
  690. add_rect(slide, 0.78, 5.53, 11.8, 0.9, PALE_TEAL, TEAL)
  691. add_text(slide, "订单交付 · 物料供应 · 生产执行 · 质量管理 · 异常改善", 1.05, 5.82, 11.25, 0.34, 14, NAVY, True, PP_ALIGN.CENTER)
  692. add_notes(slide, "本页用于说明演示案例覆盖的业务对象和场景复杂度。")
  693. page += 1
  694. # Roles
  695. slide = base_slide(prs, "谁会使用本平台", page, "不同角色围绕同一条业务链协同")
  696. roles = [
  697. ("总经理 / 厂长", "经营健康、交付风险、改善结果", NAVY),
  698. ("运营负责人", "跨模块指标、异常和改善台账", BLUE),
  699. ("销售 / 项目", "订单评审、交期、交付跟踪", CYAN),
  700. ("计划 / 采购", "排程、齐套、供应商交付", TEAL),
  701. ("仓库 / 生产", "收发存、报工、执行进度", AMBER),
  702. ("质量 / 设备", "IQC/IPQC/FQC、设备异常", RED),
  703. ]
  704. for i, (role, focus, color) in enumerate(roles):
  705. x = 0.72 + (i % 3) * 4.18
  706. y = 1.85 + (i // 3) * 2.35
  707. add_rect(slide, x, y, 3.72, 1.85, LIGHT, LINE)
  708. add_rect(slide, x + 0.22, y + 0.2, 0.62, 0.62, color, color)
  709. add_text(slide, str(i + 1), x + 0.22, y + 0.28, 0.62, 0.3, 15, WHITE, True, PP_ALIGN.CENTER)
  710. add_text(slide, role, x + 1.02, y + 0.18, 2.4, 0.38, 16, NAVY, True)
  711. add_text(slide, focus, x + 0.25, y + 1.02, 3.18, 0.5, 11, MUTED, align=PP_ALIGN.CENTER)
  712. add_rect(slide, 2.25, 6.05, 8.83, 0.6, NAVY, NAVY)
  713. add_text(slide, "同一套数据 · 不同视角 · 统一责任 · 协同处置", 2.5, 6.18, 8.35, 0.28, 14, WHITE, True, PP_ALIGN.CENTER)
  714. page += 1
  715. scenario_flow_slide(
  716. prs, page, "角色场景|厂长:每天先看全局,再抓最关键问题",
  717. ["九宫格总览", "发现红黄灯", "智慧诊断", "跨部门行动", "查看改善结果"],
  718. ["查看全厂经营健康和交付风险", "下钻受影响订单、工单和关键事实", "推动责任部门协同并查看改善前后趋势"],
  719. "少听汇报\n快速抓重点\n基于事实决策", NAVY,
  720. )
  721. page += 1
  722. scenario_flow_slide(
  723. prs, page, "角色场景|部门长:把预警转成责任明确的行动",
  724. ["模块看板", "指标偏差", "业务事实", "S8预警", "分派责任", "跟踪结果"],
  725. ["查看本部门目标、现状和趋势", "接收S8预警并确认责任对象", "明确责任人和时限,跟踪处理、验证与超时"],
  726. "统一部门重点\n过程透明可控\n问题按时闭环", BLUE,
  727. )
  728. page += 1
  729. scenario_flow_slide(
  730. prs, page, "角色场景|工程师:收到任务后快速定位并处理",
  731. ["实时提醒", "打开工作台", "深链到任务", "核对业务事实", "执行改善措施", "反馈处理证据", "验证效果"],
  732. ["工作台聚合行动项、审批、S8 任务和未读消息", "通知包含计划号、截止日期和详情入口", "临近到期、逾期和状态变化继续自动提醒"],
  733. "减少查数时间\n明确任务期限\n处理经验可追溯", TEAL,
  734. )
  735. page += 1
  736. # Value
  737. slide = base_slide(prs, "客户最终获得的,不是“更多报表”", page, "五类能够持续积累的制造运营能力")
  738. vals = [
  739. ("01", "交付更可预测", "订单、物料、产能和执行联动", BLUE),
  740. ("02", "库存更可控", "按真实需求组织采购、收货和领退料", TEAL),
  741. ("03", "质量更可追溯", "来料、过程、成品和供应商闭环", RED),
  742. ("04", "异常响应更快", "自动发现、责任分派、超时升级", AMBER),
  743. ("05", "管理持续改善", "指标、事实、行动和效果统一沉淀", NAVY),
  744. ]
  745. for i, (num, head, body, color) in enumerate(vals):
  746. x = 0.7 + i * 2.5
  747. add_rect(slide, x, 1.95, 2.2, 3.9, LIGHT, LINE)
  748. add_text(slide, num, x + 0.18, 2.15, 1.84, 0.55, 26, color, True, PP_ALIGN.CENTER)
  749. add_rect(slide, x + 0.55, 2.88, 1.1, 0.07, color, color, False)
  750. add_text(slide, head, x + 0.18, 3.25, 1.84, 0.7, 16, NAVY, True, PP_ALIGN.CENTER, MSO_ANCHOR.MIDDLE)
  751. add_text(slide, body, x + 0.25, 4.35, 1.7, 0.9, 11, MUTED, align=PP_ALIGN.CENTER, valign=MSO_ANCHOR.MIDDLE)
  752. add_notes(slide, "如果客户要求 ROI,下一步应使用客户自己的基线数据,为这五类价值分别设定量化指标。")
  753. page += 1
  754. # Fit
  755. slide = base_slide(prs, "什么样的客户最适合本平台", page, "从高频运营痛点切入,比从模块清单切入更容易形成共识")
  756. fits = [
  757. ("业务复杂", "多品种、小批量、订单变化频繁"),
  758. ("系统分散", "已有 ERP/MES/WMS,但跨系统仍靠 Excel"),
  759. ("痛点明确", "交付、缺料、质量、在制透明度不足"),
  760. ("希望渐进", "先场景试点,再扩展到全工厂"),
  761. ("组织扩张", "多工厂、多组织,需要统一口径与隔离"),
  762. ("重视改善", "不满足于看板,希望形成行动闭环"),
  763. ]
  764. for i, (head, body) in enumerate(fits):
  765. x = 0.7 + (i % 3) * 4.18
  766. y = 1.85 + (i // 3) * 2.25
  767. card(slide, head, body, x, y, 3.72, 1.72, [NAVY, BLUE, CYAN, TEAL, AMBER, RED][i], i + 1)
  768. page += 1
  769. # Sales questions
  770. slide = base_slide(prs, "建议的销售切入方式", page, "不要先问“客户要哪些模块”,先问四个业务问题")
  771. questions = [
  772. "哪类订单最容易延期?通常到哪个环节才发现?",
  773. "缺料清单由谁维护?计划、采购和仓库是否一致?",
  774. "质量异常关闭后,如何确认没有再次发生?",
  775. "管理看板上的红灯,能否追到单据、责任人和行动?",
  776. ]
  777. for i, q in enumerate(questions):
  778. y = 1.8 + i * 1.05
  779. add_rect(slide, 0.8, y, 8.1, 0.78, LIGHT, LINE)
  780. add_text(slide, f"{i + 1}", 1.02, y + 0.17, 0.46, 0.32, 16, CYAN, True, PP_ALIGN.CENTER)
  781. add_text(slide, q, 1.62, y + 0.12, 6.92, 0.42, 15, NAVY, True)
  782. add_rect(slide, 9.28, 1.8, 3.42, 3.95, PALE_TEAL, TEAL)
  783. add_text(slide, "销售策略", 9.58, 2.12, 2.82, 0.45, 20, TEAL, True, PP_ALIGN.CENTER)
  784. add_bullets(slide, ["找到可量化的高价值场景", "用客户自己的业务对象演示", "先做闭环,再扩展模块", "把价值指标写进试点目标"], 9.63, 2.92, 2.72, 2.1, 13, accent=TEAL)
  785. add_notes(slide, "销售人员可以直接使用这四个问题做首次访谈。答案会自然指向交付、缺料、质量或异常改善场景。")
  786. page += 1
  787. # Implementation
  788. slide = base_slide(prs, "典型落地路径", page, "从一个高价值场景开始,逐步建立可复制的制造运营能力")
  789. stages = [
  790. ("1", "业务诊断", "确认痛点、角色、指标", NAVY),
  791. ("2", "运营建模", "统一主数据、规则和口径", BLUE),
  792. ("3", "场景试点", "打通一条端到端闭环", CYAN),
  793. ("4", "系统连接", "按需连接现有系统", TEAL),
  794. ("5", "运营推广", "扩展模块、看板和异常", AMBER),
  795. ("6", "持续优化", "用评价和台账积累经验", RED),
  796. ]
  797. for i, (num, head, body, color) in enumerate(stages):
  798. x = 0.62 + i * 2.08
  799. add_rect(slide, x, 2.05, 1.78, 3.58, LIGHT, LINE)
  800. add_rect(slide, x + 0.5, 2.32, 0.78, 0.78, color, color)
  801. add_text(slide, num, x + 0.5, 2.5, 0.78, 0.3, 17, WHITE, True, PP_ALIGN.CENTER)
  802. add_text(slide, head, x + 0.15, 3.38, 1.48, 0.5, 15, NAVY, True, PP_ALIGN.CENTER)
  803. add_text(slide, body, x + 0.18, 4.28, 1.42, 0.75, 10.5, MUTED, align=PP_ALIGN.CENTER)
  804. if i < len(stages) - 1:
  805. add_text(slide, "›", x + 1.77, 3.43, 0.28, 0.4, 20, color, True, PP_ALIGN.CENTER)
  806. add_rect(slide, 1.28, 6.05, 10.75, 0.62, NAVY, NAVY)
  807. add_text(slide, "试点不是“先上一套系统”,而是先证明一个场景能产生业务结果", 1.55, 6.18, 10.2, 0.3, 14, WHITE, True, PP_ALIGN.CENTER)
  808. page += 1
  809. # Demo route
  810. slide = base_slide(prs, "推荐现场演示路线", page, "控制在 20–30 分钟,围绕一个问题完成一次完整下钻")
  811. route = [
  812. ("01", "九宫格", "看整体健康"),
  813. ("02", "模块看板", "选黄/红指标"),
  814. ("03", "智慧诊断", "看目标与事实"),
  815. ("04", "改善计划", "明确责任时限"),
  816. ("05", "我的工作台", "看个人待办"),
  817. ("06", "通知深链", "直达业务处理"),
  818. ("07", "效果台账", "看结果与留痕"),
  819. ]
  820. for i, (num, head, body) in enumerate(route):
  821. x = 0.46 + i * 1.82
  822. add_rect(slide, x, 2.1, 1.54, 3.65, [PALE_BLUE, PALE_BLUE, PALE_TEAL, LIGHT, PALE_AMBER, PALE_TEAL, PALE_BLUE][i], LINE)
  823. add_text(slide, num, x + 0.14, 2.35, 1.26, 0.42, 17, [NAVY, BLUE, CYAN, TEAL, AMBER, GREEN, NAVY][i], True, PP_ALIGN.CENTER)
  824. add_text(slide, head, x + 0.1, 3.18, 1.34, 0.6, 13.5, NAVY, True, PP_ALIGN.CENTER)
  825. add_text(slide, body, x + 0.12, 4.28, 1.3, 0.62, 10, MUTED, align=PP_ALIGN.CENTER)
  826. if i < len(route) - 1:
  827. add_text(slide, "›", x + 1.53, 3.55, 0.28, 0.42, 22, CYAN, True, PP_ALIGN.CENTER)
  828. add_notes(slide, "演示时不要在菜单里漫游。始终围绕一个业务问题,从总览到事实再到行动闭环。")
  829. page += 1
  830. # Closing
  831. slide = prs.slides.add_slide(prs.slide_layouts[6])
  832. slide.background.fill.solid()
  833. slide.background.fill.fore_color.rgb = NAVY
  834. add_brand(slide, dark=True)
  835. add_text(slide, "让工厂从“事后解释”", 0.78, 1.55, 11.8, 0.65, 30, WHITE, True, PP_ALIGN.CENTER)
  836. add_text(slide, "走向“事前预警 · 协同处置 · 持续改善”", 0.78, 2.42, 11.8, 0.72, 30, CYAN, True, PP_ALIGN.CENTER)
  837. add_rect(slide, 3.25, 3.58, 6.85, 0.07, CYAN, CYAN, False)
  838. add_text(slide, "从一个高价值场景开始", 2.0, 4.12, 9.35, 0.52, 20, WHITE, True, PP_ALIGN.CENTER)
  839. add_text(slide, "建立可复制的制造运营能力", 2.0, 4.76, 9.35, 0.52, 20, WHITE, True, PP_ALIGN.CENTER)
  840. add_pill(slide, "河南产互联", 5.25, 5.9, 2.83, CYAN, WHITE, 17)
  841. add_footer(slide, page, dark=True)
  842. add_notes(slide, "结束时回到客户场景:建议下一步选择一条真实订单或一个高频痛点,安排业务诊断与场景演示。")
  843. OUTPUT.parent.mkdir(parents=True, exist_ok=True)
  844. prs.save(OUTPUT)
  845. print(OUTPUT)
  846. print(f"slides={len(prs.slides)}")
  847. def build_compact():
  848. """Generate the compact, screenshot-led sales presentation."""
  849. prs = Presentation()
  850. prs.slide_width = Inches(W)
  851. prs.slide_height = Inches(H)
  852. prs.core_properties.title = f"{SYSTEM_NAME}系统介绍"
  853. prs.core_properties.subject = "面向销售、售前与制造企业管理者的业务价值介绍"
  854. prs.core_properties.author = SYSTEM_NAME
  855. prs.core_properties.comments = "真实系统截图、业务场景与制造运营闭环介绍"
  856. page = 1
  857. # 01 Cover
  858. slide = prs.slides.add_slide(prs.slide_layouts[6])
  859. slide.background.fill.solid()
  860. slide.background.fill.fore_color.rgb = NAVY
  861. add_pill(slide, "系统介绍", 0.68, 1.72, 1.25, CYAN)
  862. add_text(slide, SYSTEM_NAME, 0.68, 2.35, 11.9, 1.08, 31, WHITE, True)
  863. add_text(slide, "连接数据、业务与责任,让制造运营从看见问题走向闭环改善", 0.72, 3.62, 11.3, 0.62, 19, RGBColor(204, 219, 234))
  864. add_rect(slide, 0.72, 4.55, 6.4, 0.06, CYAN, CYAN, False)
  865. add_text(slide, "订单协同 · 计划执行 · 供应保障 · 质量追溯 · 异常处置 · 智慧运营", 0.72, 4.92, 11.6, 0.5, 16, CYAN, True)
  866. add_text(slide, "销售 / 售前 / 客户业务交流版", 0.72, 6.25, 4.8, 0.3, 11, RGBColor(190, 202, 214))
  867. add_footer(slide, page, dark=True)
  868. add_notes(slide, "开场先讲制造企业跨系统、跨部门的运营断点,再说明平台如何把问题、责任和结果串成闭环。")
  869. page += 1
  870. # 02 Pain + positioning
  871. slide = base_slide(prs, "为什么需要制造业数据智能运营平台", page, "企业并不缺系统,缺的是跨系统、跨部门的统一运营闭环")
  872. pains = [
  873. ("数据分散", "订单、计划、供应、仓储、生产和质量口径不一致。", BLUE),
  874. ("风险滞后", "缺料、延期、质量与设备问题到现场才暴露。", AMBER),
  875. ("协同靠人", "会议、群聊和 Excel 承担责任分派与进度跟踪。", RED),
  876. ("看板不闭环", "红灯能看见,但根因、任务和改善效果无法持续追踪。", TEAL),
  877. ]
  878. for i, (head, body, color) in enumerate(pains):
  879. card(slide, head, body, 0.55 + i * 3.15, 1.72, 2.85, 1.52, color, i + 1)
  880. layers = [
  881. ("经营决策层", "九宫格 · 我的工作台 · 智慧诊断 · 改善台账", NAVY, WHITE),
  882. ("业务协同层", "订单 · 计划 · 供应 · 生产 · 质量 · 仓储 · 异常", CYAN, WHITE),
  883. ("数据连接层", "现有 ERP / MES / WMS · 数据中台 · DWD / KPI", PALE_BLUE, NAVY),
  884. ]
  885. for i, (head, body, color, tc) in enumerate(layers):
  886. x = 0.92 + i * 0.45
  887. y = 3.62 + i * 0.88
  888. w = 11.5 - i * 0.9
  889. add_rect(slide, x, y, w, 0.68, color, color)
  890. add_text(slide, head, x + 0.2, y + 0.1, 1.62, 0.35, 12, tc, True)
  891. add_text(slide, body, x + 1.92, y + 0.09, w - 2.15, 0.38, 12.5, tc, True, PP_ALIGN.CENTER)
  892. add_notes(slide, "定位不是替代全部业务系统,而是在其上建立统一的制造运营协同层。")
  893. page += 1
  894. # 03 End-to-end loop
  895. slide = base_slide(prs, "一条完整的制造运营闭环", page, "上一步的结果成为下一步的输入,现场变化反向影响计划与客户承诺")
  896. flow(slide, ["运营建模", "订单评审", "工单排程", "物料齐套", "采购到货", "仓储检验", "生产执行"], 1.9, 0.48, 12.4, font_size=10.5)
  897. flow(slide, ["成品检验", "入库发运", "异常处置", "指标诊断", "改善审批", "行动执行", "效果验证"], 3.12, 0.48, 12.4, [TEAL, BLUE, AMBER, RED], 10.5)
  898. add_rect(slide, 0.85, 4.62, 11.65, 1.52, PALE_TEAL, CYAN)
  899. add_text(slide, "业务结果", 1.1, 4.92, 1.3, 0.38, 15, TEAL, True)
  900. add_text(slide, "订单交期更可信 · 缺料风险更前置 · 生产执行更透明 · 质量问题更可追溯", 2.25, 4.86, 9.8, 0.48, 15, NAVY, True, PP_ALIGN.CENTER)
  901. add_text(slide, "管理结果", 1.1, 5.56, 1.3, 0.38, 15, TEAL, True)
  902. add_text(slide, "异常有人接 · 任务有人办 · 到期有人催 · 改善结果有人验证", 2.25, 5.5, 9.8, 0.48, 15, NAVY, True, PP_ALIGN.CENTER)
  903. page += 1
  904. # 04 Module map
  905. slide = base_slide(prs, "系统功能全景:S0–S9", page, "从业务建模到经营改善,覆盖制造运营主链")
  906. modules = [
  907. ("S0", "运营建模", "主数据 · 规则 · 指标", NAVY),
  908. ("S1", "产销协同", "订单 · 评审 · 交付", BLUE),
  909. ("S2", "制造协同", "排程 · 日计划 · 追踪", CYAN),
  910. ("S3", "供应协同", "需求 · 齐套 · 采购", TEAL),
  911. ("S4", "采购执行", "交货 · 到货 · 退货", AMBER),
  912. ("S5", "物料仓储", "IQC · 库存 · 领退料", BLUE),
  913. ("S6", "生产执行", "投产 · 报工 · IPQC", CYAN),
  914. ("S7", "成品仓储", "FQC · 入库 · 发运", TEAL),
  915. ("S8", "异常监控", "发现 · 分派 · 升级", RED),
  916. ("S9", "智慧运营", "看板 · 诊断 · 改善", NAVY),
  917. ]
  918. for i, (code, name, desc, color) in enumerate(modules):
  919. x = 0.55 + (i % 5) * 2.53
  920. y = 1.75 + (i // 5) * 2.35
  921. add_rect(slide, x, y, 2.26, 1.88, LIGHT, LINE)
  922. add_text(slide, code, x + 0.18, y + 0.15, 0.55, 0.4, 18, color, True)
  923. add_text(slide, name, x + 0.18, y + 0.62, 1.88, 0.36, 15, NAVY, True)
  924. add_text(slide, desc, x + 0.18, y + 1.17, 1.88, 0.44, 10, MUTED)
  925. add_rect(slide, 1.15, 6.32, 11.05, 0.42, NAVY, NAVY)
  926. add_text(slide, "按客户痛点组合能力,不要求一次性上线全部模块", 1.35, 6.38, 10.65, 0.24, 12, WHITE, True, PP_ALIGN.CENTER)
  927. page += 1
  928. # 05 Foundation
  929. slide = base_slide(prs, "S0|先统一业务语言,再让系统协同", page, "主数据、业务规则、组织权限与指标口径是后续自动化的共同基础")
  930. foundation = [
  931. ("业务对象", "客户、供应商、物料、BOM、订单、工单", BLUE),
  932. ("制造资源", "工艺、工序、产线、设备、日历与班次", CYAN),
  933. ("质量标准", "IQC / IPQC / FQC 规则、抽样与判定", TEAL),
  934. ("运营规则", "优先级、预警、审批、KPI 与责任角色", AMBER),
  935. ]
  936. for i, (head, body, color) in enumerate(foundation):
  937. x = 0.72 + (i % 2) * 6.18
  938. y = 1.82 + (i // 2) * 2.1
  939. card(slide, head, body, x, y, 5.68, 1.66, color, i + 1)
  940. add_rect(slide, 1.18, 6.18, 10.95, 0.55, PALE_BLUE, BLUE)
  941. add_text(slide, "一次建模,多模块复用:减少口径争议,让计划、质量、仓储和指标计算使用同一份可信基础", 1.42, 6.29, 10.45, 0.28, 12.5, NAVY, True, PP_ALIGN.CENTER)
  942. page += 1
  943. # 06 S1-S2
  944. screenshot_feature_slide(
  945. prs, page, "S1–S2|从客户订单到可执行生产计划",
  946. "订单评审不是单独审批,而是同时评估交期、物料、产能与执行影响",
  947. FLOW_SHOTS / "S1-04c-review-with-wo.png",
  948. "系统能力",
  949. ["订单评审、优先级与交期评估", "评审后生成工单并联动需求", "结合产线日历形成可执行排程"],
  950. "客户价值",
  951. ["交期承诺有业务依据", "插单影响可追踪、可解释", "订单到工单全过程贯通"],
  952. BLUE, "系统 UAT 实测界面",
  953. )
  954. page += 1
  955. # 07 S2-S3
  956. screenshot_feature_slide(
  957. prs, page, "S2–S3|计划、齐套与供应风险协同",
  958. "把生产排程和物料保障放在同一条业务链上,提前识别停线风险",
  959. DASHBOARD_SHOTS / "S3-dashboard.png",
  960. "系统能力",
  961. ["工单排程与执行进度追踪", "按 BOM、库存和在途计算齐套", "缺料下钻到订单、工单与供应商"],
  962. "客户价值",
  963. ["缺料从现场前移到计划阶段", "采购与计划共享同一优先级", "争取催交、替代与调序窗口"],
  964. TEAL, "系统 UAT 实测界面",
  965. )
  966. page += 1
  967. # 08 S4-S5
  968. screenshot_feature_slide(
  969. prs, page, "S4–S5|采购到货、IQC 与库存状态贯通",
  970. "从供应商交付到来料检验、入库和领料,每一步保留数量、批次与质量状态",
  971. IQC_SHOTS / "20260811-2306-提交检验结果合格-IQC202608110002.png",
  972. "系统能力",
  973. ["采购交货、部分到货与延期跟踪", "IQC 检验、判定、复检与审批", "库存、批次、库位及生产领退料"],
  974. "客户价值",
  975. ["避免不合格物料误入生产", "质量退货与补货形成闭环", "库存流向可追溯到业务来源"],
  976. AMBER, "系统 UAT 实测界面",
  977. )
  978. page += 1
  979. # 09 S6-S7
  980. screenshot_feature_slide(
  981. prs, page, "S6–S7|生产执行、成品质量与交付反馈",
  982. "投产、报工、过程检验、成品检验和发运结果持续反馈给计划与交付",
  983. DASHBOARD_SHOTS / "S6-dashboard.png",
  984. "系统能力",
  985. ["工序报工、在制与末道完成跟踪", "IPQC / FQC 质量判定与复检", "成品入库、库存和销售发运"],
  986. "客户价值",
  987. ["执行偏差及时暴露", "进度反向更新交付风险", "客户催单时能回答当前真实状态"],
  988. CYAN, "系统 UAT 实测界面",
  989. )
  990. page += 1
  991. # 10 S8-S9
  992. screenshot_feature_slide(
  993. prs, page, "S8–S9|从经营红灯到责任明确的改善行动",
  994. "看板、异常监控、智慧诊断、个人任务和改善台账形成完整管理闭环",
  995. DASHBOARD_SHOTS / "S9-dashboard.png",
  996. "系统能力",
  997. ["规则监控并自动生成异常事件", "九宫格、模块看板与事实下钻", "诊断后创建计划、审批与行动项"],
  998. "客户价值",
  999. ["风险无需等待人工汇报", "责任、时限和处理过程全程留痕", "改善前后效果可验证、可沉淀"],
  1000. RED, "系统 UAT 实测界面",
  1001. )
  1002. page += 1
  1003. # 11 Dual entry
  1004. slide = base_slide(prs, "双入口:管理者看全局,每个人办自己的事", page, "同一套业务事实,按角色提供经营驾驶舱与个人工作台")
  1005. add_rect(slide, 0.62, 1.78, 5.72, 2.25, PALE_BLUE, BLUE)
  1006. add_pill(slide, "经营视角", 0.92, 2.03, 1.18, BLUE)
  1007. add_text(slide, "九宫格经营驾驶舱", 0.92, 2.58, 4.9, 0.46, 20, NAVY, True)
  1008. add_bullets(slide, ["查看全厂健康与红黄灯", "下钻模块、指标和业务事实", "面向厂长与运营管理层"], 0.94, 3.08, 4.95, 0.72, 11.5, spacing=3, accent=BLUE)
  1009. add_rect(slide, 6.98, 1.78, 5.72, 2.25, PALE_TEAL, TEAL)
  1010. add_pill(slide, "个人视角", 7.28, 2.03, 1.18, TEAL)
  1011. add_text(slide, "我的工作台", 7.28, 2.58, 4.9, 0.46, 20, NAVY, True)
  1012. add_bullets(slide, ["聚合行动项、审批与 S8 任务", "显示未读消息和到期提醒", "面向部门长、工程师与业务人员"], 7.3, 3.08, 4.95, 0.72, 11.5, spacing=3, accent=TEAL)
  1013. flow(slide, ["异常 / 改善 / 审批", "持久化站内信", "在线实时提醒", "工作台刷新", "深链处理", "结果留痕"], 4.52, 0.62, 12.08, [RED, AMBER, CYAN, TEAL, BLUE, NAVY], 10.5)
  1014. add_text(slide, "在线即时提醒,离线后重新登录仍能看到未读和待办;任务只进入明确责任人的工作台。", 1.05, 5.68, 11.2, 0.56, 13.5, NAVY, True, PP_ALIGN.CENTER, MSO_ANCHOR.MIDDLE)
  1015. page += 1
  1016. # 12 Dashboard screenshots
  1017. screenshot_pair_slide(
  1018. prs, page, "实际界面|动态运营看板",
  1019. "统一筛选、分层指标、红黄绿状态和业务下钻,让管理层与业务人员看到同一事实",
  1020. DASHBOARD_SHOTS / "S1-dashboard.png", "S1 产销协同看板",
  1021. DASHBOARD_SHOTS / "S3-dashboard.png", "S3 供应协同看板",
  1022. "系统 UAT 实测界面",
  1023. )
  1024. page += 1
  1025. # 13 Diagnosis + improvement
  1026. slide = base_slide(prs, "智慧诊断与改善闭环", page, "不只告诉管理者“红了”,还要说明原因、责任和改善结果")
  1027. flow(slide, ["发现偏差", "下钻事实", "确认根因", "创建计划", "正式审批", "自动派发", "执行反馈", "效果评价"], 1.82, 0.5, 12.35, [RED, AMBER, BLUE, CYAN, TEAL, GREEN, NAVY], 10)
  1028. loop_cards = [
  1029. ("事实可验证", "诊断结论回到订单、工单、物料、检验单和异常事件。", BLUE),
  1030. ("责任可落实", "行动项明确系统用户、截止日期,并进入个人工作台。", TEAL),
  1031. ("过程可提醒", "在线实时通知,离线保留未读,到期与逾期持续提醒。", AMBER),
  1032. ("结果可评价", "改善前后指标、执行证据、审批和日志统一沉淀。", NAVY),
  1033. ]
  1034. for i, (head, body, color) in enumerate(loop_cards):
  1035. x = 0.72 + (i % 2) * 6.18
  1036. y = 3.22 + (i // 2) * 1.62
  1037. card(slide, head, body, x, y, 5.68, 1.26, color, i + 1)
  1038. page += 1
  1039. # 14 Integration mode
  1040. slide = base_slide(prs, "既能独立运行,也能连接现有系统", page, "从一个高价值场景开始,按客户现状逐步连接和扩展")
  1041. add_rect(slide, 0.68, 1.82, 5.85, 3.72, PALE_BLUE, BLUE)
  1042. add_text(slide, "独立作业模式", 1.0, 2.08, 5.2, 0.48, 21, BLUE, True, PP_ALIGN.CENTER)
  1043. add_bullets(slide, ["在平台内维护主数据与业务规则", "完成计划、协同、执行、异常和改善", "适合新工厂、试点场景和快速上线"], 1.12, 2.82, 4.95, 1.88, 15, accent=BLUE)
  1044. add_rect(slide, 6.82, 1.82, 5.85, 3.72, PALE_TEAL, TEAL)
  1045. add_text(slide, "集成协同模式", 7.14, 2.08, 5.2, 0.48, 21, TEAL, True, PP_ALIGN.CENTER)
  1046. add_bullets(slide, ["连接客户现有 ERP / MES / WMS", "汇聚订单、生产、采购、库存和质量数据", "通过数据中台标准化、对账并构建指标"], 7.26, 2.82, 4.95, 1.88, 15, accent=TEAL)
  1047. add_rect(slide, 1.72, 5.98, 9.9, 0.65, NAVY, NAVY)
  1048. add_text(slide, "不要求一次性替换全部系统,优先证明一个场景能够产生业务结果", 1.95, 6.13, 9.45, 0.3, 14, WHITE, True, PP_ALIGN.CENTER)
  1049. page += 1
  1050. # 15 Order scenario
  1051. scenario_case_slide(
  1052. prs, page, "场景一|客户插单,能不能承诺交期?",
  1053. "一页看清业务背景、平台处理过程、真实界面和客户价值",
  1054. FLOW_SHOTS / "S1-04c-review-with-wo.png",
  1055. "高优先级订单要求快速确认交期,但设计、物料、产能和现有订单影响分散在不同部门。",
  1056. ["统一订单评审、优先级与交期依据", "生成工单并联动需求、排程和齐套", "持续跟踪执行进度与交付风险"],
  1057. ["承诺更快", "依据更可信", "变化可追踪", "风险可预警"],
  1058. BLUE, "系统 UAT 实测界面",
  1059. )
  1060. page += 1
  1061. # 16 Material scenario
  1062. scenario_case_slide(
  1063. prs, page, "场景二|关键物料延期,生产会不会停?",
  1064. "把缺料救火前移为供应风险协同",
  1065. DASHBOARD_SHOTS / "S3-dashboard.png",
  1066. "关键供应商部分到货,多张工单争用同一物料,采购知道延期但计划尚未调整。",
  1067. ["按工单和 BOM 计算真实需求", "结合库存、在途和交货计划识别缺口", "按受影响订单确定催交、替代和调序优先级"],
  1068. ["缺料前置", "优先级统一", "协同透明", "减少停线"],
  1069. AMBER, "系统 UAT 实测界面",
  1070. )
  1071. page += 1
  1072. # 17 Quality scenario
  1073. scenario_case_slide(
  1074. prs, page, "场景三|质量异常如何避免重复发生?",
  1075. "来料、过程、成品质量与异常改善形成同一条证据链",
  1076. IQC_SHOTS / "20260811-2306-提交检验结果合格-IQC202608110002.png",
  1077. "关键来料 IQC 不合格并影响生产齐套,后续 IPQC、FQC 也需要持续关注。",
  1078. ["统一检验规则、批次和质量状态", "异常关联供应商、物料、工单与订单", "整改进入审批、责任分派和效果验证"],
  1079. ["质量可追溯", "库存受控", "责任闭环", "改善可验证"],
  1080. RED, "系统 UAT 实测界面",
  1081. )
  1082. page += 1
  1083. # 18 Management scenario
  1084. scenario_case_slide(
  1085. prs, page, "场景四|指标变红,如何找到根因并推动解决?",
  1086. "从经营驾驶舱下钻到业务事实,再把事实转成责任明确的改善行动",
  1087. DASHBOARD_SHOTS / "S1-dashboard.png",
  1088. "传统看板只能显示红灯,原因和行动散落在会议纪要,过一段时间无法确认是否真正解决。",
  1089. ["九宫格发现风险,模块看板定位指标", "智慧诊断关联订单、工单、物料和异常", "形成改善计划、个人任务、提醒和效果评价"],
  1090. ["少听汇报", "快速抓重点", "基于事实决策", "经验可沉淀"],
  1091. TEAL, "系统 UAT 实测界面",
  1092. )
  1093. page += 1
  1094. # 19 Demo data + users
  1095. slide = base_slide(prs, "业务演示数据与使用角色", page, "演示覆盖真实业务对象,不是只有静态看板")
  1096. metrics = [("3", "业务场景数据集"), ("169", "每组 KPI"), ("55", "销售订单"), ("238", "工单"), ("约 40", "S8 异常")]
  1097. for i, (value, label) in enumerate(metrics):
  1098. add_metric(slide, value, label, 0.55 + i * 2.53, 1.72, 2.25, [NAVY, BLUE, CYAN, TEAL, RED][i])
  1099. roles = [
  1100. ("厂长 / 运营", "经营健康、风险和改善结果"),
  1101. ("销售 / 计划", "订单评审、交期和排程"),
  1102. ("采购 / 仓库", "齐套、交付、收发存"),
  1103. ("生产 / 质量", "报工、检验和异常处置"),
  1104. ]
  1105. for i, (role, focus) in enumerate(roles):
  1106. x = 0.72 + i * 3.12
  1107. card(slide, role, focus, x, 3.72, 2.82, 1.7, [NAVY, BLUE, AMBER, RED][i], i + 1)
  1108. add_rect(slide, 1.48, 5.92, 10.38, 0.62, PALE_TEAL, TEAL)
  1109. add_text(slide, "同一套数据 · 不同角色视角 · 统一责任 · 协同处置", 1.72, 6.07, 9.9, 0.28, 14, NAVY, True, PP_ALIGN.CENTER)
  1110. page += 1
  1111. # 20 Role journeys
  1112. slide = base_slide(prs, "三个典型角色,每天如何使用平台", page, "管理层看全局、部门长抓闭环、工程师办任务")
  1113. journeys = [
  1114. ("厂长", ["九宫格看健康", "下钻关键红灯", "查看改善结果"], "少听汇报,快速抓重点", NAVY),
  1115. ("部门长", ["模块看板看偏差", "确认 S8 责任", "分派并跟踪结果"], "统一部门重点,过程透明", BLUE),
  1116. ("工程师", ["工作台接收任务", "深链核对事实", "反馈证据与结果"], "减少查数,明确期限", TEAL),
  1117. ]
  1118. for i, (role, steps, result, color) in enumerate(journeys):
  1119. x = 0.62 + i * 4.22
  1120. add_rect(slide, x, 1.82, 3.75, 4.68, LIGHT, LINE)
  1121. add_pill(slide, role, x + 0.95, 2.08, 1.85, color, WHITE, 13)
  1122. for j, step in enumerate(steps):
  1123. add_rect(slide, x + 0.42, 2.88 + j * 0.82, 2.92, 0.58, WHITE, color)
  1124. add_text(slide, f"{j + 1} {step}", x + 0.58, 2.99 + j * 0.82, 2.58, 0.3, 11.5, NAVY, True, PP_ALIGN.CENTER)
  1125. add_text(slide, result, x + 0.42, 5.55, 2.92, 0.52, 13, color, True, PP_ALIGN.CENTER, MSO_ANCHOR.MIDDLE)
  1126. page += 1
  1127. # 21 Customer value
  1128. slide = base_slide(prs, "客户最终获得的,不是“更多报表”", page, "五类能够持续积累、可以用客户基线量化的制造运营能力")
  1129. vals = [
  1130. ("01", "交付更可预测", "订单、物料、产能和执行联动", BLUE),
  1131. ("02", "库存更可控", "按真实需求组织采购、收货和领退料", TEAL),
  1132. ("03", "质量更可追溯", "来料、过程、成品和供应商闭环", RED),
  1133. ("04", "异常响应更快", "自动发现、责任分派、超时升级", AMBER),
  1134. ("05", "管理持续改善", "指标、事实、行动和效果统一沉淀", NAVY),
  1135. ]
  1136. for i, (num, head, body, color) in enumerate(vals):
  1137. x = 0.7 + i * 2.5
  1138. add_rect(slide, x, 1.82, 2.2, 4.08, LIGHT, LINE)
  1139. add_text(slide, num, x + 0.18, 2.08, 1.84, 0.55, 26, color, True, PP_ALIGN.CENTER)
  1140. add_rect(slide, x + 0.55, 2.82, 1.1, 0.07, color, color, False)
  1141. add_text(slide, head, x + 0.18, 3.22, 1.84, 0.7, 16, NAVY, True, PP_ALIGN.CENTER, MSO_ANCHOR.MIDDLE)
  1142. add_text(slide, body, x + 0.25, 4.38, 1.7, 0.9, 11, MUTED, align=PP_ALIGN.CENTER, valign=MSO_ANCHOR.MIDDLE)
  1143. add_text(slide, "建议用客户自己的交期、停线、库存、质量和异常关闭基线,设定试点量化目标。", 1.05, 6.28, 11.2, 0.34, 12.5, NAVY, True, PP_ALIGN.CENTER)
  1144. page += 1
  1145. # 22 Fit + discovery questions
  1146. slide = base_slide(prs, "适合的客户与销售切入问题", page, "从高频运营痛点切入,比从模块清单切入更容易形成共识")
  1147. add_pill(slide, "典型客户特征", 0.62, 1.75, 1.65, BLUE)
  1148. fits = [
  1149. ("业务复杂", "多品种、小批量、订单变化频繁"),
  1150. ("系统分散", "已有 ERP / MES / WMS,跨系统仍靠 Excel"),
  1151. ("痛点明确", "交付、缺料、质量和在制透明度不足"),
  1152. ("重视改善", "不满足于看板,希望形成行动闭环"),
  1153. ]
  1154. for i, (head, body) in enumerate(fits):
  1155. x = 0.62 + (i % 2) * 3.05
  1156. y = 2.3 + (i // 2) * 1.72
  1157. card(slide, head, body, x, y, 2.72, 1.35, [NAVY, BLUE, CYAN, TEAL][i], i + 1)
  1158. add_pill(slide, "首次访谈四问", 6.92, 1.75, 1.65, TEAL)
  1159. questions = [
  1160. "哪类订单最容易延期?通常到哪个环节才发现?",
  1161. "缺料清单由谁维护?计划、采购和仓库是否一致?",
  1162. "质量异常关闭后,如何确认没有再次发生?",
  1163. "看板红灯能否追到单据、责任人和行动?",
  1164. ]
  1165. for i, q in enumerate(questions):
  1166. y = 2.28 + i * 0.92
  1167. add_rect(slide, 6.92, y, 5.72, 0.7, LIGHT, LINE)
  1168. add_text(slide, str(i + 1), 7.12, y + 0.16, 0.42, 0.3, 14, TEAL, True, PP_ALIGN.CENTER)
  1169. add_text(slide, q, 7.68, y + 0.12, 4.62, 0.4, 12.5, NAVY, True)
  1170. add_rect(slide, 7.22, 6.12, 5.12, 0.52, NAVY, NAVY)
  1171. add_text(slide, "找到可量化场景 → 用客户业务对象演示 → 写入试点目标", 7.4, 6.23, 4.76, 0.26, 10.5, WHITE, True, PP_ALIGN.CENTER)
  1172. page += 1
  1173. # 23 Implementation + demo route
  1174. slide = base_slide(prs, "典型落地路径与现场演示路线", page, "先证明一个场景产生业务结果,再逐步复制和扩展")
  1175. add_pill(slide, "落地路径", 0.58, 1.72, 1.22, BLUE)
  1176. stages = [("1", "业务诊断"), ("2", "运营建模"), ("3", "场景试点"), ("4", "系统连接"), ("5", "运营推广"), ("6", "持续优化")]
  1177. for i, (num, head) in enumerate(stages):
  1178. x = 0.58 + i * 2.08
  1179. add_rect(slide, x, 2.24, 1.75, 1.28, LIGHT, LINE)
  1180. add_text(slide, num, x + 0.12, 2.4, 0.42, 0.34, 15, [NAVY, BLUE, CYAN, TEAL, AMBER, RED][i], True, PP_ALIGN.CENTER)
  1181. add_text(slide, head, x + 0.48, 2.38, 1.1, 0.38, 12, NAVY, True, PP_ALIGN.CENTER)
  1182. if i < len(stages) - 1:
  1183. add_text(slide, "›", x + 1.73, 2.6, 0.3, 0.36, 18, CYAN, True, PP_ALIGN.CENTER)
  1184. add_pill(slide, "20–30 分钟演示路线", 0.58, 4.02, 2.05, TEAL)
  1185. route = ["九宫格", "模块看板", "智慧诊断", "改善计划", "我的工作台", "通知深链", "效果台账"]
  1186. flow(slide, route, 4.58, 0.58, 12.18, [NAVY, BLUE, CYAN, TEAL, AMBER, GREEN, NAVY], 10.5)
  1187. add_rect(slide, 1.25, 5.88, 10.82, 0.68, PALE_TEAL, TEAL)
  1188. add_text(slide, "现场演示始终围绕一个真实业务问题,从总览下钻到事实,再回到责任人与改善结果。", 1.5, 6.05, 10.32, 0.3, 13, NAVY, True, PP_ALIGN.CENTER)
  1189. page += 1
  1190. # 24 Closing
  1191. slide = prs.slides.add_slide(prs.slide_layouts[6])
  1192. slide.background.fill.solid()
  1193. slide.background.fill.fore_color.rgb = NAVY
  1194. add_text(slide, "让制造运营从“事后解释”", 0.78, 2.12, 11.8, 0.65, 30, WHITE, True, PP_ALIGN.CENTER)
  1195. add_text(slide, "走向“事前预警 · 协同处置 · 持续改善”", 0.78, 2.98, 11.8, 0.72, 30, CYAN, True, PP_ALIGN.CENTER)
  1196. add_rect(slide, 3.25, 4.05, 6.85, 0.07, CYAN, CYAN, False)
  1197. add_text(slide, "从一个高价值场景开始,建立可复制的制造运营能力", 1.35, 4.58, 10.65, 0.58, 20, WHITE, True, PP_ALIGN.CENTER)
  1198. add_text(slide, SYSTEM_NAME, 1.0, 5.72, 11.35, 0.48, 17, RGBColor(204, 219, 234), True, PP_ALIGN.CENTER)
  1199. add_footer(slide, page, dark=True)
  1200. OUTPUT.parent.mkdir(parents=True, exist_ok=True)
  1201. prs.save(OUTPUT)
  1202. print(OUTPUT)
  1203. print(f"slides={len(prs.slides)}")
  1204. def build_layered():
  1205. """Generate the layered, screenshot-led system introduction."""
  1206. prs = Presentation()
  1207. prs.slide_width = Inches(W)
  1208. prs.slide_height = Inches(H)
  1209. prs.core_properties.title = f"{SYSTEM_NAME}系统介绍"
  1210. prs.core_properties.subject = "经营决策、业务协同、数据连接与典型场景"
  1211. prs.core_properties.author = SYSTEM_NAME
  1212. prs.core_properties.comments = "按三层功能架构组织,全部功能介绍使用真实系统界面"
  1213. page = 1
  1214. # 01 Cover
  1215. slide = prs.slides.add_slide(prs.slide_layouts[6])
  1216. slide.background.fill.solid()
  1217. slide.background.fill.fore_color.rgb = NAVY
  1218. add_pill(slide, "系统介绍", 0.68, 1.72, 1.25, CYAN)
  1219. add_text(slide, SYSTEM_NAME, 0.68, 2.35, 11.9, 1.08, 31, WHITE, True)
  1220. add_text(slide, "连接数据、业务与责任,让制造运营从看见问题走向闭环改善", 0.72, 3.62, 11.3, 0.62, 19, RGBColor(204, 219, 234))
  1221. add_rect(slide, 0.72, 4.55, 6.4, 0.06, CYAN, CYAN, False)
  1222. add_text(slide, "经营决策 · 业务协同 · 数据连接 · 场景闭环", 0.72, 4.92, 11.6, 0.5, 16, CYAN, True)
  1223. add_text(slide, "销售 / 售前 / 客户业务交流版", 0.72, 6.25, 4.8, 0.3, 11, RGBColor(190, 202, 214))
  1224. add_footer(slide, page, dark=True)
  1225. page += 1
  1226. # 02 Directory
  1227. slide = base_slide(prs, "目录", page, "从平台定位到三层功能,再用典型场景说明业务价值")
  1228. sections = [
  1229. ("01", "平台定位与全景", "为什么建设 · 三层架构 · 运营闭环", "03–05", NAVY),
  1230. ("02", "经营决策层", "九宫格 · S9 · 工作台 · 诊断 · 改善", "06–11", BLUE),
  1231. ("03", "业务协同层", "订单 · 计划 · 供应 · 生产 · 质量 · 仓储 · 异常", "12–19", CYAN),
  1232. ("04", "数据连接层", "ERP/MES/WMS · 数据中台 · DWD/KPI", "20–23", TEAL),
  1233. ("05", "场景与落地", "四类典型场景 · 使用角色 · 建设路径", "24–29", AMBER),
  1234. ]
  1235. for i, (num, head, body, pages, color) in enumerate(sections):
  1236. x = 0.72 + (i % 3) * 4.18
  1237. y = 1.72 + (i // 3) * 2.28
  1238. w = 3.78 if i < 3 else 5.85
  1239. if i >= 3:
  1240. x = 0.72 + (i - 3) * 6.18
  1241. add_rect(slide, x, y, w, 1.72, LIGHT, LINE)
  1242. add_text(slide, num, x + 0.2, y + 0.2, 0.7, 0.45, 20, color, True)
  1243. add_text(slide, head, x + 0.92, y + 0.18, w - 1.55, 0.42, 16, NAVY, True)
  1244. add_text(slide, body, x + 0.25, y + 0.78, w - 0.5, 0.5, 10.5, MUTED, align=PP_ALIGN.CENTER)
  1245. add_pill(slide, pages, x + w - 0.82, y + 0.2, 0.58, color, WHITE, 9)
  1246. page += 1
  1247. # 03 Why
  1248. slide = base_slide(prs, "为什么需要制造业数据智能运营平台", page, "企业并不缺系统,缺的是跨系统、跨部门的统一运营闭环")
  1249. pains = [
  1250. ("数据分散", "订单、计划、供应、仓储、生产和质量口径不一致。", BLUE),
  1251. ("风险滞后", "缺料、延期、质量与设备问题到现场才暴露。", AMBER),
  1252. ("协同靠人", "会议、群聊和 Excel 承担责任分派与进度跟踪。", RED),
  1253. ("看板不闭环", "红灯能看见,但根因、任务和改善效果无法持续追踪。", TEAL),
  1254. ]
  1255. for i, (head, body, color) in enumerate(pains):
  1256. card(slide, head, body, 0.55 + i * 3.15, 1.72, 2.85, 1.52, color, i + 1)
  1257. add_rect(slide, 0.95, 3.75, 11.42, 2.2, PALE_BLUE, BLUE)
  1258. add_text(slide, "平台定位", 1.22, 4.02, 1.25, 0.38, 15, BLUE, True)
  1259. add_text(slide, "不是替代 ERP、MES、WMS,而是在现有系统之上建立统一的制造运营协同层", 2.35, 3.96, 9.45, 0.52, 18, NAVY, True, PP_ALIGN.CENTER)
  1260. add_text(slide, "统一事实 → 提前预警 → 跨部门协同 → 责任闭环 → 持续改善", 1.35, 4.92, 10.75, 0.48, 16, TEAL, True, PP_ALIGN.CENTER)
  1261. page += 1
  1262. # 04 Functional architecture
  1263. slide = base_slide(prs, "系统功能划分:三层能力共同形成运营闭环", page, "每层解决不同问题,三层使用同一套业务事实与责任链路")
  1264. layers = [
  1265. ("经营决策层", "九宫格 · 我的工作台 · 智慧诊断 · 改善台账", NAVY, WHITE, "看全局、抓重点、推改善"),
  1266. ("业务协同层", "订单 · 计划 · 供应 · 生产 · 质量 · 仓储 · 异常", CYAN, WHITE, "跨部门围绕同一业务对象协同"),
  1267. ("数据连接层", "现有 ERP / MES / WMS · 数据中台 · DWD / KPI", PALE_BLUE, NAVY, "接入、治理、建模并形成可信指标"),
  1268. ]
  1269. for i, (head, body, color, tc, value) in enumerate(layers):
  1270. x = 0.82 + i * 0.46
  1271. y = 1.72 + i * 1.45
  1272. w = 11.7 - i * 0.92
  1273. add_rect(slide, x, y, w, 1.05, color, color)
  1274. add_text(slide, head, x + 0.22, y + 0.16, 1.8, 0.34, 14, tc, True)
  1275. add_text(slide, body, x + 2.08, y + 0.13, w - 4.0, 0.42, 14, tc, True, PP_ALIGN.CENTER)
  1276. add_text(slide, value, x + w - 2.12, y + 0.18, 1.86, 0.5, 9.5, tc, True, PP_ALIGN.CENTER)
  1277. add_rect(slide, 1.62, 6.22, 10.12, 0.5, PALE_TEAL, TEAL)
  1278. add_text(slide, "数据成为事实,事实驱动协同,协同产生行动,行动回写经营结果", 1.88, 6.33, 9.6, 0.26, 13, NAVY, True, PP_ALIGN.CENTER)
  1279. page += 1
  1280. # 05 Loop
  1281. slide = base_slide(prs, "一条完整的制造运营闭环", page, "上一步结果成为下一步输入,现场变化反向影响计划与客户承诺")
  1282. flow(slide, ["订单评审", "工单排程", "物料齐套", "采购到货", "仓储检验", "生产执行", "成品发运"], 1.82, 0.48, 12.4, font_size=10.5)
  1283. flow(slide, ["异常发现", "责任分派", "业务处置", "指标诊断", "改善审批", "行动执行", "效果验证"], 3.12, 0.48, 12.4, [RED, AMBER, BLUE, CYAN, TEAL, GREEN, NAVY], 10.5)
  1284. add_rect(slide, 0.85, 4.62, 11.65, 1.52, PALE_TEAL, CYAN)
  1285. add_text(slide, "业务结果", 1.1, 4.92, 1.3, 0.38, 15, TEAL, True)
  1286. add_text(slide, "订单交期更可信 · 缺料风险更前置 · 生产执行更透明 · 质量问题更可追溯", 2.25, 4.86, 9.8, 0.48, 15, NAVY, True, PP_ALIGN.CENTER)
  1287. add_text(slide, "管理结果", 1.1, 5.56, 1.3, 0.38, 15, TEAL, True)
  1288. add_text(slide, "异常有人接 · 任务有人办 · 到期有人催 · 改善结果有人验证", 2.25, 5.5, 9.8, 0.48, 15, NAVY, True, PP_ALIGN.CENTER)
  1289. page += 1
  1290. # 06 Decision overview
  1291. screenshot_quad_slide(
  1292. prs, page, "经营决策层|从全局态势到个人行动",
  1293. "四类真实系统界面共同完成“看见问题—定位原因—推动行动—验证结果”",
  1294. [
  1295. (SYSTEM_SHOTS / "decision-grid.png", "九宫格经营驾驶舱"),
  1296. (SYSTEM_SHOTS / "decision-workbench.png", "我的工作台"),
  1297. (SYSTEM_SHOTS / "decision-diagnosis.png", "智慧诊断"),
  1298. (SYSTEM_SHOTS / "decision-improvement-ledger.png", "改善计划台账"),
  1299. ],
  1300. "系统 Demo 实测界面",
  1301. )
  1302. page += 1
  1303. # 07 Grid
  1304. screenshot_feature_slide(
  1305. prs, page, "九宫格|整厂经营态势一屏掌握",
  1306. "把 S1–S9 关键状态、异常趋势和经营指标集中到统一驾驶舱",
  1307. SYSTEM_SHOTS / "decision-grid.png",
  1308. "系统能力", ["模块红黄绿状态总览", "关键指标、异常趋势与风险分布", "一键下钻模块看板和业务事实"],
  1309. "管理价值", ["减少逐部门收集汇报", "快速识别跨模块风险", "统一当天经营重点"],
  1310. BLUE, "系统 Demo 实测界面",
  1311. )
  1312. page += 1
  1313. # 08 S9
  1314. screenshot_feature_slide(
  1315. prs, page, "S9|整厂宏观运营指标看板",
  1316. "S9 面向整厂经营管理,不是单一业务模块看板",
  1317. DASHBOARD_SHOTS / "S9-dashboard.png",
  1318. "宏观指标", ["质量损耗率、订单交付周期", "订单准时满足率、生产效率", "全库利用率及整厂级目标差距"],
  1319. "管理价值", ["统一厂级指标口径", "跨模块观察经营结果", "从宏观偏差进入诊断与改善"],
  1320. NAVY, "系统 UAT 实测界面",
  1321. )
  1322. page += 1
  1323. # 09 Workbench
  1324. screenshot_feature_slide(
  1325. prs, page, "我的工作台|每个人只处理自己的任务",
  1326. "行动项、审批、S8 事项和未读消息按责任人统一聚合",
  1327. SYSTEM_SHOTS / "decision-workbench.png",
  1328. "任务聚合", ["改善行动项与到期状态", "审批待办、S8 事项和未读消息", "通知深链直接进入业务处理页"],
  1329. "使用价值", ["减少跨系统找任务", "责任和截止日期清晰", "在线提醒、离线登录仍可恢复"],
  1330. TEAL, "系统 Demo 实测界面",
  1331. )
  1332. page += 1
  1333. # 10 Diagnosis
  1334. screenshot_feature_slide(
  1335. prs, page, "智慧诊断|从指标偏差下钻到主要问题",
  1336. "以指标目标与现状为起点,形成问题定位、改善计划和效果验证链路",
  1337. SYSTEM_SHOTS / "decision-diagnosis.png",
  1338. "诊断链路", ["目标与现状差距量化", "定位责任部门与主要问题", "关联预警、事实明细和下层指标"],
  1339. "使用价值", ["避免只看红灯不知原因", "用统一事实支持讨论", "诊断结果直接进入改善闭环"],
  1340. CYAN, "系统 Demo 实测界面",
  1341. )
  1342. page += 1
  1343. # 11 Improvement
  1344. screenshot_feature_slide(
  1345. prs, page, "改善台账|让改善计划、行动与评价持续留痕",
  1346. "从诊断结果创建计划,经过审批、任务分派、执行反馈和自动评价",
  1347. SYSTEM_SHOTS / "decision-improvement-ledger.png",
  1348. "闭环能力", ["计划状态、责任部门和到期日", "行动项分派、提醒与执行证据", "审批记录、逾期标识和效果评价"],
  1349. "管理价值", ["改善事项不再散落", "过程责任可追踪", "改善前后结果可验证、可复用"],
  1350. TEAL, "系统 Demo 实测界面",
  1351. )
  1352. page += 1
  1353. # 12 Collaboration overview
  1354. slide = base_slide(prs, "业务协同层|围绕订单贯通七类业务能力", page, "订单是需求起点,计划、供应、生产、质量、仓储和异常共同影响最终交付")
  1355. chain = [
  1356. ("01", "订单", "评审 · 承诺 · 交付", BLUE),
  1357. ("02", "计划", "排程 · 日计划 · 追踪", CYAN),
  1358. ("03", "供应", "需求 · 齐套 · 采购", TEAL),
  1359. ("04", "生产", "投产 · 报工 · 在制", BLUE),
  1360. ("05", "质量", "IQC · IPQC · FQC", RED),
  1361. ("06", "仓储", "库存 · 领退料 · 发运", AMBER),
  1362. ("07", "异常", "发现 · 分派 · 升级", NAVY),
  1363. ]
  1364. for i, (num, head, body, color) in enumerate(chain):
  1365. x = 0.48 + i * 1.82
  1366. add_rect(slide, x, 2.05, 1.58, 2.55, LIGHT, LINE)
  1367. add_text(slide, num, x + 0.14, 2.25, 1.3, 0.42, 19, color, True, PP_ALIGN.CENTER)
  1368. add_text(slide, head, x + 0.14, 2.95, 1.3, 0.42, 16, NAVY, True, PP_ALIGN.CENTER)
  1369. add_text(slide, body, x + 0.16, 3.65, 1.26, 0.62, 10, MUTED, align=PP_ALIGN.CENTER)
  1370. add_rect(slide, 0.85, 5.25, 11.65, 0.78, PALE_TEAL, TEAL)
  1371. add_text(slide, "统一业务对象:订单号 · 工单号 · 物料 · 批次 · 检验单 · 异常事件", 1.15, 5.46, 11.05, 0.35, 14, NAVY, True, PP_ALIGN.CENTER)
  1372. page += 1
  1373. # 13 Order
  1374. screenshot_feature_slide(
  1375. prs, page, "订单协同|从订单评审到交付跟踪",
  1376. "把设计、物料、产能和交期依据放在同一订单决策过程",
  1377. FLOW_SHOTS / "S1-04c-review-with-wo.png",
  1378. "核心功能", ["订单与合同评审", "交期确认、优先级与插单影响", "评审后生成工单并跟踪交付"],
  1379. "业务价值", ["承诺有依据", "订单状态透明", "变化影响可追踪"],
  1380. BLUE, "系统 UAT 实测界面",
  1381. )
  1382. page += 1
  1383. # 14 Planning
  1384. screenshot_feature_slide(
  1385. prs, page, "计划协同|把工单转成可执行日计划",
  1386. "综合产线能力、日历、物料齐套和优先级形成可执行排程",
  1387. FLOW_SHOTS / "S2-13-T3-schedule-ui.png",
  1388. "核心功能", ["工单工序排程", "产线日历与可执行日计划", "计划下达、异常记录和执行追踪"],
  1389. "业务价值", ["计划更可执行", "插单影响可解释", "计划与现场进度一致"],
  1390. CYAN, "系统 UAT 实测界面",
  1391. )
  1392. page += 1
  1393. # 15 Supply
  1394. screenshot_feature_slide(
  1395. prs, page, "供应协同|缺料风险前移到计划阶段",
  1396. "按订单和工单计算需求,结合库存、在途与交货计划识别真实缺口",
  1397. DASHBOARD_SHOTS / "S3-dashboard.png",
  1398. "核心功能", ["物料需求与交货计划", "齐套计算、缺料和供应商风险", "采购申请、订单、委外与催交"],
  1399. "业务价值", ["减少临停救火", "采购优先级统一", "供应影响可下钻"],
  1400. TEAL, "系统 UAT 实测界面",
  1401. )
  1402. page += 1
  1403. # 16 Production
  1404. screenshot_feature_slide(
  1405. prs, page, "生产协同|透明跟踪投产、报工与在制",
  1406. "让计划、车间和交付共同看到工单真实执行状态",
  1407. DASHBOARD_SHOTS / "S6-dashboard.png",
  1408. "核心功能", ["生产指令、工序与报工", "在制、末道完成和执行偏差", "车间效率、设备 OEE 与工时"],
  1409. "业务价值", ["现场状态透明", "偏差及时暴露", "进度反向更新交付风险"],
  1410. CYAN, "系统 UAT 实测界面",
  1411. )
  1412. page += 1
  1413. # 17 Quality
  1414. screenshot_feature_slide(
  1415. prs, page, "质量协同|贯通来料、过程与成品质量",
  1416. "检验规则、批次、判定、复检和审批形成完整证据链",
  1417. IQC_SHOTS / "20260811-2306-提交检验结果合格-IQC202608110002.png",
  1418. "核心功能", ["IQC / IPQC / FQC 检验任务", "结果录入、审核、退回与关单", "关联物料、供应商、工单和批次"],
  1419. "业务价值", ["质量状态受控", "问题来源可追溯", "整改与效果评价闭环"],
  1420. RED, "系统 UAT 实测界面",
  1421. )
  1422. page += 1
  1423. # 18 Warehouse
  1424. screenshot_feature_slide(
  1425. prs, page, "仓储协同|库存、批次与收发运全程可追溯",
  1426. "从采购收货、生产领退料到成品入库和发运统一数量与状态",
  1427. BID_SHOTS / "ui_s5_stock.png",
  1428. "核心功能", ["库存、批次、库位和状态查询", "采购收货、领料、退料与入库", "备料、发料、成品库存和发运"],
  1429. "业务价值", ["库存去向清楚", "质量状态隔离", "仓储结果反馈计划与交付"],
  1430. AMBER, "系统实际界面",
  1431. )
  1432. page += 1
  1433. # 19 Exception
  1434. screenshot_feature_slide(
  1435. prs, page, "异常协同|发现、分派、处置、验证和关闭",
  1436. "S8 汇聚交付、供应、生产、质量等异常,按角色形成责任闭环",
  1437. SYSTEM_SHOTS / "collaboration-exception-dashboard.png",
  1438. "核心功能", ["规则监控和主动提报", "认领、分派、转派、升级与驳回", "处理反馈、验证、关闭和时效统计"],
  1439. "业务价值", ["异常不再依赖人工汇报", "责任与时限明确", "全过程可追踪、可复盘"],
  1440. RED, "系统 Demo 实测界面",
  1441. )
  1442. page += 1
  1443. # 20 Data overview
  1444. screenshot_feature_slide(
  1445. prs, page, "数据连接层|从外部系统到业务消费与回写",
  1446. "数据地图展示来源、接入、治理、服务和业务消费的完整链路",
  1447. SYSTEM_SHOTS / "data-platform-map.png",
  1448. "连接范围", ["ERP / SAP、MES、WMS 等外部系统", "数据库同步、API 入站与文件接入", "API 出站、业务查询、看板与回写"],
  1449. "平台价值", ["保留现有系统投资", "形成统一数据路径", "异常和同步状态可观察"],
  1450. BLUE, "系统 Demo 实测界面",
  1451. )
  1452. page += 1
  1453. # 21 ERP/MES/WMS
  1454. screenshot_pair_slide(
  1455. prs, page, "现有 ERP / MES / WMS|标准化接入而非整体替换",
  1456. "通过数据库、API 和文件方式接入订单、生产、采购、库存与质量数据",
  1457. SYSTEM_SHOTS / "data-platform-sources.png", "数据源管理:连接与健康状态",
  1458. FLOW_SHOTS / "WMS-01-备料列表-SM20260810001.png", "WMS 实际业务界面:生产备料",
  1459. "系统 Demo / UAT 实测界面",
  1460. )
  1461. page += 1
  1462. # 22 Data platform
  1463. screenshot_pair_slide(
  1464. prs, page, "数据中台|统一管理接入、同步、日志与质量",
  1465. "数据接入不是一次性接口工程,而是可配置、可调度、可追踪的持续能力",
  1466. SYSTEM_SHOTS / "data-platform-overview.png", "数据中台工作台",
  1467. SYSTEM_SHOTS / "data-platform-sync-tasks.png", "同步配置中心",
  1468. "系统 Demo 实测界面",
  1469. )
  1470. page += 1
  1471. # 23 DWD/KPI
  1472. screenshot_pair_slide(
  1473. prs, page, "DWD / KPI|把原始数据变成可信运营指标",
  1474. "标准层统一业务对象,指标主数据定义层级、口径、责任与诊断关系",
  1475. SYSTEM_SHOTS / "data-kpi-master.png", "运营指标主数据与分层指标树",
  1476. DASHBOARD_SHOTS / "S9-dashboard.png", "整厂宏观运营指标结果",
  1477. "系统 Demo / UAT 实测界面",
  1478. )
  1479. page += 1
  1480. # 24 Scenario 1
  1481. scenario_case_slide(
  1482. prs, page, "场景一|业务协同层·订单承诺与交付协同环节",
  1483. "类型:跨部门订单协同场景|核心问题:客户插单后能否可信承诺交期",
  1484. FLOW_SHOTS / "S1-04c-review-with-wo.png",
  1485. "高优先级订单要求快速确认交期,但设计、物料、产能和现有订单影响分散在不同部门。",
  1486. ["统一评审交期、优先级和影响依据", "生成工单并联动需求、排程与齐套", "持续跟踪执行进度和交付风险"],
  1487. ["承诺更快", "依据更可信", "变化可追踪", "风险可预警"],
  1488. BLUE, "系统 UAT 实测界面",
  1489. )
  1490. page += 1
  1491. # 25 Scenario 2
  1492. scenario_case_slide(
  1493. prs, page, "场景二|业务协同层·供应缺料保障环节",
  1494. "类型:计划与供应协同场景|核心问题:关键物料延期是否会造成停线",
  1495. DASHBOARD_SHOTS / "S3-dashboard.png",
  1496. "关键供应商部分到货,多张工单争用同一物料,采购知道延期但计划尚未调整。",
  1497. ["按工单和 BOM 计算真实需求", "结合库存、在途和交货计划识别缺口", "按受影响订单确定催交、替代和调序优先级"],
  1498. ["缺料前置", "优先级统一", "协同透明", "减少停线"],
  1499. AMBER, "系统 UAT 实测界面",
  1500. )
  1501. page += 1
  1502. # 26 Scenario 3
  1503. scenario_case_slide(
  1504. prs, page, "场景三|业务协同层·质量异常闭环环节",
  1505. "类型:质量追溯与整改场景|核心问题:如何避免同类质量问题重复发生",
  1506. IQC_SHOTS / "20260811-2306-提交检验结果合格-IQC202608110002.png",
  1507. "关键来料出现质量问题并影响生产齐套,后续过程检验和成品检验也需要持续关注。",
  1508. ["统一检验规则、批次和质量状态", "异常关联供应商、物料、工单与订单", "整改进入审批、责任分派和效果验证"],
  1509. ["质量可追溯", "库存受控", "责任闭环", "改善可验证"],
  1510. RED, "系统 UAT 实测界面",
  1511. )
  1512. page += 1
  1513. # 27 Scenario 4
  1514. scenario_case_slide(
  1515. prs, page, "场景四|经营决策层·整厂运营决策环节",
  1516. "类型:管理驾驶舱与持续改善场景|核心问题:整厂指标变红后如何找到根因并推动解决",
  1517. SYSTEM_SHOTS / "decision-grid.png",
  1518. "传统看板只能显示红灯,原因和行动散落在会议纪要,过一段时间无法确认是否真正解决。",
  1519. ["九宫格识别风险,S9 查看整厂指标", "智慧诊断关联事实、责任部门和主要问题", "形成改善计划、个人任务、提醒和效果评价"],
  1520. ["少听汇报", "快速抓重点", "基于事实决策", "经验可沉淀"],
  1521. TEAL, "系统 Demo 实测界面",
  1522. )
  1523. page += 1
  1524. # 28 Roles
  1525. slide = base_slide(prs, "三个典型角色,每天如何使用平台", page, "管理层看全局、部门长抓闭环、工程师办任务")
  1526. journeys = [
  1527. ("厂长 / 运营", ["九宫格看整厂健康", "S9 识别宏观偏差", "查看改善结果"], "少听汇报,快速抓重点", NAVY),
  1528. ("部门负责人", ["模块看板看偏差", "确认异常与根因", "分派并跟踪行动"], "统一重点,过程透明", BLUE),
  1529. ("业务工程师", ["工作台接收任务", "深链核对业务事实", "反馈证据与结果"], "减少查数,明确期限", TEAL),
  1530. ]
  1531. for i, (role, steps, result, color) in enumerate(journeys):
  1532. x = 0.62 + i * 4.22
  1533. add_rect(slide, x, 1.82, 3.75, 4.68, LIGHT, LINE)
  1534. add_pill(slide, role, x + 0.72, 2.08, 2.3, color, WHITE, 13)
  1535. for j, step in enumerate(steps):
  1536. add_rect(slide, x + 0.42, 2.88 + j * 0.82, 2.92, 0.58, WHITE, color)
  1537. add_text(slide, f"{j + 1} {step}", x + 0.52, 2.99 + j * 0.82, 2.72, 0.3, 11, NAVY, True, PP_ALIGN.CENTER)
  1538. add_text(slide, result, x + 0.42, 5.55, 2.92, 0.52, 13, color, True, PP_ALIGN.CENTER, MSO_ANCHOR.MIDDLE)
  1539. page += 1
  1540. # 29 Implementation + value
  1541. slide = base_slide(prs, "从一个高价值场景开始,逐步形成整厂运营能力", page, "先建立基线并证明业务结果,再连接系统、复制场景和持续优化")
  1542. stages = [
  1543. ("1", "业务诊断"), ("2", "基线建模"), ("3", "场景试点"),
  1544. ("4", "系统连接"), ("5", "运营推广"), ("6", "持续优化"),
  1545. ]
  1546. for i, (num, head) in enumerate(stages):
  1547. x = 0.58 + i * 2.08
  1548. add_rect(slide, x, 1.85, 1.75, 1.18, LIGHT, LINE)
  1549. add_text(slide, num, x + 0.12, 2.18, 0.42, 0.34, 15, [NAVY, BLUE, CYAN, TEAL, AMBER, RED][i], True, PP_ALIGN.CENTER)
  1550. add_text(slide, head, x + 0.48, 2.15, 1.1, 0.38, 12, NAVY, True, PP_ALIGN.CENTER)
  1551. values = [
  1552. ("交付", "订单承诺更可信", BLUE),
  1553. ("供应", "缺料风险更前置", TEAL),
  1554. ("质量", "问题来源可追溯", RED),
  1555. ("异常", "响应与关闭更快", AMBER),
  1556. ("管理", "改善结果可验证", NAVY),
  1557. ]
  1558. for i, (head, body, color) in enumerate(values):
  1559. x = 0.72 + i * 2.5
  1560. add_rect(slide, x, 3.72, 2.18, 1.72, LIGHT, LINE)
  1561. add_text(slide, head, x + 0.2, 4.02, 1.78, 0.38, 17, color, True, PP_ALIGN.CENTER)
  1562. add_text(slide, body, x + 0.18, 4.62, 1.82, 0.4, 11, NAVY, True, PP_ALIGN.CENTER)
  1563. add_rect(slide, 1.25, 5.98, 10.82, 0.62, PALE_TEAL, TEAL)
  1564. add_text(slide, "建议以客户自己的交期、停线、库存、质量和异常关闭基线设定试点目标", 1.5, 6.12, 10.32, 0.3, 13, NAVY, True, PP_ALIGN.CENTER)
  1565. page += 1
  1566. # 30 Closing
  1567. slide = prs.slides.add_slide(prs.slide_layouts[6])
  1568. slide.background.fill.solid()
  1569. slide.background.fill.fore_color.rgb = NAVY
  1570. add_text(slide, "让制造运营从“事后解释”", 0.78, 2.12, 11.8, 0.65, 30, WHITE, True, PP_ALIGN.CENTER)
  1571. add_text(slide, "走向“事前预警 · 协同处置 · 持续改善”", 0.78, 2.98, 11.8, 0.72, 30, CYAN, True, PP_ALIGN.CENTER)
  1572. add_rect(slide, 3.25, 4.05, 6.85, 0.07, CYAN, CYAN, False)
  1573. add_text(slide, "从一个高价值场景开始,建立可复制的制造运营能力", 1.35, 4.58, 10.65, 0.58, 20, WHITE, True, PP_ALIGN.CENTER)
  1574. add_text(slide, SYSTEM_NAME, 1.0, 5.72, 11.35, 0.48, 17, RGBColor(204, 219, 234), True, PP_ALIGN.CENTER)
  1575. add_footer(slide, page, dark=True)
  1576. OUTPUT.parent.mkdir(parents=True, exist_ok=True)
  1577. prs.save(OUTPUT)
  1578. print(OUTPUT)
  1579. print(f"slides={len(prs.slides)}")
  1580. if __name__ == "__main__":
  1581. build_layered()