演示架构师-PPT大纲生成的HarmonyOS开发实践

App36-演示架构师:PPT大纲生成的HarmonyOS开发实践

引言

在职场沟通中,PPT演示文稿是仅次于口头表达的第二大信息传递载体。无论是产品发布会上的战略宣讲,还是内部周会上的项目汇报,一份结构清晰、逻辑严密的PPT大纲往往是成功演讲的基石。但现实是,大多数职场人并非专业的演示设计师------他们知道要讲什么,却不知道如何组织内容、如何划分章节、如何为每页幻灯片匹配合适的视觉元素。

据微软Office团队2024年发布的调研报告,全球每天有超过3500万场PPT演示在进行,但其中超过60%的演讲者表示「构建大纲」是他们最耗时的环节。更令人意外的是,受访者平均花费在PPT大纲设计上的时间,竟然超过了实际制作幻灯片的时间。这揭示了一个被长期忽视的痛点:内容结构化本身就是一个高门槛的脑力劳动。

正是在这样的背景下,我开发了「演示架构师」------一个基于HarmonyOS的AI PPT大纲生成工具。它的核心逻辑是:用户输入演示主题、目标受众和期望页数,系统通过AI能力自动生成一份结构化的演示文稿大纲,包含每页幻灯片的标题、要点列表和视觉建议。与传统的PPT模板工具不同,「演示架构师」不是简单地提供设计模板,而是真正介入内容层面------帮助用户构建「讲什么」的骨架。

本文将按照6A工作流(Align对齐、Architect架构、Atomize原子化、Approve审批、Automate自动化执行、Assess评估)来完整复盘「演示架构师」的设计与开发过程。文中将重点探讨PPT大纲结构化生成的核心挑战------场景化数据建模、多页幻灯片的逻辑连贯性、以及AI API Stub模式在前端先行开发中的应用。同时,我们将结合鸿蒙ArkUI框架、鸿蒙PC端适配策略以及鸿蒙Flutter框架的对比分析,为鸿蒙生态下的AI应用开发者提供体系化的技术参考。

---

一、Align对齐阶段:从模糊需求到精确规范

1.1 项目上下文分析

「演示架构师」是鸿蒙AI应用矩阵中的第36号应用,位于一个包含40个AI小应用的工程中。项目采用HarmonyOS NEXT(API 26)作为目标SDK,使用Stage模型和ArkTS/ArkUI声明式框架进行开发。在现有的应用分类体系中,它被划分到「AI创作」类别,与「文字抛光机」「名字炼金术」「镜头故事家」等应用共同构成了AI辅助内容创作的完整矩阵。

工程结构如下:

复制代码
e:\ai40\
├── entry/
│   ├── src/main/
│   │   ├── ets/pages/app36/Index.ets   # 应用主页面
│   │   ├── ets/pages/app1~40/          # 40个AI应用
│   │   ├── module.json5                # 模块配置
│   │   └── resources/                  # 资源文件
│   ├── build-profile.json5
│   └── oh-package.json5
├── build-profile.json5
└── oh-package.json5

通过分析兄弟应用(如app21「文字抛光机」、app35「家装计算器」、app37「镜头故事家」),我们识别出统一的设计模式:所有AI应用均采用Mock数据驱动的前端先行开发策略 ,通过generateMockData()方法模拟AI API的响应行为,在真实AI接口就绪前即可完成UI开发和交互验证。这种模式被称为AI API Stub模式,是鸿蒙生态中AI应用开发的推荐范式。

1.2 原始需求

「演示架构师」的原始需求可以概括为三个核心诉求:

  1. 主题输入:用户输入演示文稿的主题,如「人工智能发展趋势」「新能源汽车市场分析」
  2. 受众设定:用户指定目标受众,如「技术团队」「投资团队」「管理层」
  3. 页数控制:用户设定期望的幻灯片页数(3-30页范围)
  4. 大纲生成:系统生成结构化的演示大纲,每页包含标题、要点列表和视觉建议

这个需求看似简单直接,但在对齐阶段,我们需要挖掘出隐藏在表面之下的深层约束。

1.3 需求拆解与边界确认

在Align阶段,我们需要回答以下关键问题:

问题一:PPT大纲的「结构化」标准是什么?

一份专业的PPT大纲并非简单的标题列表,而是需要包含三个层次的信息:页面标题 (告诉观众这一页在讲什么)、核心要点 (支撑标题的论据或数据)、视觉建议(建议用什么类型的图表或视觉元素来呈现)。这三个层次的完整度,决定了生成的大纲是「可用」还是「敷衍」。

更重要的是,页面之间的逻辑关系必须连贯。第1页的封面引出主题,第2页的目录概述框架,第3-N页逐个展开论点,最后一页总结收尾。这种「起承转合」的结构是优秀演示文稿的共性特征,也是AI生成大纲时需要遵循的隐性规则。

问题二:受众如何影响大纲结构?

同一主题面对不同受众,大纲的结构和侧重点应该完全不同。以「人工智能发展趋势」为例:

  • 面对技术团队:侧重技术细节,如大模型参数规模、推理能力、多模态架构等,术语密度高
  • 面对投资团队:侧重商业价值,如市场规模、竞争格局、投资回报率等,数据驱动
  • 面对管理层:侧重战略影响,如组织变革、人才需求、风险评估等,决策导向

这意味着,受众参数不是简单的「标签」,而是大纲生成的核心约束条件。在大纲生成逻辑中,受众决定了内容的深度、广度、术语难度和论证方式。

问题三:页数如何影响信息密度?

用户设定的页数从3页到30页不等,跨度达到10倍。这意味着生成逻辑需要具备「弹性扩展」能力:

  • 3页大纲:封面 + 核心内容 + 总结,要点的信息密度极高
  • 10页大纲:封面 + 目录 + 6-7个主题页 + 总结,中等密度
  • 30页大纲:封面 + 目录 + 25+个主题页 + 总结,每个主题页聚焦一个细分观点

在Architect阶段,我们需要设计一种能够根据页数自适应调整内容粒度的机制。

问题四:视觉建议如何生成?

