AI差评分析 —— 基于 HarmonyOS 的 AI 应用开发全流程技术实践
AI差评分析 —— 基于 HarmonyOS 的 AI 应用开发全流程技术实践
引言
在当今数字化商业环境中,用户评价是企业改进产品和服务的重要依据。然而,面对海量的用户差评,手动分析不仅效率低下,而且难以挖掘深层次的根因和趋势。“AI差评分析” 应用应运而生,它利用 HarmonyOS 的 ArkTS 技术栈,构建了一个智能化的差评分析仪表盘,帮助用户快速洞察问题分类、根因分析、情绪倾向和改进建议。
本文以 “AI差评分析” 应用为案例,严格遵循 对齐(Align)→ 架构(Architect)→ 原子化(Atomize)→ 审批(Approve)→ 自动化执行(Automate)→ 评估(Assess) 六阶段开发流程,详细阐述从需求分析到最终交付的完整技术实践。全文将深入剖析 ArkTS 语言在鸿蒙生态中的语法约束与最佳实践,展示 ArkUI 声明式 UI 框架的数据驱动机制,并分享在三层架构模式下的代码组织策略。

1. 对齐阶段(Align)
对齐阶段的目标是将模糊的产品需求转化为精确的技术规范。这是整个开发流程的基石,决定了后续所有工作的方向和质量。
1.1 项目上下文分析
1.1.1 技术栈全景
“AI差评分析” 应用是 HarmonyOS 生态中的一个 AI 子应用,运行在以下技术栈之上:
- 操作系统:HarmonyOS 6.0.1(API 21,Stage 模型)
- 开发语言:ArkTS(基于 TypeScript 的鸿蒙原生语言)
- UI 框架:ArkUI 声明式 UI 框架
- 构建工具:Hvigor(鸿蒙原生构建工具)
- 目标设备:Phone(手机)
- SDK 兼容:targetSdkVersion 6.0.1(21),compatibleSdkVersion 6.0.1(21)
- IDE:DevEco Studio
该项目是一个大型 AI 应用集合的一部分,整个应用市场包含多个 AI 应用,覆盖健康生活、工作效率、创意娱乐、学习成长、职业发展五大类别。“AI差评分析” 归属于"工作效率"类别,图标为 📉,副标题为"差评分析"。
1.1.2 项目结构分析
该应用的代码组织结构如下:
entry/src/main/ets/
├── apps/
│ └── AI差评分析/
│ ├── AI差评分析Page.ets # 页面层(View)
│ ├── AI差评分析Model.ets # 数据模型层(Model)
│ └── AI差评分析Service.ets # 业务逻辑层(Service)
├── pages/
│ └── Index.ets # 主入口页面(应用列表)
├── entryability/
│ └── EntryAbility.ets # Ability 入口
└── entrybackupability/
└── EntryBackupAbility.ets # 备份扩展
路由配置通过 main_pages.json 统一管理:
{
"src": [
"pages/Index",
"apps/AI差评分析/AI差评分析Page",
// ... 其他应用的路由注册
]
}
应用注册信息通过 apps.json 配置,包含图标、标题、颜色、分类等元数据:
{
"icon": "📉",
"title": "AI差评分析",
"subtitle": "差评分析",
"color": "#3B82F6",
"bg": "#EFF6FF",
"border": "#BFDBFE",
"page": "apps/AI差评分析/AI差评分析Page",
"cat": "工作效率"
}
1.1.3 架构模式分析
通过分析代码结构,可以发现该应用采用了 分层架构(Layered Architecture) 模式,类似于前端领域的 MVC/MVP 模式:
- Page 层(View):负责 UI 渲染和用户交互,使用 ArkUI 的
@Component装饰器定义组件,通过@State装饰器管理响应式状态 - Model 层:定义数据实体
AI差评分析Data,封装所有业务数据字段,包括分类、根因、情绪、改进建议等 - Service 层:封装核心业务逻辑,将用户输入数据转换为结构化的分析结果,目前使用 Mock 数据模拟 AI 生成
这种分层模式在 HarmonyOS 应用开发中非常典型,体现了良好的关注点分离原则。
1.1.4 依赖关系分析
在 oh-package.json5 中可以确认,应用层没有额外的第三方依赖,仅依赖鸿蒙 SDK 内置的 @kit.ArkUI 和 @kit.ArkTS 框架:
{
"name": "entry",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "",
"author": "",
"license": "",
"dependencies": {}
}
这表明 HarmonyOS 的 SDK 已经提供了足够丰富的原生 API 支持,无需引入外部库即可完成复杂的 UI 交互和数据展示。
1.2 需求理解确认
经过对项目代码和配置文件的全面分析,我们对 “AI差评分析” 的需求进行如下确认:
| 需求项 | 描述 | 验收标准 |
|---|---|---|
| 用户输入 | 支持用户输入差评内容和产品类型 | 输入框可正常录入文本 |
| AI 分析 | 基于输入数据生成结构化的差评分析报告 | 点击"分析数据"按钮后显示分析结果 |
| 问题分类 | 展示差评的问题分类及其统计信息 | 结果区域展示 categories、count、ratio、severity |
| 根因分析 | 展示问题的根因、证据和影响范围 | 结果区域展示 root_causes、cause、evidence、impact |
| 情绪分析 | 展示整体情绪倾向 | 结果区域展示 sentiment 字段 |
| 改进建议 | 展示改进措施、优先级、负责人和时间线 | 结果区域展示 improvement、action、priority、owner、timeline |
| 正面洞察 | 展示差评中可挖掘的正面信号 | 结果区域展示 positive_insights 字段 |
| 页面导航 | 支持返回上级页面 | 点击"← 返回"可返回应用列表 |
1.3 疑问澄清与决策
在开发过程中,团队针对以下关键问题进行了决策:
问题 1:ArkTS 语言约束如何影响编码风格?
ArkTS 是 TypeScript 的子集,但做了大量严格的语法限制。经过分析,我们确认了以下关键约束并制定了对应的编码规范:
- 不支持
any和unknown类型 → 所有变量必须显式指定类型,如使用Record<string, Object>替代any - 不支持解构赋值 → 使用临时变量逐字段操作,如
let reviewsVal: string = String(input['reviews'] || '') - 不支持
Function.bind/Function.apply→ 遵循传统 OOP 风格处理this - 不支持索引签名 → 使用
string[]数组替代{ [key: string]: string } - 不支持
for...in遍历对象 → 使用常规for循环或ForEach迭代数组 - 不支持对象字面量直接作为类型 → 显式声明
class AI差评分析Data - 不支持
in运算符 → 使用instanceof替代 - 不支持
as const断言 → 使用显式类型标注 - 不支持
JSX表达式 → 使用 ArkUI 的链式 API 构建 UI
问题 2:数据模型如何设计?
考虑到差评分析的复杂性,数据模型需要包含以下维度的信息:
- 问题分类维度:categories(分类列表)、category(当前分类)、count(数量)、ratio(占比)、severity(严重程度)
- 根因分析维度:root_causes(根因列表)、cause(根因描述)、evidence(证据)、impact(影响范围)
- 情绪分析维度:sentiment(整体情绪分析)
- 改进建议维度:improvement(改进措施列表)、action(具体行动)、priority(优先级)、owner(负责人)、timeline(时间线)
- 正面洞察维度:positive_insights(差评中可挖掘的正面信号)
问题 3:Service 层如何与 AI 能力对接?
当前阶段,Service 层使用 Mock 数据模拟 AI 生成结果。未来计划接入真实的大模型 API(如 OpenAI GPT 或华为盘古大模型),将用户输入构建为 Prompt 发送给 AI 服务,然后将返回的 JSON 数据解析为 AI差评分析Data 实例。
1.4 边界确认
经过对齐分析,我们明确了以下任务边界:
在范围内:
- 构建完整的 Page、Model、Service 三层架构
- 实现差评内容的文本输入和产品类型输入
- 实现 Mock 数据的生成与展示
- 实现分析报告的结构化展示
- 实现页面路由注册和应用列表集成
不在范围内:
- 真实的 AI 大模型 API 对接(后续迭代)
- 数据持久化存储(后续迭代)
- 用户登录和权限管理
- 多语言国际化支持
- 差评数据的批量导入导出
2. 架构阶段(Architect)
架构阶段的目标是从共识文档出发,设计系统架构、模块划分和接口规范。
2.1 整体架构设计
“AI差评分析” 应用采用经典的三层架构,遵循 MVVM(Model-View-ViewModel)模式在 HarmonyOS 中的最佳实践:
┌─────────────────────────────────────────────────────────┐
│ View 层 (Page) │
│ ┌─────────────────────────────────────────────────────┐│
│ │ AI差评分析Page.ets ││
│ │ - @State inputData: Record<string, Object> ││
│ │ - @State resultData: AI差评分析Data | null ││
│ │ - @State showResult: boolean ││
│ │ - ArkUI 声明式 UI 组件 ││
│ └──────────────┬──────────────────────────────────────┘│
└─────────────────┼────────────────────────────────────────┘
│ 调用 generateData(input)
▼
┌─────────────────────────────────────────────────────────┐
│ Service 层 │
│ ┌─────────────────────────────────────────────────────┐│
│ │ AI差评分析Service.ets ││
│ │ - generateData(input): AI差评分析Data ││
│ │ - Mock 数据生成逻辑 ││
│ │ - 未来: AI API 调用封装 ││
│ └──────────────┬──────────────────────────────────────┘│
└─────────────────┼────────────────────────────────────────┘
│ 返回 AI差评分析Data 实例
▼
┌─────────────────────────────────────────────────────────┐
│ Model 层 │
│ ┌─────────────────────────────────────────────────────┐│
│ │ AI差评分析Data (class) ││
│ │ - categories: string[] ││
│ │ - root_causes: string[] ││
│ │ - sentiment: string ││
│ │ - improvement: string[] ││
│ │ - positive_insights: string ││
│ │ + ... 其他业务字段 ││
│ └─────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────┘
2.2 核心数据流
数据流采用单向数据流模式,确保数据变更的可预测性:
用户输入 ──→ TextInput.onChange() ──→ this.inputData 更新
│
▼
用户点击"分析数据"按钮 ──→ this.service.generateData(input)
│
▼
Service 层解析/生成数据
│
▼
返回 AI差评分析Data 实例
│
▼
this.resultData = data
this.showResult = true
│
▼
ArkUI 自动重新渲染 UI
这种数据流模式的关键优势在于:
- 可预测性:数据始终单向流动,便于追踪和调试
- 响应式:
@State装饰器确保 UI 自动响应数据变化 - 解耦性:View 层不直接操作数据,而是通过 Service 层间接处理
2.3 模块依赖关系
AI差评分析Page.ets
├── import { AI差评分析Data } from './AI差评分析Model'
├── import { AI差评分析Service } from './AI差评分析Service'
└── import { router } from '@kit.ArkUI'
AI差评分析Service.ets
└── import { AI差评分析Data } from './AI差评分析Model'
AI差评分析Model.ets
└── 无外部依赖(纯数据实体)
依赖方向为:Page → Service → Model,符合分层架构的依赖倒置原则。
2.4 接口契约定义
Service 层接口:
// 输入: 用户输入的差评数据
// 输出: 结构化的差评分析结果
generateData(input: Record<string, Object>): AI差评分析Data
Model 层数据实体:
class AI差评分析Data {
categories: string[] // 问题分类列表
category: string // 当前分类
count: string // 数量
ratio: string // 占比
severity: string // 严重程度
root_causes: string[] // 根因列表
cause: string // 根因描述
evidence: string // 证据
impact: string // 影响范围
sentiment: string // 情绪分析
improvement: string[] // 改进措施列表
action: string // 具体行动
priority: string // 优先级
owner: string // 负责人
timeline: string // 时间线
positive_insights: string // 正面洞察
}
2.5 异常处理策略
在 HarmonyOS 应用中,异常处理遵循以下策略:
- Service 层异常:在
generateData方法内部捕获异常,返回默认的 Mock 数据,确保 UI 层不会因数据异常而崩溃 - UI 层防御:使用
if (this.resultData !== null)进行空值检查,避免访问 null 对象的属性 - 路由异常:
router.back()调用由 ArkUI 框架内部处理异常 - 资源加载异常:
Index.ets中的loadApps()方法使用try-catch捕获 JSON 解析异常,并回退到默认空列表
3. 原子化阶段(Atomize)
原子化阶段将任务分解为更小的、可管理的子任务,以便高效执行和跟踪。
3.1 任务分解
“AI差评分析” 应用的开发任务被分解为以下原子任务:
任务 1:创建 Model 数据模型
描述:定义 AI差评分析Data 类,封装所有业务数据字段。
文件:entry/src/main/ets/apps/AI差评分析/AI差评分析Model.ets
验收标准:类包含 17 个字段,所有字段有默认值,构造函数中初始化所有字段。
代码实现:
export class AI差评分析Data {
categories: string[] = []
category: string = ''
count: string = ''
ratio: string = ''
severity: string = ''
root_causes: string[] = []
cause: string = ''
evidence: string = ''
impact: string = ''
sentiment: string = ''
improvement: string[] = []
action: string = ''
priority: string = ''
owner: string = ''
timeline: string = ''
positive_insights: string = ''
constructor() {
this.categories = []
this.category = ''
this.count = ''
this.ratio = ''
this.severity = ''
this.root_causes = []
this.cause = ''
this.evidence = ''
this.impact = ''
this.sentiment = ''
this.improvement = []
this.action = ''
this.priority = ''
this.owner = ''
this.timeline = ''
this.positive_insights = ''
}
}
技术要点分析:
在 ArkTS 中,类的字段声明有严格的语法要求:
-
字段声明位置:ArkTS 要求所有字段在类声明内部直接声明,不支持在构造函数中动态声明字段。这与标准 TypeScript 不同,在 TypeScript 中可以在构造函数中通过
this.field = value动态创建字段。 -
显式初始化:ArkTS 不支持确定性赋值断言
let v!: T,因此所有字段必须在声明时提供初始值。这就是为什么我们在类声明中为每个字段都赋了初始值(空字符串或空数组)。 -
构造函数冗余:由于 ArkTS 要求字段必须在声明时初始化,构造函数中的赋值操作实际上是冗余的。但从代码清晰度和维护性角度考虑,保留构造函数中的显式初始化可以作为文档化的方式展示所有字段的默认状态。
-
不支持索引访问类型:ArkTS 不允许使用
type T = MyClass['field']这样的索引访问类型语法,因此在需要引用字段类型时,必须直接使用类型名称。
任务 2:实现 Service 业务逻辑层
描述:实现 AI差评分析Service 类,封装数据生成逻辑。
文件:entry/src/main/ets/apps/AI差评分析/AI差评分析Service.ets
验收标准:Service 类包含 generateData 方法,接收用户输入,返回 AI差评分析Data 实例。
代码实现:
import { AI差评分析Data } from './AI差评分析Model'
export class AI差评分析Service {
private model: AI差评分析Data
constructor() {
this.model = new AI差评分析Data()
}
// 生成AI差评分析数据
generateData(input: Record<string, Object>): AI差评分析Data {
let result: AI差评分析Data = new AI差评分析Data()
// Mock data generation based on input
let reviewsVal: string = String(input['reviews'] || '')
result.categories = ['示例数据1', '示例数据2', '示例数据3']
result.root_causes = ['示例数据1', '示例数据2', '示例数据3']
result.sentiment = '生成结果:' + reviewsVal
result.improvement = ['示例数据1', '示例数据2', '示例数据3']
result.positive_insights = '生成结果:' + reviewsVal
return result
}
}
技术要点分析:
-
Record<string, Object> 类型:ArkTS 不支持
any和unknown类型,因此我们需要使用Record<string, Object>来接收动态输入。Record<K, V>是 ArkTS 支持的少数几个实用类型之一(与Partial、Required、Readonly并列)。 -
类型转换:由于 ArkTS 不支持索引签名,我们不能直接使用
input.reviews来访问字段,而必须使用input['reviews']这种索引访问方式。但需要注意的是,返回值的类型是Object,需要显式转换为string。 -
Mock 数据策略:在当前阶段,Service 层使用 Mock 数据模拟 AI 生成结果。这种策略在开发初期非常有效,可以:
- 让 UI 层和 Service 层并行开发
- 在 AI API 接入前验证完整的 UI 交互流程
- 方便单元测试和 UI 自动化测试
-
未来扩展设计:Service 类的设计为未来接入真实 AI API 预留了扩展点。只需修改
generateData方法的内部实现,将 Mock 数据替换为 API 调用,而不需要修改 Page 层和 Model 层的任何代码。
任务 3:构建 Page 页面 UI
描述:使用 ArkUI 声明式 UI 构建完整的差评分析页面。
文件:entry/src/main/ets/apps/AI差评分析/AI差评分析Page.ets
验收标准:页面包含 Header、数据指标、输入区域、分析按钮、结果展示区域。
页面结构设计:
┌─────────────────────────────────┐
│ ← 返回 📱 AI差评分析 LIVE │ ← Header
│ DASHBOARD · 实时监控 │
├─────────────────────────────────┤
│ [数据源: 3] [分析中: --] [就绪: ✓] │ ← 数据指标
├─────────────────────────────────┤
│ 差评内容 │ ← 输入区域
│ ┌───────────────────────────┐ │
│ │ 请输入差评内容 │ │
│ └───────────────────────────┘ │
│ 产品类型 │
│ ┌───────────────────────────┐ │
│ │ 请输入产品类型 │ │
│ └───────────────────────────┘ │
├─────────────────────────────────┤
│ [📱 ▶ 分析数据] │ ← 分析按钮
├─────────────────────────────────┤
│ 📊 分析报告 │ ← 结果展示区域
│ Categories │
│ • 示例数据1 │
│ • 示例数据2 │
│ • 示例数据3 │
│ Category: ... │
│ Count: ... │
│ Ratio: ... │
│ Severity: ... │
│ Root causes │
│ ... │
│ Improvement │
│ ... │
└─────────────────────────────────┘
技术要点分析:
-
@State 装饰器:ArkUI 使用
@State装饰器标记响应式状态变量。当状态变量发生变化时,ArkUI 会自动重新渲染相关的 UI 组件。这是声明式 UI 框架的核心机制。 -
条件渲染:通过
if (this.showResult && this.resultData !== null)实现条件渲染,控制分析报告的显示与隐藏。这种模式在 ArkUI 中非常常见,用于实现加载状态、空状态和错误状态的切换。 -
ForEach 循环渲染:ArkUI 使用
ForEach组件实现列表渲染,需要提供两个回调函数:itemGenerator(生成子组件)和keyGenerator(生成唯一标识符)。这与 React 的map函数类似,但 ArkTS 不支持解构,因此回调参数需要逐个声明。
任务 4:注册路由配置
描述:在 main_pages.json 中注册页面路由。
文件:entry/src/main/resources/base/profile/main_pages.json
验收标准:路由数组中包含 "apps/AI差评分析/AI差评分析Page"。
任务 5:集成到应用列表
描述:在 apps.json 中添加应用配置信息。
文件:entry/src/main/resources/rawfile/apps/apps.json
验收标准:JSON 数组中包含 AI差评分析的配置对象,包含 icon、title、subtitle、color、page、cat 等字段。
3.2 任务依赖关系
任务 1 (Model) ──→ 任务 2 (Service) ──→ 任务 3 (Page)
│
任务 4 (路由) ─────────────┤
│
任务 5 (应用列表) ──────────┘
任务 1 和任务 2 是任务 3 的前提条件,而任务 4 和任务 5 可以与任务 3 并行执行。
4. 审批阶段(Approve)
审批阶段对前面阶段的成果进行审核和批准,确保符合要求。
4.1 代码审查清单
4.1.1 Model 层审查
审查项:数据模型完整性
- 所有业务字段已定义:categories、category、count、ratio、severity、root_causes、cause、evidence、impact、sentiment、improvement、action、priority、owner、timeline、positive_insights
- 字段类型正确:字符串数组使用
string[],单值使用string - 所有字段具有默认值,避免空指针异常
- 构造函数中初始化所有字段
- 类使用
export导出,可供其他模块引用
4.1.2 Service 层审查
审查项:业务逻辑正确性
- Service 类正确导入 Model 类
-
generateData方法签名符合规范:(input: Record<string, Object>) => AI差评分析Data - 参数类型使用
Record<string, Object>而非any(符合 ArkTS 约束) - 返回类型显式指定(符合 ArkTS 对函数返回类型推断的限制)
- 构造函数中创建 Model 实例
- 使用箭头函数而非普通函数(ArkTS 不支持独立函数中的
this)
4.1.3 Page 层审查
审查项:UI 交互完整性
- 页面使用
@Entry和@Component装饰器标记 - 使用
@State装饰器管理响应式状态 - Header 包含返回按钮、标题和 LIVE 状态标识
- 数据指标行展示三个指标项
- 输入区域包含差评内容和产品类型两个输入框
- 分析按钮绑定点击事件,调用 Service 层生成数据
- 结果展示区域使用条件渲染,在数据就绪后显示
- 使用
ForEach循环渲染列表数据 - 使用
router.back()实现页面返回 - 页面背景色为深色模式(
#0F172A),符合现代仪表盘设计风格
4.1.4 ArkTS 语法合规审查
审查项:是否违反 ArkTS 语法约束
- 未使用
any或unknown类型 - 未使用解构赋值
- 未使用
Function.bind/Function.apply/Function.call - 未使用
for...in循环 - 未使用
in运算符 - 未使用
as const断言 - 未使用索引签名
- 未使用对象字面量作为类型声明
- 所有 import 语句在文件开头
- 未使用
var关键字(使用let) - 未使用解构变量声明
- 类字段在类声明内部声明,而非构造函数中
- 函数返回类型显式指定
4.2 ArkTS 语法约束深度解析
在审批过程中,我们特别关注 ArkTS 与标准 TypeScript 的语法差异。以下是一些关键约束的详细解析:
4.2.1 不支持解构赋值
标准 TypeScript 中,解构赋值是一种常见的语法糖:
// TypeScript 写法(在 ArkTS 中不支持)
const { name, age } = person
在 ArkTS 中,必须使用临时变量逐字段赋值:
// ArkTS 兼容写法
let name: string = person.name
let age: number = person.age
在我们的代码中,ForEach 的回调参数也体现了这一约束:
// ArkTS 兼容写法 - 不使用解构
ForEach(this.resultData.categories, (item: string, index: number) => {
// ...
}, (item: string, index: number) => index.toString())
4.2.2 不支持索引签名
标准 TypeScript 中,可以定义索引签名:
// TypeScript 写法(在 ArkTS 中不支持)
interface StringMap {
[key: string]: string
}
在 ArkTS 中,必须使用 Record<K, V> 或数组替代:
// ArkTS 兼容写法
let inputData: Record<string, Object> = {}
4.2.3 不支持对象字面量作为类型
标准 TypeScript 中,可以直接使用对象字面量:
// TypeScript 写法(在 ArkTS 中不支持)
let point: { x: number, y: number } = { x: 10, y: 20 }
在 ArkTS 中,必须显式声明类或接口:
// ArkTS 兼容写法
class Point {
x: number = 0
y: number = 0
}
let point: Point = new Point()
point.x = 10
point.y = 20
在我们的项目中,AI差评分析Data 类的设计正是遵循了这一原则。
4.2.4 函数返回类型显式指定
ArkTS 对函数返回类型推断有限制。当 return 语句中的表达式是对返回类型被省略的函数或方法的调用时,会发生编译时错误。因此,所有函数必须显式指定返回类型:
// 必须显式指定返回类型
generateData(input: Record<string, Object>): AI差评分析Data {
// ...
return result
}
4.3 质量门控
经过审批,以下质量门控条件全部满足:
- 需求边界清晰无歧义:已完成需求确认,输入输出字段明确
- 技术方案与现有架构对齐:采用与项目其他应用一致的三层架构
- 验收标准具体可测试:每个原子任务都有明确的验收标准
- 所有关键假设已确认:Mock 数据策略、ArkTS 语法约束等已确认
- 项目特性规范已对齐:遵循项目的编码规范、目录结构和命名约定
5. 自动化执行阶段(Automate)
自动化执行阶段利用自动化工具和流程执行任务,提高开发效率和质量。
5.1 代码生成脚本
在 “AI差评分析” 应用的开发过程中,我们使用了自动化脚本辅
更多推荐

所有评论(0)