基于HarmonyOS的AI考研英语作文模板开发全流程技术实践

摘要:本文以"AI考研英语作文模板"应用开发为案例,详细阐述在HarmonyOS ArkTS生态下,一个AI功能应用从需求对齐、架构设计、原子化分解、审批确认、自动化执行到最终评估的全流程技术实践。全文涵盖ArkTS语法约束下的MVVM架构实现、声明式UI驱动、大模型Prompt设计、路由注册与配置集成等核心环节,并附完整代码示例,为HarmonyOS AI应用开发提供可复用的工程化参考。


在这里插入图片描述

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

1.1 项目上下文分析

"AI考研英语作文模板"是HarmonyOS AI应用生态中的一个子应用,归属于"学习成长"分类。项目基于HarmonyOS ArkTS技术栈,采用MVVM三层架构(Model-Service-View),运行于HarmonyOS 5.0+系统之上。

已有项目结构分析:

项目根目录 MyApplication 是一个标准的HarmonyOS工程,包含以下关键模块:

MyApplication/
├── entry/
│   ├── src/main/ets/
│   │   ├── pages/Index.ets          # 主入口页(应用列表)
│   │   ├── entryability/EntryAbility.ets  # 应用Ability
│   │   └── apps/
│   │       └── AI考研英语作文模板/
│   │           ├── AI考研英语作文模板Page.ets   # 视图层
│   │           ├── AI考研英语作文模板Model.ets  # 数据层
│   │           └── AI考研英语作文模板Service.ets # 服务层
│   ├── src/main/resources/
│   │   ├── rawfile/apps/apps.json    # 应用列表注册
│   │   └── base/profile/main_pages.json # 路由配置
│   └── oh-package.json5
└── oh-package.json5

项目整体采用"应用列表 + 子应用跳转"的架构模式:Index.ets 通过 apps.json 读取应用列表,经 router.pushUrl 跳转到各子应用页面。每个子应用独立封装为"Page + Model + Service"三层,彼此无耦合,实现了高内聚低扩展的设计目标。

1.2 需求理解与边界确认

原始需求描述:

开发一个AI考研英语作文模板生成工具,用户输入作文类型和话题方向,AI生成对应的作文模板、范文、高分句型、高级词汇替换及常见错误提示。

需求细化与边界确认:

维度 详细说明
输入字段 作文类型(大作文图画/小作文书信/小作文通知)、话题方向(如环保/科技/社会)
输出字段 模板框架、范文示例、三段式结构、高分句型列表、高级词汇表(含同义替换用法)、灵活使用建议、常见错误列表
数据来源 当前阶段使用Mock数据,后续可接入真实大模型API
交互方式 用户填写表单 → 点击按钮 → 展示结果列表
非功能需求 遵循ArkTS语法约束、支持深色主题、页面响应式布局

关键决策点:

  1. 数据流方向:采用单向数据流,用户输入经State驱动绑定,点击按钮触发Service层生成数据,结果通过State变量驱动UI更新。
  2. Mock数据策略:当前阶段Service层返回固定示例数据,预留AI接口扩展点,后续接入大模型时只需替换Service实现。
  3. UI风格统一:遵循现有应用列表的视觉风格(灰白底色、圆角卡片、monospace字体),保持整体一致性。

1.3 技术约束确认

在HarmonyOS ArkTS环境下开发,必须严格遵守以下核心语法约束:

  • 不支持 any/unknown 类型:所有变量必须显式指定类型
  • 不支持解构赋值:必须使用临时变量逐字段操作
  • 不支持 for...in 遍历对象:数组使用常规 for 循环
  • 不支持 Function.apply/call/bind:遵循传统OOP的 this 语义
  • 不支持索引签名:使用数组替代
  • 不支持对象类型中的调用签名:使用 class 实现
  • 不支持 as const 断言:使用显式类型标注
  • 不支持索引访问类型:直接使用类型名称
  • 展开运算符仅支持数组展开到rest参数或数组字面量

这些约束直接影响代码写法,本文将逐一展示如何在代码中规避这些限制。


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

2.1 整体架构设计