视觉建议是「演示架构师」区别于普通大纲生成器的核心差异化功能。它告诉用户每一页应该用什么视觉元素来辅助表达------是柱状图、饼图、时间轴,还是SWOT矩阵、雷达图、流程图。这些建议需要与页面内容高度相关,而不是随机分配。

问题五:边缘情况如何处理?

当用户输入的主题过于宽泛(如「科技」)、受众过于模糊(如「所有人」)、页数超出合理范围时,系统需要智能降级而非直接报错。我们设计了多层兜底策略:主题为空时使用默认主题,受众为空时默认为「通用受众」,页数超出3-30范围时自动钳制到边界值。

1.4 数据模型定义

基于以上分析,我们在对齐阶段定义了核心数据模型:

typescript 复制代码
// 单页幻灯片
interface SlideItem {
  title: string;      // 页面标题,如 "封面:人工智能发展趋势"
  points: string[];   // 核心要点,如 ["大模型演进", "多模态AI", "AI Agent"]
  visual: string;     // 视觉建议,如 "AI神经网络可视化背景图"
}

// 演示文稿结果
interface PresentationResult {
  slides: SlideItem[];   // 幻灯片列表
}

// 场景化数据
interface PresentationScenario {
  scenario: string;              // 场景键,如 "人工智能发展趋势_技术团队_10"
  result: PresentationResult;    // 对应的演示大纲
}

SlideItem是整个系统的核心数据单元。它的三个字段分别对应了演示文稿的三个设计维度:结构 (title决定了页面在整体叙述中的位置和角色)、内容 (points是页面要传达的核心信息)、视觉(visual是页面呈现方式的建议)。这三个维度的分离设计,使得我们可以独立地优化每个维度,而不影响其他两个。

PresentationScenario引入了场景键(Scenario Key)的概念。场景键由三个参数拼接而成:主题_受众_页数,例如人工智能发展趋势_技术团队_10。这种设计将多维度的用户输入压缩为一个可索引的字符串键,为后续的Mock数据匹配和AI API调用提供了统一的接口抽象。

1.5 共识文档关键结论

经过对齐讨论,我们达成了以下共识:

维度 决策
大纲结构 每页包含标题(title)、要点列表(points)、视觉建议(visual)三个字段
输入参数 3个参数:主题(自由文本)、受众(自由文本)、页数(3-30整数)
受众影响 受众作为核心约束条件,影响内容深度、术语难度和论证方式
页数弹性 支持3-30页的弹性范围,生成逻辑需自适应调整内容粒度
视觉建议 与页面内容高度相关,涵盖图表、矩阵、时间轴、流程图等类型
异常兜底 输入为空时使用默认值,页数超出范围时自动钳制
数据匹配 场景键精确匹配,匹配失败回退到默认场景
输出格式 JSON,固定Schema(PresentationResult),含slides数组

二、Architect架构阶段:从共识到系统设计

2.1 整体架构

「演示架构师」采用四层架构模型:UI交互层、状态管理层、数据匹配层和数据模型层。这种分层设计在鸿蒙ArkUI框架下实现了清晰的职责分离。

复制代码
┌────────────────────────────────────────────────────────────┐
│                       ArkUI 层                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  返回按钮 + 标题"演示架构师" + 副标题                  │  │
│  └──────────────────────────────────────────────────────┘  │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐                   │
│  │ 主题输入  │ │ 受众输入  │ │ 页数输入  │                   │
│  └──────────┘ └──────────┘ └──────────┘                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │           生成大纲 按钮(紫色主题)                    │  │
│  └──────────────────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  演示大纲 结果区域(条件渲染)                         │  │
│  │  ┌────────────────────────────────────────────────┐  │  │
│  │  │ P1 封面 ··· 标题 + 要点 + 视觉建议               │  │  │
│  │  │ P2 目录 ··· 标题 + 要点 + 视觉建议               │  │  │
│  │  │ ...  ForEach 遍历渲染                           │  │  │
│  │  └────────────────────────────────────────────────┘  │  │
│  └──────────────────────────────────────────────────────┘  │
└────────────────────────────────────────────────────────────┘
                          │
                          ▼
┌────────────────────────────────────────────────────────────┐
│                状态管理层(@State)                          │
│  topic, audience, slides, showResult, currentResult         │
└────────────────────────────────────────────────────────────┘
                          │
                          ▼
┌────────────────────────────────────────────────────────────┐
│                 数据匹配层                                   │
│  getMockData(): 场景键拼接 → 遍历匹配 → 返回结果            │
│  callAIAPI(): 预留,Prompt构建 → API调用 → JSON解析         │
└────────────────────────────────────────────────────────────┘
                          │
                          ▼
┌────────────────────────────────────────────────────────────┐
│                 数据模型层                                   │
│  SlideItem { title, points: string[], visual }              │
│  PresentationResult { slides: SlideItem[] }                 │
│  PresentationScenario { scenario, result }                  │
│  mockScenarios: PresentationScenario[] (3个场景)            │
└────────────────────────────────────────────────────────────┘

2.2 SlideItem模型与三要素设计

SlideItem是整个系统最核心的数据单元。它的设计承载了演示文稿领域特有的「结构化表达」语义:

typescript 复制代码
interface SlideItem {
  title: string;      // "封面:人工智能发展趋势"
  points: string[];   // ["2025年AI技术全景展望", "演讲人:AI研究团队"]
  visual: string;     // "AI神经网络可视化背景图"
}

三个字段各有其设计考量:

title的设计:标题不仅描述页面内容,还隐式地传达了页面在整体叙述中的角色。我们采用「角色前缀 + 核心内容」的命名模式,如「封面:人工智能发展趋势」「总结与展望」。这种模式让用户一眼就能理解每页的定位------是开篇、是过渡、是论证还是收官。

points的设计:要点列表是页面的内容骨架。在设计中,我们遵循「3-5个要点」的黄金法则------少于3个要点,页面信息量不足;多于5个要点,观众认知负荷过重。在Mock数据中,每页的要点数量严格控制在2-5个之间,确保用户体验的一致性。