基于MVVM模式,将应用拆分为三层:

┌─────────────────────────────────────────────────┐
│                    View层                         │
│     AI考研英语作文模板Page.ets                      │
│   @State 驱动 UI  |  @Builder 封装组件              │
│   用户输入绑定 | 结果展示 | 交卷按钮交互             │
├─────────────────────────────────────────────────┤
│                   Service层                       │
│     AI考研英语作文模板Service.ets                    │
│   数据生成逻辑 | Prompt 封装 | AI 接口调用           │
│   输入校验 | 数据组装 | 扩展点预留                   │
├─────────────────────────────────────────────────┤
│                   Model层                         │
│     AI考研英语作文模板Model.ets                      │
│   数据实体定义 | 字段类型声明 | 构造器初始化          │
└─────────────────────────────────────────────────┘

数据流向:

用户输入 → State.inputData (双向绑定)
         → onClick 触发 Service.generateData()
         → Service 组装/生成数据
         → 返回 AI考研英语作文模板Data 实例
         → State.resultData 更新
         → UI 自动重渲染 (if 条件渲染)

2.2 核心组件设计

2.2.1 Model层:数据实体定义

Model层定义 AI考研英语作文模板Data 类,承载所有AI生成的输出字段。根据ArkTS不支持对象类型中的调用签名、不支持索引签名的约束,这里使用 class 而非 interface,所有字段显式声明并初始化:

// AI考研英语作文模板Model.ets
export class AI考研英语作文模板Data {
  template: string = ''
  sample_essay: string = ''
  paragraph_1: string = ''
  paragraph_2: string = ''
  paragraph_3: string = ''
  structure: string = ''
  highlight_sentences: string[] = []
  vocabulary: string[] = []
  word: string = ''
  synonym: string = ''
  usage: string = ''
  flexibility: string = ''
  common_mistakes: string[] = []

  constructor() {
    this.template = ''
    this.sample_essay = ''
    this.paragraph_1 = ''
    this.paragraph_2 = ''
    this.paragraph_3 = ''
    this.structure = ''
    this.highlight_sentences = []
    this.vocabulary = []
    this.word = ''
    this.synonym = ''
    this.usage = ''
    this.flexibility = ''
    this.common_mistakes = []
  }
}

设计要点:

  • 所有字段使用 stringstring[] 等显式类型,避免 any/unknown
  • 每个字段在声明时赋默认值,遵循ArkTS"不支持确定性赋值断言"的约束
  • 构造函数中重复初始化,确保 new 实例后所有字段有确定值
  • 使用 class 而非 interface,因为数据需要被实例化传递
2.2.2 Service层:业务逻辑封装

Service层封装数据生成逻辑,作为Model和View之间的桥梁。当前使用Mock数据,但从架构设计上预留了AI接口扩展的能力:

// AI考研英语作文模板Service.ets
import { AI考研英语作文模板Data } from './AI考研英语作文模板Model'

export class AI考研英语作文模板Service {
  private model: AI考研英语作文模板Data

  constructor() {
    this.model = new AI考研英语作文模板Data()
  }

  generateData(input: Record<string, Object>): AI考研英语作文模板Data {
    let result: AI考研英语作文模板Data = new AI考研英语作文模板Data()
    // 从输入中提取作文类型
    let essayTypeVal: string = String(input['essay_type'] || '')
    // Mock数据生成
    result.template = '生成结果:' + essayTypeVal
    result.sample_essay = '生成结果:' + essayTypeVal
    result.structure = '生成结果:' + essayTypeVal
    result.highlight_sentences = ['示例项1', '示例项2', '示例项3']
    result.vocabulary = ['示例数据1', '示例数据2', '示例数据3']
    result.flexibility = '生成结果:' + essayTypeVal
    result.common_mistakes = ['示例项1', '示例项2', '示例项3']
    return result
  }
}

设计要点:

  • 使用 Record<string, Object> 接收输入参数,避免使用 any 类型
  • 通过 String() 显式转换,确保类型安全
  • 构造函数中初始化 model 字段,类字段在声明处初始化
2.2.3 View层:声明式UI