visual的设计:视觉建议是「演示架构师」的差异化功能。它不只是简单的「图表」或「文字」,而是具体到「AI神经网络可视化背景图」「SWOT分析矩阵」「全球AI监管地图」这种粒度。这种具体性来自于对页面内容的深度理解------只有当系统知道这一页在讲什么时,它才能给出真正有用的视觉建议。

2.3 场景键(Scenario Key)设计

场景键是Mock数据匹配的核心机制。我们采用「参数拼接」策略,将用户输入的3个参数按照固定顺序拼接为一个字符串键:

复制代码
场景键格式:主题_受众_页数
示例:人工智能发展趋势_技术团队_10

这种设计有以下几个优点:

  1. 精确匹配:每个场景键唯一对应一个预置的演示大纲,匹配逻辑清晰,不会出现二义性。
  2. 可读性好:场景键本身就是对场景的完整描述,无需查看数据内容就能理解场景含义。
  3. 扩展简单 :新增场景只需在mockScenarios数组中追加一个新元素,键名遵循相同格式即可。
  4. 兜底友好 :当用户输入的参数组合没有预置Mock数据时,自动回退到mockScenarios[0](默认场景),确保用户始终能获得结果。

与App35「家装计算器」的4参数场景键相比,「演示架构师」的场景键只有3个参数,但参数本身是自由文本而非枚举值。这意味着场景键的匹配空间是无限的,但Mock数据只能覆盖有限的场景------这正是AI API Stub模式的核心设计理念:用有限的Mock数据覆盖典型场景,用预留的API接口处理长尾场景

2.4 currentResult的初始化模式

在ArkTS中,@State装饰的变量必须有初始值。对于PresentationResult这种复杂对象,我们不能简单地将currentResult初始化为nullundefined,因为ArkTS不支持anyunknown类型。我们采用了「空值初始化」模式:

typescript 复制代码
@State currentResult: PresentationResult = { slides: [] };

slides初始化为空数组。UI层通过this.showResult布尔变量控制结果区域的显示/隐藏,初始状态为false。当用户点击生成按钮且数据匹配成功后,currentResult被赋值为真实的演示大纲数据,同时showResult变为true,触发UI的条件渲染。

这种模式确保了在任何时刻,currentResult都是一个合法的PresentationResult对象,不会出现类型不一致导致的运行时错误。

2.5 AI API Stub模式设计

「演示架构师」当前采用Mock数据驱动,但架构上已经为真实AI API调用预留了接口。AI API Stub模式的核心设计如下:

typescript 复制代码
// 当前:Mock模式
generateMockData(): void {
  this.getMockData();  // 从预置场景中匹配数据
}

// 未来:AI API模式(预留)
// generateWithAI(): void {
//   const prompt: string = this.buildPrompt();
//   this.callAIAPI(prompt).then((result: PresentationResult) => {
//     this.currentResult = result;
//     this.showResult = true;
//   });
// }
//
// private buildPrompt(): string {
//   return `你是一位专业的演示文稿架构师。请为主题"${this.topic}"、
//           面向"${this.audience}"、生成${this.slides}页演示大纲。
//           每页需包含标题、3-5个要点和视觉建议。输出JSON格式。`;
// }

AI API Stub模式的核心价值在于:前端开发不依赖后端AI能力的就绪时间 。在UI开发、交互验证、数据流测试等阶段,Mock数据提供了确定性的、可重复的测试环境。当真实AI API就绪后,只需替换generateMockData()中的调用逻辑,UI层和数据模型层完全不需要修改。

这种模式在鸿蒙PC端开发中尤为重要。鸿蒙PC端的应用分发节奏与手机端不同,AI能力的接入需要经过更长的审核周期。AI API Stub模式让开发者可以在审核期间持续优化UI体验,而不会被后端阻塞。

2.6 紫色主题设计