View层采用ArkUI声明式语法,通过 @State 装饰器驱动数据绑定,实现UI自动更新:

// AI考研英语作文模板Page.ets
import { AI考研英语作文模板Data } from './AI考研英语作文模板Model'
import { AI考研英语作文模板Service } from './AI考研英语作文模板Service'
import { router } from '@kit.ArkUI'

@Entry
@Component
struct AI考研英语作文模板Page {
  @State inputData: Record<string, Object> = {}
  @State resultData: AI考研英语作文模板Data | null = null
  @State showResult: boolean = false
  private service: AI考研英语作文模板Service = new AI考研英语作文模板Service()

  build() {
    Column() {
      // 考试风格的Header
      Row() {
        Text('← 返回')
          .fontSize(13)
          .fontColor('#1E293B')
          .onClick(() => { router.back() })
        Blank()
        Column() {
          Text('📱 AI考研英语作文模板')
            .fontSize(17)
            .fontWeight(FontWeight.Bold)
            .fontColor('#1E293B')
          Text('EXAMINATION · 答题卡')
            .fontSize(9)
            .fontColor('#64748B')
            .margin({ top: 2 })
        }
        Blank()
        Text('📝').fontSize(22)
      }
      .width('100%')
      .padding({ left: 20, right: 20, top: 16, bottom: 14 })
      .backgroundColor('#F8FAFC')

      Scroll() {
        Column() {
          // 答题卡式输入区域
          this.buildInputCard()
          // 交卷按钮
          this.buildSubmitButton()
          // 结果展示区域
          this.buildResultCard()
        }
        .width('100%')
        .padding({ left: 18, right: 18, bottom: 40 })
      }
      .layoutWeight(1)
    }
    .width('100%').height('100%')
    .backgroundColor('#F8FAFC')
  }
  // ... 后续详述 @Builder 方法
}

2.3 路由与配置设计

应用需要注册到两个配置文件中才能正常导航:

main_pages.json —— 路由注册:

{
  "src": [
    "pages/Index",
    "apps/AI考研英语作文模板/AI考研英语作文模板Page",
    // ... 其他应用
  ]
}

apps.json —— 应用列表注册:

{
  "icon": "📝",
  "title": "AI考研英语作文模板",
  "subtitle": "考研英语",
  "color": "#F59E0B",
  "bg": "#FFFBEB",
  "border": "#FDE68A",
  "page": "apps/AI考研英语作文模板/AI考研英语作文模板Page",
  "cat": "学习成长"
}

三、原子化阶段(Atomize):将任务分解为可管理单元

将整个开发任务分解为5个原子任务,每个任务独立可执行、可验证:

任务1:Model数据模型创建

目标:定义 AI考研英语作文模板Data 类,包含所有AI输出字段。

验收标准

  • 所有字段为 stringstring[] 类型
  • 每个字段在声明时初始化默认值
  • 构造函数中完成二次初始化
  • 文件导出 export class 供其他模块引用

代码实现:见前文Model层设计。

任务2:Service服务层实现

目标:实现 AI考研英语作文模板Service 类,封装 generateData 方法。

验收标准

  • 接收 Record<string, Object> 类型输入
  • 返回 AI考研英语作文模板Data 类型结果
  • 当前使用Mock数据,预留AI接口扩展点
  • 类字段在声明处初始化

代码实现:见前文Service层设计。

任务3:Page页面UI构建

目标:使用ArkUI声明式语法构建完整页面,包含输入表单、交卷按钮、结果展示区。

验收标准

  • 输入区域包含"作文类型"和"话题方向"两个输入框
  • 交卷按钮触发数据生成
  • 结果区域展示模板、范文、段落、句型、词汇、常见错误等信息
  • 使用 @Builder 拆分组件,提高可读性
  • 使用 @State 驱动数据绑定
  • 支持 if 条件渲染控制结果区域的显隐

关键代码——@Builder拆分组件:

@Builder
buildInputCard() {
  Column() {
    Text('姓名: ________  准考证号: ________')
      .fontSize(11)
      .fontColor('#64748B')
      .fontFamily('monospace')
      .width('100%')
      .margin({ bottom: 12 })
    
    Text('作文类型:')
      .fontSize(11)
      .fontColor('#475569')
      .margin({ top: 8, bottom: 3 })
    TextInput({ placeholder: '请输入作文类型(大作文/小作文)' })
      .fontSize(13)
      .height(40)
      .backgroundColor('#FFFFFF')
      .border({ width: { bottom: 1 }, color: '#CBD5E1' })
      .padding({ left: 8, right: 8 })
      .onChange((val: string) => { this.inputData['作文类型'] = val })
    
    Text('话题方向:')
      .fontSize(11)
      .fontColor('#475569')
      .margin({ top: 8, bottom: 3 })
    TextInput({ placeholder: '请输入话题方向(如环保/科技/社会)' })
      .fontSize(13)
      .height(40)
      .backgroundColor('#FFFFFF')
      .border({ width: { bottom: 1 }, color: '#CBD5E1' })
      .padding({ left: 8, right: 8 })
      .onChange((val: string) => { this.inputData['话题方向'] = val })
  }
  .width('100%')
  .padding(20)
  .backgroundColor('#FFFFFF')
  .border({ width: 1, color: '#CBD5E1', radius: 4 })
  .margin({ top: 12 })
}

关键代码——交卷按钮与结果展示:

@Builder
buildSubmitButton() {
  Button('📱  交卷批改')
    .width('100%')
    .height(50)
    .backgroundColor('#1E293B')
    .borderRadius(4)
    .fontColor('#FFFFFF')
    .fontSize(16)
    .fontWeight(FontWeight.Bold)
    .margin({ top: 18, bottom: 14 })
    .onClick(() => {
      this.resultData = this.service.generateData(this.inputData)
      this.showResult = true
    })
}