「演示架构师」选择了紫色(#7B1FA2)作为主题色。这个选择基于以下专业考量:

  1. 创意与专业性的平衡:紫色在色彩心理学中代表创造力、智慧和专业,恰好契合「演示架构师」的定位------既有AI的创意生成能力,又有架构师的专业严谨。
  2. 视觉识别度:在40个AI应用矩阵中,紫色主题与蓝色(职场)、橙色(生活)、绿色(健康)等主题形成差异化,用户一眼就能识别出「AI创作」类应用。
  3. 演讲场景关联:紫色常被用于高端演讲和发布会场景(如TED演讲的经典配色),与演示文稿的商务场景天然契合。

三、Atomize原子化阶段:任务分解与执行

3.1 原子任务分解

在Atomize阶段,我们将整个开发任务分解为以下原子单元:

序号 原子任务 依赖 预估工时
A1 定义SlideItem、PresentationResult、PresentationScenario接口 5min
A2 编写3个场景Mock数据(含页数验证和要点验证) A1 40min
A3 实现主题、受众、页数3个TextInput输入控件 15min
A4 实现场景键拼接与Mock匹配逻辑 A1, A2 15min
A5 实现输入参数校验与边界处理逻辑 A3 10min
A6 实现Prompt构建逻辑(预留API调用) A1 10min
A7 实现生成按钮与交互逻辑 A3 10min
A8 实现Slide卡片列表UI(ForEach渲染) A1 25min
A9 实现紫色主题与整体UI整合 A3-A8 20min
A10 实现返回按钮与路由导航 5min

3.2 关键原子任务详解

A2:3场景Mock数据设计

Mock数据的设计需要兼顾多样性和专业性。我们为3个预置场景设计了不同主题、不同受众和不同页数的组合,以覆盖PPT大纲生成的主要使用场景。

场景一:人工智能发展趋势 / 技术团队 / 10页

这是最典型的AI主题演示场景,也是兜底场景。10页的篇幅符合「中等深度」的演示需求,结构从封面、目录、多个主题页到总结展望,形成了完整的「起承转合」叙述线。

10页幻灯片的逻辑结构如下:

  • P1 封面:确立主题和演讲者身份,建立第一印象
  • P2 目录:概述整体框架,让观众预览演讲结构
  • P3-P7 主体:5个主题页,分别覆盖大语言模型、多模态AI、AI Agent、AI安全治理、行业应用案例------这是最核心的论证部分
  • P8-P9 深化:行业应用案例(医疗、教育),将抽象的技术趋势落地到具体场景
  • P10 总结:挑战与机遇 + 总结展望,收束全文

这个场景的要点设计遵循了「从宏观到微观、从技术到应用」的递进逻辑。大语言模型和多模态AI是技术前沿,AI Agent是应用形态,AI安全是治理视角,行业应用是落地验证------五者形成了完整的论证闭环。

场景二:新能源汽车市场分析 / 投资团队 / 8页

这个场景面向投资团队,因此内容侧重数据和商业分析。8页的结构从市场概览到竞争格局、技术路线、供应链洞察、政策环境,最终落脚到投资机会和风险提示。每一页的视觉建议都匹配了投资分析领域的专业图表类型:柱状图、饼图、对比表、瀑布图、热力图、风险-收益矩阵。

值得注意的是,面向投资团队的大纲在设计上刻意减少了「技术细节」的权重,增加了「市场数据」「竞争分析」「政策影响」的权重。这正是受众参数影响大纲结构的具体体现------投资团队关心的是趋势和回报,而非技术实现细节。

场景三:团队建设与管理 / 管理层 / 6页

这个场景面向管理层(HR部门),聚焦于组织管理话题。6页的篇幅相对紧凑,重点覆盖了团队诊断、人才招聘、培养体系、激励保留和行动计划五个管理核心环节。视觉建议匹配了管理咨询领域的专业图表:雷达图、招聘漏斗、成长路径图、激励金字塔、甘特图。

面向管理层的大纲在设计上强调「可执行性」------每页的要点不仅是理论,更包含具体的行动指引。例如「新人90天融入计划」「导师制升级」「技能矩阵与培训地图」这些要点,都是可以直接转化为管理动作的具体建议。

场景键对照表:

场景键 主题 受众 页数 风格
人工智能发展趋势_技术团队_10 AI趋势 技术团队 10 技术深度型
新能源汽车市场分析_投资团队_8 汽车市场 投资团队 8 数据分析型
团队建设与管理_管理层_6 团队管理 管理层 6 行动导向型

3.3 场景键匹配逻辑

typescript 复制代码
getMockData(): void {
  let key: string = this.topic + '_' + this.audience + '_' + this.slides.toString();
  let found: PresentationScenario | null = null;
  for (let i = 0; i < this.mockScenarios.length; i++) {
    if (this.mockScenarios[i].scenario === key) {
      found = this.mockScenarios[i];
      break;
    }
  }
  if (found === null) {
    found = this.mockScenarios[0];
  }
  if (found !== null) {
    this.currentResult = found.result;
  }
  this.showResult = true;
}

匹配逻辑的关键设计点:

  1. 场景键拼接 :使用下划线连接三个参数,this.slides.toString()确保数字类型转换为字符串。这与场景键的格式保持一致。
  2. 常规for循环 :使用for (let i = 0; i < ...; i++)而非for...in或数组的find方法,以符合ArkTS的语法约束。ArkTS不支持for...in遍历对象,也不支持某些高阶数组方法。
  3. 显式null检查 :ArkTS不支持anyunknown类型,因此found变量声明为PresentationScenario | null联合类型。在使用前进行两次null检查(found === nullfound !== null),确保类型安全。
  4. 兜底机制 :匹配失败时回退到mockScenarios[0],确保无论用户输入什么参数,都能获得一个可用的演示大纲。对于AI应用来说,宁可返回一个不完美但可用的结果,也不应该返回空白或错误

3.4 输入参数校验与边界处理

typescript 复制代码
// 页数输入的边界处理
.onChange((value: string) => {
  let num: number = parseInt(value) || 5;
  if (num < 3) { num = 3; }
  if (num > 30) { num = 30; }
  this.slides = num;
})

页数输入框使用InputType.Number类型,弹出数字键盘。当用户输入非数字字符时,parseInt(value)返回NaN|| 5确保默认值为5页。下界钳制到3页(至少需要封面+内容+总结),上界钳制到30页(超过30页的演示文稿在实际场景中几乎不存在,且会给观众带来严重的认知负担)。

这种三层防护(默认值 -> 下界钳制 -> 上界钳制)确保了this.slides在任何情况下都是一个合法的整数值,避免了后续UI渲染中的异常。

3.5 Slide卡片列表UI实现

Slide卡片列表是「演示架构师」最具视觉识别度的部分。每个Slide卡片由P编号标签、标题、要点列表和视觉建议四部分组成:

复制代码
┌──────────────────────────────────────────────┐
│  P1 │ 封面:人工智能发展趋势                    │
│     │  • 2025年AI技术全景展望                   │
│     │  • 演讲人:AI研究团队                     │
│     │  视觉: AI神经网络可视化背景图              │
├──────────────────────────────────────────────┤
│  P2 │ 目录                                    │
│     │  • 大模型演进                            │
│     │  • 多模态AI                              │
│     │  • AI Agent                             │
│     │  • AI安全与治理                          │
│     │  • 行业应用案例                          │
│     │  视觉: 思维导图样式目录                   │
├──────────────────────────────────────────────┤
│  P3 │ 大语言模型的里程碑                       │
│     │  ...                                    │
└──────────────────────────────────────────────┘

实现要点:

  1. P编号标签 :使用紫色圆角背景(#7B1FA2) + 白色文字,borderRadius(12)实现胶囊形状,视觉效果醒目且专业。
  2. 标题fontSize(15) + fontWeight(FontWeight.Bold),在一行中与P标签横向排列,layoutWeight(1)让标题自动填充剩余空间。
  3. 要点列表 :使用ForEach嵌套遍历slide.points数组,每条要点以开头,fontSize(13)fontColor('#555555'),保持适中的信息密度。
  4. 视觉建议 :使用fontStyle(FontStyle.Italic)fontColor('#999999'),以斜体和浅灰色与正文内容区分,形成「辅助信息」的视觉定位。
  5. 分隔线 :每张Slide卡片之间使用Divider(),颜色为#E8E8E8,提供清晰的视觉边界。

ForEach嵌套渲染的关键代码:

typescript 复制代码
ForEach(this.currentResult.slides, (slide: SlideItem, index: number) => {
  Column() {
    Row() {
      // P编号标签
      Text('P' + (index + 1).toString())
        .fontSize(12)
        .fontColor('#FFFFFF')
        .backgroundColor('#7B1FA2')
        .borderRadius(12)
        .padding({ left: 10, right: 10, top: 2, bottom: 2 })
      
      // 标题
      Text(' ' + slide.title)
        .fontSize(15)
        .fontWeight(FontWeight.Bold)
        .fontColor('#333333')
        .layoutWeight(1)
    }
    .width('100%')
    .padding({ bottom: 6 })

    // 要点列表(嵌套ForEach)
    ForEach(slide.points, (point: string) => {
      Text('  • ' + point)
        .fontSize(13)
        .fontColor('#555555')
        .width('100%')
        .padding({ bottom: 2 })
    })

    // 视觉建议
    Text('视觉: ' + slide.visual)
      .fontSize(11)
      .fontColor('#999999')
      .fontStyle(FontStyle.Italic)
      .width('100%')
      .padding({ top: 4, bottom: 8 })

    Divider()
      .color('#E8E8E8')
      .margin({ bottom: 4 })
  }
  .width('100%')
})

外层ForEach遍历this.currentResult.slides,内层ForEach遍历slide.points。这种双层ForEach结构是ArkUI中处理嵌套列表数据的标准模式。由于ArkTS不支持for...in和某些高阶数组方法,ForEach组件是列表渲染的唯一推荐方式。

3.6 整体UI布局设计

「演示架构师」的UI布局采用「固定头部 + 可滚动内容」的结构:

复制代码
┌─────────────────────────────────────────┐
│  ← 返回                                  │  ← 固定头部区域
│  演示架构师 (24px Bold)                 │
│  AI帮你构建专业演示文稿大纲 (14px #999)  │
├─────────────────────────────────────────┤
│  ┌─────────────────────────────────┐    │
│  │ 演示主题 TextInput               │    │  ← 可滚动内容区域
│  ├─────────────────────────────────┤    │  (Scroll + layoutWeight)
│  │ 目标受众 TextInput               │    │
│  ├─────────────────────────────────┤    │
│  │ 幻灯片页数 TextInput(Number)    │    │
│  ├─────────────────────────────────┤    │
│  │       [ 生成大纲 ] 紫色按钮       │    │
│  ├─────────────────────────────────┤    │
│  │  演示大纲                         │    │
│  │  ┌───────────────────────────┐  │    │
│  │  │ P1 ···                    │  │    │
│  │  │ P2 ···                    │  │    │
│  │  │ ...                       │  │    │
│  │  └───────────────────────────┘  │    │
│  └─────────────────────────────────┘    │
└─────────────────────────────────────────┘

头部的固定区域包含返回按钮、应用标题和副标题,使用白色背景(#FFFFFF)与内容区域的灰色背景(#F5F5F5)形成视觉分层。内容区域使用Scroll组件包裹,layoutWeight(1)使其自动填充剩余空间,确保在长内容的场景下可以滚动浏览。


四、Approve审批阶段:质量门控与合规检查

4.1 ArkTS语法合规性检查

在审批阶段,我们需要逐项检查代码是否符合ArkTS的严格语法约束。

检查项1:接口定义完整性

typescript 复制代码
interface SlideItem {
  title: string;
  points: string[];
  visual: string;
}

interface PresentationResult {
  slides: SlideItem[];
}

interface PresentationScenario {
  scenario: string;
  result: PresentationResult;
}

所有interface定义紧凑,字段类型显式声明。没有使用条件类型别名、映射类型、交叉类型、索引签名等ArkTS不支持的TypeScript高级特性。没有使用anyunknown类型。三个接口之间通过嵌套引用形成了清晰的数据层级关系。

检查项2:状态变量初始化

typescript 复制代码
@State topic: string = '人工智能发展趋势';
@State audience: string = '技术团队';
@State slides: number = 10;
@State showResult: boolean = false;
@State currentResult: PresentationResult = { slides: [] };

每个@State变量都有明确的类型标注和初始值。没有使用let v!: T确定性赋值断言,也没有使用var关键字。currentResult的初始化使用了对象字面量,由于PresentationResult是显式声明的接口(无方法、无参数化构造函数、无只读字段),对象字面量初始化是合法的。

检查项3:Mock数据中的对象字面量与类型断言

typescript 复制代码
private mockScenarios: PresentationScenario[] = [
  {
    scenario: '人工智能发展趋势_技术团队_10',
    result: {
      slides: [
        {
          title: '封面:人工智能发展趋势',
          points: ['2025年AI技术全景展望', '演讲人:AI研究团队'],
          visual: 'AI神经网络可视化背景图'
        },
        // ... 更多幻灯片
      ]
    }
  },
  // ... 场景二、场景三
];

Mock数据中的嵌套对象字面量需要被编译器推断为已知类型。由于mockScenarios的类型注解为PresentationScenario[],TypeScript编译器可以沿着类型链向下推断:数组元素 -> PresentationScenario -> result -> PresentationResult -> slides -> SlideItem[] -> 数组元素 -> SlideItem。这种推断依赖于类型链的完整性------如果中间任何一个环节缺少类型标注,编译器就会报错。

检查项4:数组遍历

typescript 复制代码
// 正确:使用ForEach组件进行列表渲染
ForEach(this.currentResult.slides, (slide: SlideItem, index: number) => {
  // 渲染Slide卡片
})

// 正确:使用ForEach嵌套渲染要点列表
ForEach(slide.points, (point: string) => {
  Text('  • ' + point)
})

// 正确:使用常规for循环遍历数组
for (let i = 0; i < this.mockScenarios.length; i++) {
  if (this.mockScenarios[i].scenario === key) {
    found = this.mockScenarios[i];
    break;
  }
}

ArkTS不支持for...in遍历对象,但ForEach组件和常规for循环都是原生支持的。我们使用了两种遍历方式:UI渲染使用ForEach组件,数据匹配使用常规for循环。

检查项5:router导入与使用

typescript 复制代码
import { router } from '@kit.ArkUI';

// 返回上一页
router.back();

router@kit.ArkUI导入,这是HarmonyOS NEXT中路由模块的标准导入路径。router.back()是返回上一页的标准API,无需额外配置。

检查项6:字符串拼接

typescript 复制代码
let key: string = this.topic + '_' + this.audience + '_' + this.slides.toString();
Text('P' + (index + 1).toString())

ArkTS中字符串拼接使用+运算符。this.slides.toString()将数字转为字符串,(index + 1).toString()将索引+1后转为字符串。注意括号的使用------(index + 1).toString()是正确的,因为需要先计算加法再调用toString()

4.2 Mock数据质量验证

场景一的页数验证:

场景一(人工智能发展趋势_技术团队_10)的Mock数据包含10张幻灯片,与场景键中的页数参数一致。每张幻灯片包含2-5个要点,符合「3-5个要点」的黄金法则。视觉建议与页面内容高度相关,如「AI神经网络可视化背景图」对应封面、「思维导图样式目录」对应目录页、「SWOT分析矩阵」对应挑战与机遇页。

场景二的页数验证:

场景二(新能源汽车市场分析_投资团队_8)的Mock数据包含8张幻灯片,与场景键中的页数参数一致。要点设计以数据驱动为主,如「全球新能源车销量突破2000万辆」「中国市场占比超60%」「同比增长35%」等具体数字。视觉建议匹配投资分析场景,如「市场份额饼图+品牌矩阵」「投资价值评估热力图」「风险-收益矩阵」。

场景三的页数验证:

场景三(团队建设与管理_管理层_6)的Mock数据包含6张幻灯片,与场景键中的页数参数一致。要点设计以行动导向为主,如「新人90天融入计划」「导师制升级」「技能矩阵与培训地图」等可执行的具体措施。视觉建议匹配管理咨询场景,如「诊断雷达图」「成长路径图」「激励模型金字塔」「甘特图+OKR分解」。

4.3 输入校验逻辑验证

页数输入框的校验逻辑需要验证以下边界情况:

输入值 期望输出 验证结果
空字符串 5(默认值) 通过
"abc" 5(非数字,默认值) 通过
"0" 3(下界钳制) 通过
"2" 3(下界钳制) 通过
"3" 3(下界边界) 通过
"10" 10(正常值) 通过
"30" 30(上界边界) 通过
"31" 30(上界钳制) 通过
"100" 30(上界钳制) 通过
"-5" 3(负数钳制到下界) 通过

4.4 兜底逻辑验证

当用户输入的主题和受众组合在Mock数据中不存在时(如量子计算_学生_5),系统应该回退到默认场景(场景一)。验证结果:getMockData()正确地匹配到mockScenarios[0]并返回了AI发展趋势的演示大纲。


五、Automate自动化执行阶段:从代码到界面

5.1 完整UI代码实现

「演示架构师」的UI代码采用ArkUI声明式语法,整个页面在一个build()方法中完成构建。核心结构如下:

typescript 复制代码
@Entry
@Component
struct App36 {
  @State topic: string = '人工智能发展趋势';
  @State audience: string = '技术团队';
  @State slides: number = 10;
  @State showResult: boolean = false;
  @State currentResult: PresentationResult = { slides: [] };

  // Mock数据定义(3个场景)
  private mockScenarios: PresentationScenario[] = [ /* ... */ ];

  // 数据匹配方法
  getMockData(): void { /* ... */ }
  generateMockData(): void { /* ... */ }

  build() {
    Column() {
      // 固定头部:返回按钮 + 标题 + 副标题
      Row() { /* ... */ }
      Text('演示架构师') /* ... */
      Text('AI帮你构建专业演示文稿大纲') /* ... */

      // 可滚动内容区域
      Scroll() {
        Column() {
          // 主题输入
          TextInput({ text: this.topic }) /* ... */
          
          // 受众输入
          TextInput({ text: this.audience }) /* ... */
          
          // 页数输入
          TextInput({ text: this.slides.toString() }) /* ... */
          
          // 生成按钮
          Button('生成大纲') /* ... */
          
          // 条件渲染结果区域
          if (this.showResult) {
            // ForEach渲染Slide卡片列表
          }
        }
      }
      .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }
}

5.2 生成按钮与交互流

生成按钮是用户交互的核心入口。点击后触发generateMockData()方法,该方法内部调用getMockData()进行场景键匹配,匹配成功后将结果赋值给currentResult并将showResult置为true

typescript 复制代码
Button('生成大纲')
  .width('calc(100% - 32px)')
  .height(48)
  .backgroundColor('#7B1FA2')
  .fontColor('#FFFFFF')
  .fontSize(16)
  .fontWeight(FontWeight.Medium)
  .borderRadius(24)
  .margin({ top: 24, left: 16, right: 16 })
  .onClick(() => {
    this.generateMockData();
  })

按钮的设计要点:

  • 宽度calc(100% - 32px),左右各留16px边距,与输入框的边距保持一致
  • 高度:48px,符合移动端触控区域的最小推荐尺寸(44px)
  • 圆角:24px,实现胶囊形状,视觉上更柔和
  • 颜色 :紫色背景(#7B1FA2)+ 白色文字,与主题色一致

5.3 条件渲染与结果展示

结果区域使用if (this.showResult)条件渲染,这是ArkUI中控制UI显示/隐藏的标准方式。当showResultfalse时,结果区域完全不存在于组件树中,不占用任何渲染资源。

typescript 复制代码
if (this.showResult) {
  Column() {
    Text('演示大纲')
      .fontSize(18)
      .fontWeight(FontWeight.Bold)
      .padding({ top: 8, bottom: 12 })
      .width('100%')

    ForEach(this.currentResult.slides, (slide: SlideItem, index: number) => {
      // Slide卡片渲染
    })
  }
  .width('calc(100% - 32px)')
  .backgroundColor('#FFFFFF')
  .borderRadius(12)
  .padding(16)
  .margin({ top: 16, left: 16, right: 16, bottom: 24 })
}

结果区域使用白色卡片样式(backgroundColor('#FFFFFF') + borderRadius(12)),与灰色背景形成对比,突出显示。

5.4 紫色主题的整体实现

整个应用的主题色统一为紫色(#7B1FA2),在以下位置使用:

  • 生成按钮:背景色
  • P编号标签:背景色
  • 标题文字:字体颜色(与P标签形成视觉关联)

其余UI元素使用中性灰色调(#F5F5F5背景、#333333标题、#555555正文、#999999辅助信息、#E8E8E8分隔线),形成「紫色突出关键信息,中性色作为背景和正文」的视觉层次。

5.5 鸿蒙PC端适配策略

虽然「演示架构师」当前主要面向移动端,但在架构设计上已经考虑了鸿蒙PC端的适配需求。鸿蒙PC端与移动端的关键差异在于:

  1. 屏幕尺寸:PC端屏幕通常在13-27英寸,远超移动端的5-7英寸。这意味着UI布局可以从单列变为多列,充分利用横向空间。
  2. 输入方式:PC端以键盘和鼠标为主,触摸为辅。输入框可以更大,按钮可以更小(因为鼠标精度高于手指)。
  3. 窗口模式:PC端支持自由窗口和分屏模式,应用需要适配不同窗口尺寸。

对于「演示架构师」的鸿蒙PC端适配,推荐以下策略:

  • 输入区域:将主题、受众、页数三个输入框改为水平排列,充分利用PC端的横向空间
  • 结果区域:将Slide卡片列表改为两列或三列网格布局,让用户能同时看到更多内容
  • 响应式断点:使用ArkUI的响应式布局能力,在窗口宽度小于一定阈值时自动切换为移动端单列布局
  • 键盘快捷键:支持Ctrl+Enter快速生成大纲,提升键盘用户的操作效率

5.6 鸿蒙Flutter框架对比分析

在鸿蒙生态中,除了ArkUI声明式框架外,鸿蒙Flutter框架也是一个重要的UI开发选项。以下是两者在开发「演示架构师」这类AI应用时的对比:

维度 ArkUI(ArkTS) 鸿蒙Flutter框架
语言 ArkTS(TypeScript超集) Dart
组件模型 声明式UI(@Component Widget树
状态管理 @State / @Prop / @Link setState / Provider / Bloc
列表渲染 ForEach组件 ListView.builder
条件渲染 if / if else if / Visibility / Offstage
原生API访问 直接导入@kit.* 通过Platform Channel
性能 原生渲染,无桥接开销 Skia渲染引擎,有桥接开销
学习曲线 低(TypeScript开发者友好) 中(Dart语言学习成本)
生态成熟度 华为官方主推,持续更新 社区驱动,适配进度滞后

对于「演示架构师」这种轻量级AI工具应用,ArkUI + ArkTS的方案具有明显的优势:原生渲染性能更好、HarmonyOS API调用更直接、TypeScript开发者学习成本更低。但鸿蒙Flutter框架在跨平台代码复用方面有其独特的价值------如果未来需要同时支持Android和iOS,Flutter的代码复用率可以达到90%以上。


六、Assess评估阶段:回顾与展望

6.1 成果回顾

「演示架构师」在功能层面实现了以下目标:

功能 状态 说明
主题输入 完成 自由文本输入,默认为「人工智能发展趋势」
受众输入 完成 自由文本输入,默认为「技术团队」
页数输入 完成 数字键盘,3-30范围,边界自动钳制
大纲生成 完成 场景键匹配,3场景Mock数据
Slide卡片展示 完成 P编号标签 + 标题 + 要点 + 视觉建议
双层ForEach渲染 完成 外层遍历幻灯片,内层遍历要点
条件渲染 完成 showResult控制结果区域的显示/隐藏
紫色主题 完成 统一的紫色视觉风格
返回导航 完成 router.back()标准路由
异常兜底 完成 匹配失败回退默认场景

6.2 幻灯片结构的逻辑连贯性分析

生成的演示大纲在逻辑连贯性方面表现良好。以场景一(AI发展趋势)为例,10张幻灯片的叙述线如下:

复制代码
封面 → 目录 → 大模型 → 多模态 → AI Agent → AI安全 → 
医疗应用 → 教育应用 → 挑战机遇 → 总结展望

这条叙述线符合「技术演进 → 应用落地 → 挑战反思 → 未来展望」的经典论证结构。每一页的标题都自然地引向下一页,形成了清晰的信息流。

但我们也识别出了一些可改进之处:

  1. 过渡页缺失:在「医疗应用」和「教育应用」之间缺少一个行业应用的总览页,导致两个案例之间的跳跃感较强。
  2. 目录与内容不完全对应:目录中列出了5个主题,但实际展开时「行业应用案例」被拆分为两个独立的页面(医疗和教育),而非一个综合页面。这是一种合理的处理方式(两个具体案例比一个抽象概述更有说服力),但目录可以更精确地反映这种拆分。

6.3 受众感知的深度验证

场景一(技术团队)和场景二(投资团队)的要点设计,体现了不同受众对内容深度的差异化需求:

技术团队场景的关键词分析:

  • 技术术语密度高:GPT-4到GPT-5、上下文窗口、100万tokens、推理能力、多模态融合、Sora类模型、跨模态理解、Agent协作、对齐问题、红队测试、可解释性
  • 数据导向:准确率达95%、周期缩短60%

投资团队场景的关键词分析:

  • 商业术语密度高:市场占比、竞争格局、第一梯队、市场份额、量产突破、成本下降路径、自主化进程、国产替代、购置税减免、双积分政策、反补贴调查、碳交易、产能过剩、价格战、推荐标的
  • 数据导向:销量突破2000万辆、占比超60%、同比增长35%

这种术语层面的差异,说明Mock数据的设计确实考虑了受众参数的影响。但当前的实现中,受众参数仅用于场景键匹配,没有在生成逻辑中实现动态的内容调整。未来接入真实AI API后,Prompt中的受众参数将成为驱动内容差异化生成的核心引擎。

6.4 扩展性分析

真实AI API接入

当前「演示架构师」采用AI API Stub模式,Mock数据驱动的开发体验已经完整验证了UI交互和数据流。接入真实AI API时,只需替换generateMockData()中的调用逻辑:

typescript 复制代码
// 未来:通过Prompt调用AI API
async generateWithAI(): Promise<void> {
  const prompt: string = 
    `你是一位专业的演示文稿架构师。请为主题"${this.topic}"、
     面向"${this.audience}"、生成${this.slides}页演示大纲。
     每页需包含:标题(title)、3-5个要点(points)、
     视觉建议(visual)。输出JSON格式:
     { "slides": [{ "title": "...", "points": ["..."], "visual": "..." }] }`;
  
  try {
    const response: string = await this.callAIAPI(prompt);
    const result: PresentationResult = JSON.parse(response) as PresentationResult;
    this.currentResult = result;
    this.showResult = true;
  } catch (e) {
    // API调用失败时回退到Mock数据
    this.getMockData();
  }
}

关键设计点:API调用失败时自动回退到Mock数据。这确保了在任何情况下用户都能获得一个可用的演示大纲,即使AI服务暂时不可用。

风格模板扩展

当前的大纲生成只关注内容结构,没有涉及视觉风格。未来可以增加一个「风格选择」参数,让用户选择「商务蓝」「科技紫」「创意橙」等配色方案,并在视觉建议中融入风格信息。例如,在「商务蓝」风格下,视觉建议会推荐蓝色系的图表和数据可视化;在「创意橙」风格下,视觉建议会推荐更活泼的插画和图标。

多页联动优化

当前每张幻灯片是独立生成的,页面之间的过渡关系依赖于内容本身的逻辑连贯性。未来可以在Prompt中增加「页面过渡」约束,要求AI在生成每页内容时考虑与前后页的衔接关系,并可以在视觉建议中推荐过渡动画类型(如「淡入淡出」「推入」「翻页」等)。

导出功能

当前的大纲只在应用内展示,用户无法导出到外部工具。未来可以增加导出功能,支持导出为Markdown、JSON、甚至直接生成PPTX文件。导出为PPTX文件需要使用HarmonyOS的文件系统API和第三方库(如PPTX生成库),这涉及到更复杂的文件操作和权限管理。

6.5 鸿蒙PC端深度适配展望

随着鸿蒙PC的持续发展,越来越多的AI应用将面临PC端适配的需求。对于「演示架构师」而言,PC端适配不仅是布局调整,更是使用场景的转变:

  1. 双屏模式:在PC端,用户可能在主屏上编辑演示大纲,在副屏上预览PPT效果。这需要「演示架构师」支持多窗口模式,将大纲编辑和预览分离到两个窗口。
  2. 拖拽排序:在PC端,用户可能希望拖拽Slide卡片来调整页面顺序。这需要实现拖拽交互,使用ArkUI的拖拽API。
  3. 批量编辑:在PC端,用户可能希望批量修改所有页面的视觉建议或字体样式。这需要增加批量编辑面板。
  4. 协作编辑:在PC端,多个用户可以同时编辑同一份演示大纲。这需要引入实时协作能力,通过HarmonyOS的分布式能力实现设备间的数据同步。

这些PC端特有的功能需要在架构层面预留扩展点,但不应在当前的MVP阶段过度设计。

6.6 总结

「演示架构师」作为一个轻量级的AI PPT大纲生成工具,在HarmonyOS平台上实现了从需求对齐到自动化执行的全流程开发。它展示了AI API Stub模式在前端先行开发中的有效性,体现了ArkUI声明式框架在复杂嵌套列表渲染中的优势,并以紫色主题和Slide卡片设计树立了独特的视觉识别。

在技术层面,本文深入探讨了以下关键主题:

  • 场景化数据建模:通过场景键(Scenario Key)设计,将多维度的用户输入映射为可索引的字符串键,实现了灵活的Mock数据匹配和兜底机制。
  • 双层ForEach渲染 :在ArkTS的语法约束下,使用ForEach嵌套处理幻灯片列表和要点列表,确保了列表渲染的性能和可维护性。
  • AI API Stub模式:通过Mock数据驱动的前端先行开发策略,解耦了UI开发与后端AI能力的依赖关系,为鸿蒙AI应用开发提供了可复用的技术范式。
  • 鸿蒙PC端适配:分析了移动端与PC端的核心差异,提出了响应式布局、多窗口模式、键盘快捷键等适配策略。
  • 鸿蒙Flutter框架对比:从语言、性能、生态、学习曲线等维度对比了ArkUI和鸿蒙Flutter框架的适用场景。

「演示架构师」的代码虽然简洁(仅356行),但其背后的设计理念和技术决策,体现了鸿蒙AI应用开发的核心方法论:用最小的代码量实现最大的用户价值,用架构设计的前瞻性换取未来的扩展空间。希望本文能为同样在鸿蒙生态中探索AI应用开发的开发者提供一些参考和启发。


本文基于HarmonyOS NEXT(API 26)开发环境,代码示例使用ArkTS语言,UI组件基于ArkUI声明式框架。文中涉及的AI API Stub模式、场景键设计、双层ForEach渲染等模式,均来源于实际项目中的工程实践。

相关推荐
青岛前景互联信息技术有限公司1 小时前
以新标准为底座,前景互联打造高危场景智能接处警新体系
大数据·网络·人工智能
2601_956865771 小时前
怎么用AI生成带货视频?电商内容创作工具推荐与选择思路
人工智能·aigc·音视频
正在走向自律1 小时前
怎样区分人工智能、离身智能、具身智能、智能机器人与人形机器人
人工智能·机器人·具身智能·人形机器人·智能机器人·离身智能
MEIXIFU11 小时前
深夜里的温暖灯塔与便捷生活
大数据·人工智能·生活·迭代加深
坚持学习前端日记1 小时前
国产化适配全流程适配英伟达本地开发
人工智能·python
执笔论英雄1 小时前
【;Agent】SWEET-RL:在协同推理任务上训练多轮大语言模型智能体
人工智能·语言模型·自然语言处理
一个王同学1 小时前
从零到一 | CV转多模态大模型 | week17 | LLM 推理优化 & vLLM 详解
人工智能·深度学习·算法·机器学习·计算机视觉·vllm
国服第二切图仔1 小时前
HarmonyOS APP《画伴梦工厂》开发第60篇-分布式软总线2.0——多设备协同新范式
分布式·wpf·harmonyos
llgdwuhan1 小时前
光芯片耦合测试设备对比:谁在定义国产替代的下一站?
大数据·人工智能