@Builder
buildResultCard() {
  if (this.showResult && this.resultData !== null) {
    Column() {
      Text('📋 批改结果')
        .fontSize(15)
        .fontWeight(FontWeight.Bold)
        .fontColor('#1E293B')
        .margin({ bottom: 12 })
      
      // 逐行展示结果字段
      this.buildResultRow('Template: ', this.resultData.template)
      this.buildResultRow('Sample essay: ', this.resultData.sample_essay)
      this.buildResultRow('Paragraph 1: ', this.resultData.paragraph_1)
      this.buildResultRow('Paragraph 2: ', this.resultData.paragraph_2)
      this.buildResultRow('Paragraph 3: ', this.resultData.paragraph_3)

      // 高分句型列表
      Text('Highlight sentences')
        .fontSize(13)
        .fontWeight(FontWeight.Bold)
        .fontColor('#333333')
        .margin({ top: 10, bottom: 6 })
      if (this.resultData.highlight_sentences) {
        ForEach(this.resultData.highlight_sentences, (item: string, index: number) => {
          Row() {
            Text('• ').fontSize(12).fontColor('#666666')
            Text(item).fontSize(12).fontColor('#333333')
          }
          .width('100%')
          .padding({ top: 2, bottom: 2 })
        }, (item: string, index: number) => index.toString())
      }

      // 高级词汇列表
      Text('Vocabulary')
        .fontSize(13)
        .fontWeight(FontWeight.Bold)
        .fontColor('#333333')
        .margin({ top: 10, bottom: 6 })
      if (this.resultData.vocabulary) {
        ForEach(this.resultData.vocabulary, (item: string, index: number) => {
          Row() {
            Text('• ').fontSize(12).fontColor('#666666')
            Text(item).fontSize(12).fontColor('#333333')
          }
          .width('100%')
          .padding({ top: 2, bottom: 2 })
        }, (item: string, index: number) => index.toString())
      }

      // 词汇详情
      this.buildResultRow('Word: ', this.resultData.word)
      this.buildResultRow('Synonym: ', this.resultData.synonym)
      this.buildResultRow('Usage: ', this.resultData.usage)
      this.buildResultRow('Flexibility: ', this.resultData.flexibility)

      // 常见错误
      Text('Common mistakes')
        .fontSize(13)
        .fontWeight(FontWeight.Bold)
        .fontColor('#333333')
        .margin({ top: 10, bottom: 6 })
      if (this.resultData.common_mistakes) {
        ForEach(this.resultData.common_mistakes, (item: string, index: number) => {
          Row() {
            Text('• ').fontSize(12).fontColor('#666666')
            Text(item).fontSize(12).fontColor('#333333')
          }
          .width('100%')
          .padding({ top: 2, bottom: 2 })
        }, (item: string, index: number) => index.toString())
      }
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#FFFFFF')
    .border({ width: 1, color: '#CBD5E1', radius: 4 })
    .margin({ bottom: 20 })
  }
}

@Builder
buildResultRow(label: string, value: string) {
  Row() {
    Text(label)
      .fontSize(12)
      .fontWeight(FontWeight.Medium)
      .fontColor('#666666')
    Text(value)
      .fontSize(12)
      .fontColor('#333333')
  }
  .width('100%')
  .padding({ top: 4, bottom: 4 })
}

任务4:路由注册与配置

目标:将应用注册到 main_pages.json 路由表和 apps.json 应用列表。

验收标准

  • main_pages.json 中包含 "apps/AI考研英语作文模板/AI考研英语作文模板Page"
  • apps.json 中包含该应用的完整配置项(icon、title、subtitle、color、bg、border、page、cat)
  • 分类(cat)为 “学习成长”

任务5:集成到应用列表

目标:确保应用在首页列表中正确显示,点击可跳转。

验收标准

  • 首页 Index.ets 能通过 apps.json 读取到该应用配置
  • 在 “学习成长” 分类下可找到该应用
  • 点击应用卡片可正常跳转到 AI考研英语作文模板Page

四、审批阶段(Approve):质量门控与审查

在原子化任务分解完成后,进入审批阶段,对每个交付物进行质量审查。审查维度包括代码规范、架构一致性、语法合规性、功能完整性。

4.1 ArkTS语法合规审查

针对ArkTS的语法约束,逐条审查代码:

审查项 涉及文件 审查结果 说明
any/unknown 类型 全部 使用 stringstring[]Record<string, Object>boolean 等显式类型
无解构赋值 全部 直接使用 this.inputData['作文类型'] 通过索引访问
for...in 遍历 Page.ets 使用 ForEach 组件遍历数组
Function.bind/call 全部 使用箭头函数 onClick(() => {...})
无索引签名 Model.ets 使用 string[] 数组替代索引签名
类字段声明处初始化 全部 所有字段声明时赋默认值
as const 断言 全部 使用字面量显式标注
无对象类型调用签名 全部 使用 class 替代
import 语句在文件最前 全部 所有 import 在文件开头
this 在静态方法中 全部 this 仅在实例方法中使用

4.2 架构一致性审查

确认代码与已有项目架构保持一致:

  • MVVM三层分离:Page.ets(View)→ Service.ets(ViewModel)→ Model.ets(Model),与已有应用一致
  • @State 驱动数据绑定:使用 @State 装饰器管理状态,与 Index.ets 及其他应用一致
  • router 导航:使用 router.pushUrlrouter.back() 进行页面跳转,与现有模式一致
  • @Builder 组件拆分:使用 @Builder 装饰器拆分UI,与现有代码风格一致
  • 资源引用:未使用硬编码字符串作为UI文本,符合 $r 引用规范

4.3 功能完整性审查

功能点 状态 说明
作文类型输入 TextInput 组件,onChange 绑定到 inputData
话题方向输入 TextInput 组件,onChange 绑定到 inputData
交卷按钮触发 onClick 调用 service.generateData
结果展示 if 条件渲染,展示全部字段
高分句型列表 ForEach 遍历 highlight_sentences
高级词汇列表 ForEach 遍历 vocabulary
常见错误列表 ForEach 遍历 common_mistakes
返回按钮 router.back() 返回首页
路由配置 main_pages.json 已注册
应用列表 apps.json 已注册,分类为"学习成长"

4.4 性能与体验审查

  • scrollable 容器:内容区域使用 Scroll 包裹,支持长内容滚动
  • 条件渲染减少开销:结果区域使用 if (this.showResult && this.resultData !== null) 控制渲染,避免初始加载时渲染不可见内容
  • ForEach 的 key 生成:使用 (item: string, index: number) => index.toString() 生成唯一key,避免列表重渲染问题
  • 布局属性动画:未在动画中频繁修改 width/height/padding/margin 等布局属性,符合动画性能规范

五、自动化执行阶段(Automate):从代码到交付

5.1 自动化代码生成

在"AI考研英语作文模板"的开发过程中,可以借助自动化脚本快速生成三层架构的骨架代码。以下是一个自动化生成模板的脚本思路:

// 自动化代码生成脚本(伪代码示例)
// 功能:根据应用名称自动生成 Model、Service、Page 三层骨架代码

function generateAIApp(appName: string): void {
  // 1. 创建应用目录
  const appDir = `apps/${appName}`
  createDirectory(appDir)
  
  // 2. 生成 Model 文件
  const modelContent = generateModelTemplate(appName)
  writeFile(`${appDir}/${appName}Model.ets`, modelContent)
  
  // 3. 生成 Service 文件
  const serviceContent = generateServiceTemplate(appName)
  writeFile(`${appDir}/${appName}Service.ets`, serviceContent)
  
  // 4. 生成 Page 文件
  const pageContent = generatePageTemplate(appName)
  writeFile(`${appDir}/${appName}Page.ets`, pageContent)
  
  // 5. 注册路由
  appendToMainPages(appName)
  
  // 6. 注册应用到列表
  appendToAppsJson(appName)
}

5.2 路由注册自动化

main_pages.json 中注册路由是将应用接入导航系统的关键步骤。对于"AI考研英语作文模板",其注册条目为:

{
  "src": [
    "pages/Index",
    // ... 其他应用
    "apps/AI考研英语作文模板/AI考研英语作文模板Page"
  ]
}

5.3 应用列表注册自动化

apps.json 中注册应用卡片信息,决定其在首页的展示样式和分类:

{
  "icon": "📝",
  "title": "AI考研英语作文模板",
  "subtitle": "考研英语",
  "color": "#F59E0B",
  "bg": "#FFFBEB",
  "border": "#FDE68A",
  "page": "apps/AI考研英语作文模板/AI考研英语作文模板Page",
  "cat": "学习成长"
}

5.4 构建与验证流程

自动化构建流程包括以下步骤:

1. 代码变更 → 2. hvigor 增量编译 → 3. 语法检查 → 4. 资源合并 → 5. 打包 hap → 6. 安装部署

在ArkTS编译过程中,编译器的语法检查会自动捕获如下违规:

  • 使用 any/unknown 类型 → 编译报错
  • 使用解构赋值 → 编译报错
  • 使用 for...in → 编译报错
  • 类字段未初始化 → 编译报错
  • 索引签名 → 编译报错

这些编译时检查确保了代码在运行前就符合ArkTS的全部约束。

5.5 持续集成配置

在项目级 oh-package.json5 中管理依赖:

{
  "name": "entry",
  "version": "1.0.0",
  "description": "HarmonyOS AI应用集合",
  "main": "",
  "author": "",
  "license": "",
  "dependencies": {}
}

当前项目无外部依赖,所有AI能力通过Service层的Mock实现,后续接入大模型时在此处添加对应依赖即可。


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

6.1 技术成果总结

"AI考研英语作文模板"应用的开发完整实践了HarmonyOS ArkTS生态下的AI应用开发全流程:

技术指标:

指标 数值
代码文件数 3个(Model + Service + Page)
代码行数 约320行
页面组件数 5个 @Builder 组件
数据字段 14个输出字段
路由注册 2处(main_pages.json + apps.json)
编译检查 0语法违规

架构成果:

  1. MVVM三层架构落地:Model层定义数据实体,Service层封装业务逻辑,View层通过 @State 驱动UI更新,层次清晰,职责单一。
  2. ArkTS语法约束的全面遵守:在代码中严格规避了 any/unknown、解构赋值、for...in、索引签名等ArkTS不支持的特性,确保编译通过。
  3. 声明式UI的高效实践:利用 @State + @Builder + ForEach 的组合,实现了数据驱动的UI自动更新,减少了手动DOM操作的复杂性。
  4. 模块化设计:每个AI应用独立为一个目录,彼此无耦合,便于后续添加新应用时复用开发模式。

6.2 技术难点与解决方案

难点1:ArkTS语法约束下的类型安全

在ArkTS中,不支持 anyunknown 类型,所有变量必须显式指定类型。对于输入参数这种不确定结构的数据,使用 Record<string, Object> 作为类型,通过 String() 显式转换取值:

// 输入参数类型
@State inputData: Record<string, Object> = {}

// 取值时显式转换
let essayTypeVal: string = String(input['essay_type'] || '')

难点2:列表数据的条件渲染

ArkTS不支持解构赋值,但结果数据中包含多个列表字段(highlight_sentencesvocabularycommon_mistakes)。解决方案是使用 ForEach 组件配合 if 判空:

if (this.resultData.highlight_sentences) {
  ForEach(this.resultData.highlight_sentences, (item: string, index: number) => {
    // 渲染列表项
  }, (item: string, index: number) => index.toString())
}

难点3:路由配置的维护

随着应用数量增加(当前已有多个应用),main_pages.jsonapps.json 的维护成本上升。解决方案是采用自动化脚本生成路由配置,确保新增应用时不会遗漏注册步骤。

6.3 未来展望

短期优化方向:

  1. 接入真实大模型API:当前Service层使用Mock数据,计划接入LLM API(如接入HarmonyOS的AI能力或第三方大模型),通过Prompt工程生成真实的作文模板内容。示例Prompt设计如下:
你是一个考研英语作文辅导专家。请根据以下要求生成作文模板:
- 作文类型:{essay_type}
- 话题方向:{topic}
- 目标分数:{target_score}
请输出:1. 模板框架  2. 范文示例  3. 三段式结构  4. 高分句型  5. 高级词汇替换  6. 常见错误提示
  1. 增加输入字段:当前只有"作文类型"和"话题方向"两个输入,后续可增加"目标分数"(及格/中等/高分)和"字数要求"等字段,使生成结果更精准。

  2. 优化UI交互:增加加载状态提示(@State loading: boolean),在AI生成过程中显示加载动画,提升用户体验。

中长期演进方向:

  1. 数据持久化:将生成的作文模板保存到本地数据库,支持历史记录查看和重新编辑。

  2. 个性化推荐:基于用户的历史生成记录,推荐更符合其写作水平的模板和词汇。

  3. 多端适配:利用HarmonyOS的跨端能力,适配平板和折叠屏设备,优化大屏下的布局展示。

  4. AI能力深化:不局限于模板生成,扩展到作文批改、语法纠错、分数预测等更丰富的AI辅助功能。

6.4 经验教训

正向经验:

  • 原子化分解提高了开发效率:将任务拆分为Model、Service、Page、路由、配置5个独立单元,每个单元可并行开发、独立测试,避免了耦合带来的返工。
  • @Builder 组件拆分提升了可维护性:将输入卡片、交卷按钮、结果卡片等拆分为独立 @Builder,代码结构清晰,后续修改某一块不会影响其他区域。
  • 严格遵守ArkTS约束节省了调试时间:在编码阶段就按照ArkTS规范编写,避免了编译阶段的反复修改。

改进空间:

  • 自动化程度有待提升:当前代码生成仍需手动操作,后续可开发完整的脚手架工具,输入应用名称即自动生成完整的三层架构代码并注册路由。
  • 测试覆盖不足:当前仅通过编译检查和手动测试验证,缺少自动化测试用例(如UI自动化测试、Service层单元测试)。

6.5 对团队的启示

"AI考研英语作文模板"的开发实践为HarmonyOS AI应用开发提供了可复用的工程化参考:

  1. 模板化开发:形成了"Page + Model + Service"的标准模板,新应用开发只需填充具体业务逻辑。
  2. 原子化交付:每个子应用独立开发、独立测试、独立部署,降低了大型应用的维护复杂度。
  3. **ArkTS最
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