基于HarmonyOS的AI考研择校分析——从对齐到评估的全流程技术实践
基于HarmonyOS的AI考研择校分析——从对齐到评估的全流程技术实践
一、对齐阶段(Align):从模糊需求到精确规范
1.1 项目上下文分析
在当前考研热度持续攀升的背景下,每年数百万考生面临着"选择比努力更重要"的关键决策——院校和专业的选择直接决定了备考难度、竞争压力和最终录取概率。然而,大多数考生在择校时面临信息不对称、数据分散、缺乏个性化分析工具等痛点。本项目"AI考研择校分析"正是基于HarmonyOS生态,旨在通过AI技术为考生提供智能化、个性化的择校分析服务。
从项目上下文来看,我们正处于一个庞大的HarmonyOS AI应用矩阵之中。当前项目目录位于 entry/src/main/ets/apps/AI考研择校分析/,与AI宝宝辅食搭配、AI跑步训练计划、AI睡眠改善方案等数十个AI应用并列。每个应用都遵循统一的Model-Service-Page三层架构模式,共享同一个Index主页的网格入口和路由体系。这种架构设计确保了代码的高度可复用性和可维护性,也使得新应用的开发可以基于成熟的模板快速推进。
在技术栈方面,项目采用HarmonyOS ArkTS作为主要开发语言。ArkTS基于TypeScript但进行了针对HarmonyOS的深度优化,强调编译时类型安全和运行时性能。与标准TypeScript相比,ArkTS有以下关键差异需要注意:不支持any和unknown类型,要求所有变量显式指定类型;不支持解构赋值和as const断言;对象字面量必须有明确的类或接口对应;this只能在实例方法中使用,不能在独立函数和静态方法中使用。这些约束虽然增加了编码时的严谨性要求,但也带来了更好的编译时错误捕获能力和运行时性能表现。
1.2 需求规格与边界确认
原始需求描述:
用户需要一个能够根据个人背景智能推荐考研院校的AI工具。用户输入专业、本科背景、目标地区等信息,AI系统应输出多维度的择校分析报告,包括推荐院校列表、冲刺/匹配/保底梯度划分、备考建议、时间规划等。
需求规格细化:
经过对原始需求的深入分析和边界确认,我们将需求细化为以下明确的输入输出规范:
用户输入字段(Record<string, Object>):
major(字符串):报考专业,如"计算机科学与技术"、“金融学”undergrad(字符串):本科院校层次,如"985"、“211”、“双非”region(字符串):目标地区,如"北京"、“上海”、“江浙沪”score_estimate(字符串,可选):预估分数preference(字符串,可选):学位类型偏好,如"学硕"、“专硕”
AI输出字段(对应AI考研择校分析Data类):
recommendations(字符串数组):推荐院校列表,包含推荐理由school(字符串):推荐院校名称level(字符串):院校层次标签,如"985"、“211”、“双一流”、“普通”difficulty(字符串):考研难度评估,如"高"、“中”、“低”score_line(字符串):历年分数线参考pros(字符串):选择该校的优势分析cons(字符串):选择该校的劣势分析ratio(字符串):报录比数据reach(字符串):冲刺院校推荐match(字符串):匹配院校推荐safety(字符串):保底院校推荐strategy(字符串):整体择校策略建议preparation(字符串):备考建议timeline(字符串):备考时间轴规划info_sources(字符串):信息获取渠道推荐
1.3 目标用户群体分析
核心用户画像:
- 考研应届生(占比约60%):大三、大四在校学生,首次考研,对院校信息了解有限,需要全面的择校指导。
- 考研往届生/在职考生(占比约25%):有考研经验或工作后决定考研,对目标有更清晰的认识,需要精准的数据分析支持。
- 家长/教育从业者(占比约15%):辅助考生进行决策,需要多维度对比和客观的数据支撑。
核心用户痛点:
- 信息过载:全国数百所院校、数千个专业,传统方式需要逐个官网查询,耗时巨大且容易遗漏。
- 数据时效性:报录比、分数线等数据每年变化,手动收集难以保证最新。
- 个性化缺失:通用榜单无法结合个人背景(本科层次、专业热度、地域偏好)给出针对性建议。
- 梯度规划困难:冲刺、匹配、保底院校的比例和选择缺乏科学依据。
1.4 技术约束确认
在项目启动阶段,我们还需要确认一系列技术约束。通过分析现有项目代码和工程配置,我们梳理出以下关键约束:
ArkTS语法约束要点:
- 所有变量必须显式声明类型,不支持类型推断的隐式声明
- 组件状态管理使用
@State装饰器,驱动UI响应式更新 - 不支持
any和unknown类型,对象类型必须明确 - 不支持解构赋值,需显式逐字段赋值
- 不支持
for...in遍历对象,数组使用常规for循环或ForEach - 所有
import语句必须在文件顶部,在所有其他语句之前 - 类和接口的定义必须紧凑,不支持声明合并
- 不支持对象字面量直接作为类型声明,必须使用显式的类或接口
路由与资源约束:
- 页面路由需要在
main_pages.json中注册,路径格式为apps/应用名/应用名Page - 应用入口需要在
apps.json中配置,包含图标、标题、颜色、分类等信息 - 应用图标和文本资源优先使用
$r引用resources目录下的资源文件
二、架构阶段(Architect):从共识到系统设计
2.1 整体架构设计
AI考研择校分析采用经典的MVVM(Model-View-ViewModel)架构模式,在HarmonyOS ArkTS中具体表现为Model-Service-Page三层架构:
┌─────────────────────────────────────────────────┐
│ Page 层 (View) │
│ ArkUI 声明式 UI + @State 状态管理 │
│ 用户输入采集 + 结果展示渲染 │
├─────────────────────────────────────────────────┤
│ Service 层 (ViewModel) │
│ 业务逻辑编排 + AI 数据生成 │
│ 输入校验 + 数据格式化 + Prompt 构建 │
├─────────────────────────────────────────────────┤
│ Model 层 (Model) │
│ 数据实体定义 + 类型约束 │
│ 输出数据结构 + 字段类型声明 │
└─────────────────────────────────────────────────┘
分层职责说明:
-
Page层:负责UI渲染和用户交互,使用ArkUI声明式语法构建组件树,通过
@State装饰器管理组件状态,通过@Builder装饰器封装可复用的UI片段。用户输入通过TextInput组件的onChange回调收集,结果通过条件渲染(if表达式)展示。 -
Service层:封装业务逻辑,接收Page层传递的原始输入数据,进行校验和预处理,构建AI调用所需的Prompt或数据格式,最后将处理结果返回给Page层。Service层是连接View和Model的桥梁,也是未来接入真实大模型API的扩展点。
-
Model层:定义应用程序的数据模型,使用
class关键字声明数据类,所有字段显式声明类型并赋予默认值。Model层是纯数据容器,不包含任何业务逻辑。
2.2 核心数据流设计
用户输入 → TextInput.onChange() → inputData (Record<string, Object>)
↓
Button.onClick() 触发数据生成
↓
Service.generateData(inputData) → 业务处理
↓
返回 AI考研择校分析Data 实例
↓
@State resultData 更新 → UI 自动重新渲染
↓
展示结果卡片(推荐院校、梯度分析、备考建议等)
数据流的核心特点:
-
单向数据流:数据从用户输入流向Service层,经过处理后流入状态变量,最终驱动UI刷新。不存在反向数据修改路径,保证了数据的一致性和可追溯性。
-
状态驱动渲染:ArkUI的响应式系统通过
@State装饰器监听状态变化。当resultData被赋值时,框架自动检测到状态变更,重新执行build()方法中依赖该状态的条件渲染分支,仅更新发生变化的部分DOM节点,而非整体重绘。 -
异步友好设计:虽然当前版本使用同步Mock数据,但Service层的接口设计天然支持异步扩展。未来接入真实大模型API时,只需将
generateData方法改为async,使用await调用AI接口,Page层通过@State管理的loading状态控制加载动画即可。
2.3 组件树设计
Column (根容器, backgroundColor: #F5E6D3)
├── Row (顶部导航栏)
│ ├── Text('← 返回') → router.back()
│ ├── Blank()
│ ├── Column (标题区域)
│ │ ├── Text('📱 AI考研择校分析')
│ │ └── Text('ADMISSION · 录取通知')
│ ├── Blank()
│ └── Text('🎓')
├── Scroll (可滚动内容区域)
│ └── Column
│ ├── Column (输入表单卡片)
│ │ ├── Text('🎓 专业')
│ │ ├── TextInput (专业输入)
│ │ ├── Text('🎓 本科背景')
│ │ ├── TextInput (本科背景输入)
│ │ ├── Text('🎓 目标地区')
│ │ └── TextInput (目标地区输入)
│ ├── Button('📱 🎓 生成通知书')
│ └── if (showResult && resultData !== null)
│ └── Column (结果卡片)
│ ├── Text('🎓 录取通知书')
│ ├── Text('Recommendations')
│ ├── ForEach (推荐列表)
│ │ └── Row
│ │ ├── Text('• ')
│ │ └── Text(item)
│ ├── Row: school
│ ├── Row: level
│ ├── Row: difficulty
│ ├── Row: score_line
│ ├── Row: pros
│ ├── Row: cons
│ ├── Row: ratio
│ ├── Row: reach
│ ├── Row: match
│ ├── Row: safety
│ ├── Row: preparation
│ ├── Row: timeline
│ └── Row: info_sources
2.4 接口契约定义
Service层对外接口:
// 输入:用户填写的表单数据,键为字段名,值为对应输入值
// 输出:AI考研择校分析Data 实例,包含所有分析结果字段
generateData(input: Record<string, Object>): AI考研择校分析Data
Model层数据结构:
class AI考研择校分析Data {
recommendations: string[] // 推荐院校列表
school: string // 推荐院校名称
level: string // 院校层次
difficulty: string // 难度评估
score_line: string // 分数线
pros: string // 优势
cons: string // 劣势
ratio: string // 报录比
reach: string // 冲刺院校
match: string // 匹配院校
safety: string // 保底院校
strategy: string // 择校策略
preparation: string // 备考建议
timeline: string // 时间轴
info_sources: string // 信息渠道
}
三、原子化阶段(Atomize):任务分解与执行计划
3.1 任务分解
在架构设计确认后,我们将整个开发任务分解为以下可独立执行的原子任务:
任务1:创建Model数据模型
- 文件路径:
AI考研择校分析Model.ets - 任务内容:定义
AI考研择校分析Data类,声明所有字段及其类型,提供默认值初始化 - 依赖关系:无,是所有后续任务的基础
- 预估工时:0.5小时
任务2:实现Service服务层
- 文件路径:
AI考研择校分析Service.ets - 任务内容:实现
AI考研择校分析Service类,包含generateData方法,处理输入数据并生成分析结果 - 依赖关系:依赖Model层的数据结构定义
- 预估工时:1小时
任务3:构建Page页面UI
- 文件路径:
AI考研择校分析Page.ets - 任务内容:构建完整的用户界面,包括输入表单、触发按钮、结果展示卡片,实现状态管理
- 依赖关系:依赖Service层的数据生成能力
- 预估工时:2小时
任务4:注册路由配置
- 文件路径:
main_pages.json - 任务内容:在路由配置文件中添加AI考研择校分析页面的路由路径
- 依赖关系:依赖Page层文件创建完成
- 预估工时:0.2小时
任务5:集成到应用列表
- 文件路径:
apps.json - 任务内容:在应用列表配置中添加AI考研择校分析的入口信息,包括图标、标题、分类等
- 依赖关系:依赖Page层文件创建完成
- 预估工时:0.2小时
3.2 任务依赖关系图
任务1 (Model) ──→ 任务2 (Service) ──→ 任务3 (Page)
│
┌─────────┴─────────┐
▼ ▼
任务4 (路由注册) 任务5 (应用列表)
3.3 验收标准
Model层验收标准:
AI考研择校分析Data类包含所有必需的字段- 所有字段具有正确的类型声明
- 构造函数中为所有字段提供默认值
Service层验收标准:
generateData方法接收Record<string, Object>类型参数- 返回类型为
AI考研择校分析Data - 正确处理输入数据,生成Mock结果
Page层验收标准:
- 输入表单包含专业、本科背景、目标地区三个输入字段
- 生成按钮触发数据生成逻辑
- 结果展示区域在生成数据后显示
- 结果卡片包含所有数据字段的展示
- 顶部导航栏包含返回按钮和标题
- 整体UI风格统一,配色协调
路由和集成验收标准:
- 页面可通过首页网格入口正常跳转
- 返回按钮可正常返回首页
- 应用在正确的分类下显示
四、审批阶段(Approve):代码审查与质量门控
4.1 Model层代码审查
源文件: AI考研择校分析Model.ets
export class AI考研择校分析Data {
recommendations: string[] = []
school: string = ''
level: string = ''
difficulty: string = ''
score_line: string = ''
pros: string = ''
cons: string = ''
ratio: string = ''
reach: string = ''
match: string = ''
safety: string = ''
strategy: string = ''
preparation: string = ''
timeline: string = ''
info_sources: string = ''
constructor() {
this.recommendations = []
this.school = ''
this.level = ''
this.difficulty = ''
this.score_line = ''
this.pros = ''
this.cons = ''
this.ratio = ''
this.reach = ''
this.match = ''
this.safety = ''
this.strategy = ''
this.preparation = ''
this.timeline = ''
this.info_sources = ''
}
}
审查意见:
-
类型安全 ✅ 所有字段都显式声明了类型,符合ArkTS规范。
recommendations使用string[]类型,其他字段使用string类型,类型定义清晰准确。 -
默认值初始化 ✅ 类声明时就为每个字段提供了默认值(空字符串或空数组),同时在构造函数中再次进行了初始化。这种双重初始化的做法虽然略显冗余,但确保了无论通过何种方式(直接赋值或构造)创建对象,所有字段都有合法的初始值。
-
命名规范 ✅ 使用中文命名(
AI考研择校分析Data)与项目整体风格保持一致,字段名采用驼峰命名法(score_line、info_sources),清晰表达语义。 -
扩展性 ✅ 数据类仅包含字段声明和构造初始化,不包含任何业务逻辑,符合单一职责原则。未来如果需要添加新字段,只需在类中追加声明并初始化即可。
4.2 Service层代码审查
源文件: AI考研择校分析Service.ets
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 majorVal: string = String(input['major'] || '')
result.recommendations = ['示例数据1', '示例数据2', '示例数据3']
result.strategy = '生成结果:' + majorVal
result.preparation = '生成结果:' + majorVal
result.timeline = '生成结果:' + majorVal
result.info_sources = '生成结果:' + majorVal
return result
}
}
审查意见:
-
架构清晰 ✅ Service层通过
import引入Model类型,通过构造方法实例化Model,职责边界清晰。Page层只需依赖Service层,不需要直接操作Model,实现了关注点分离。 -
接口设计 ✅
generateData方法接收Record<string, Object>类型,这在实际使用中需要注意:input对象的键名需要与Page层传递的键名保持一致。当前代码中Page层传递的键为'专业'(中文),而Service层读取的键为'major'(英文),存在不一致的风险。建议统一键名规范。 -
Mock数据 ✅ 当前版本使用Mock数据,通过拼接输入值生成示例结果。这种模式在开发阶段足够验证UI交互流程,未来接入真实AI API时,只需替换
generateData方法内部实现即可。 -
空值处理 ✅ 使用
String(input['major'] || '')确保即使输入字段不存在或为null,也能得到空字符串而非抛出异常,体现了良好的健壮性。
4.3 Page层代码审查
源文件: 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() {
// 顶部导航栏
Row() {
Text('← 返回')
.fontSize(13)
.fontColor('#8B4513')
.onClick(() => { router.back() })
Blank()
Column() {
Text('📱 AI考研择校分析')
.fontSize(17)
.fontWeight(FontWeight.Bold)
.fontColor('#2C1810')
Text('ADMISSION · 录取通知')
.fontSize(9)
.fontColor('#8B4513')
.letterSpacing(2)
.margin({ top: 2 })
}
Blank()
Text('🎓').fontSize(22)
}
.width('100%')
.padding({ left: 20, right: 20, top: 16, bottom: 14 })
.backgroundColor('#F5E6D3')
// 主要内容区域
Scroll() {
Column() {
// 输入表单卡片
Column() {
Text('🎓 专业')
.fontSize(11).fontColor('#8B4513').margin({ top: 6, bottom: 3 })
TextInput({ placeholder: '请输入专业' })
.fontSize(13).height(40).backgroundColor('#FFF8F0')
.borderRadius(0).border({ width: 1, color: '#D4A574' })
.padding({ left: 12, right: 12 })
.onChange((val: string) => { this.inputData['专业'] = val })
Text('🎓 本科背景')
.fontSize(11).fontColor('#8B4513').margin({ top: 6, bottom: 3 })
TextInput({ placeholder: '请输入本科背景' })
.fontSize(13).height(40).backgroundColor('#FFF8F0')
.borderRadius(0).border({ width: 1, color: '#D4A574' })
.padding({ left: 12, right: 12 })
.onChange((val: string) => { this.inputData['本科背景'] = val })
Text('🎓 目标地区')
.fontSize(11).fontColor('#8B4513').margin({ top: 6, bottom: 3 })
TextInput({ placeholder: '请输入目标地区' })
.fontSize(13).height(40).backgroundColor('#FFF8F0')
.borderRadius(0).border({ width: 1, color: '#D4A574' })
.padding({ left: 12, right: 12 })
.onChange((val: string) => { this.inputData['目标地区'] = val })
}
.width('100%').padding(18).backgroundColor('#FFF8F0')
.border({ width: 2, color: '#D4A574' }).margin({ top: 6 })
// 生成按钮
Button('📱 🎓 生成通知书')
.width('100%').height(50).backgroundColor('#8B4513')
.borderRadius(0).fontColor('#FFD700').fontSize(16)
.fontWeight(FontWeight.Bold).margin({ top: 18, bottom: 14 })
.onClick(() => {
this.resultData = this.service.generateData(this.inputData)
this.showResult = true
})
// 结果展示区域
if (this.showResult && this.resultData !== null) {
this.buildResultCard()
}
}
.width('100%').padding({ left: 18, right: 18, bottom: 40 })
}
.layoutWeight(1)
}
.width('100%').height('100%').backgroundColor('#F5E6D3')
}
@Builder
buildResultCard() {
Column() {
Text('🎓 录取通知书')
.fontSize(15).fontWeight(FontWeight.Bold)
.fontColor('#2C1810').margin({ bottom: 12 })
Text('Recommendations')
.fontSize(13).fontWeight(FontWeight.Bold)
.fontColor('#333333').margin({ top: 10, bottom: 6 })
if (this.resultData.recommendations) {
ForEach(this.resultData.recommendations,
(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.buildDetailRow('School: ', this.resultData.school)
this.buildDetailRow('Level: ', this.resultData.level)
this.buildDetailRow('Difficulty: ', this.resultData.difficulty)
this.buildDetailRow('Score line: ', this.resultData.score_line)
this.buildDetailRow('Pros: ', this.resultData.pros)
this.buildDetailRow('Cons: ', this.resultData.cons)
this.buildDetailRow('Ratio: ', this.resultData.ratio)
this.buildDetailRow('Reach: ', this.resultData.reach)
this.buildDetailRow('Match: ', this.resultData.match)
this.buildDetailRow('Safety: ', this.resultData.safety)
this.buildDetailRow('Preparation: ', this.resultData.preparation)
this.buildDetailRow('Timeline: ', this.resultData.timeline)
this.buildDetailRow('Info sources: ', this.resultData.info_sources)
}
.width('100%').padding(18).backgroundColor('#FFF8F0')
.border({ width: 2, color: '#D4A574' }).margin({ bottom: 20 })
}
@Builder
buildDetailRow(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 })
}
}
审查意见:
-
状态管理 ✅ 使用
@State装饰器管理inputData、resultData、showResult三个状态变量,实现了UI的响应式更新。inputData用于收集用户输入,resultData存储分析结果,showResult控制结果展示区域的显隐。 -
UI组件使用 ✅ 合理使用
TextInput收集用户输入,Button触发操作,Scroll实现内容滚动,Blank实现弹性布局,ForEach渲染列表。组件选择符合ArkUI最佳实践。 -
条件渲染 ✅ 使用
if (this.showResult && this.resultData !== null)进行条件渲染,确保结果数据存在时才展示结果卡片,避免了空指针异常。 -
@Builder复用 ✅ 将结果卡片中的详情行提取为
buildDetailRow方法,使用@Builder装饰器实现UI片段的复用,减少了代码重复。 -
UI主题风格 ✅ 使用暖色调配色方案(
#F5E6D3背景、#8B4513棕色、#FFD700金色、#FFF8F0卡片背景),营造出"录取通知书"的仪式感,与考研择校的主题高度契合。
4.4 路由和应用集成审查
路由配置(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": "学习成长"
}
审查意见:
- 路由路径一致性 ✅ 路由配置中的路径与Page层文件的实际路径完全一致,确保导航跳转正确。
- 分类归属合理 ✅ 归类为"学习成长"(cat: “学习成长”),与考研择校的应用场景高度匹配。
- 视觉风格统一 ✅ 使用暖色调配色(
#F59E0B金色、#FFFBEB浅黄背景),在首页网格中与其他应用风格协调。
五、自动化执行阶段(Automate):代码实现详解
5.1 Model层实现详解
Model层是整个应用的数据基石。在AI考研择校分析Model.ets中,我们定义了一个完整的数据类,包含15个字段,覆盖了考研择校分析所需的全部信息维度。
关键设计决策:
-
字段颗粒度:将分析结果拆分为多个独立字段而非一个大的JSON字符串,便于在UI层按需展示,也便于未来接入AI API时逐个字段映射。
-
类型选择:所有字段使用
string类型(除recommendations使用string[]),这是ArkTS对JSON序列化友好的选择。Record<string, Object>作为输入类型,提供了最大的灵活性。 -
初始化策略:采用声明时初始化 + 构造初始化的双重策略,确保对象创建后所有字段都有合法的空值,避免后续使用时的空指针问题。
5.2 Service层实现详解
Service层是业务逻辑的核心。当前版本使用Mock数据,但接口设计已经为未来接入真实AI API做好了准备。
Mock数据生成策略:
generateData(input: Record<string, Object>): AI考研择校分析Data {
let result: AI考研择校分析Data = new AI考研择校分析Data()
let majorVal: string = String(input['major'] || '')
result.recommendations = ['示例数据1', '示例数据2', '示例数据3']
result.strategy = '生成结果:' + majorVal
// ... 其他字段赋值
return result
}
未来AI API接入方案:
当需要接入真实大模型API时,推荐以下方案:
// 未来接入真实AI API的示例
async generateData(input: Record<string, Object>): Promise<AI考研择校分析Data> {
let result: AI考研择校分析Data = new AI考研择校分析Data()
// 构建Prompt
let prompt: string = this.buildPrompt(input)
// 调用AI API(示例)
let apiResponse: string = await this.callAIApi(prompt)
// 解析API响应并填充结果
result = this.parseResponse(apiResponse)
return result
}
private buildPrompt(input: Record<string, Object>): string {
let major: string = String(input['major'] || '未知')
let undergrad: string = String(input['undergrad'] || '未知')
let region: string = String(input['region'] || '全国')
return `请根据以下信息进行考研择校分析:
报考专业:${major}
本科背景:${undergrad}
目标地区:${region}
请以JSON格式输出推荐院校、冲刺/匹配/保底院校、备考建议等信息。`
}
5.3 Page层实现详解
Page层的实现涉及多个ArkUI关键特性,包括状态管理、条件渲染、列表渲染、Builder复用等。
状态管理机制:
@State inputData: Record<string, Object> = {} // 用户输入数据
@State resultData: AI考研择校分析Data | null = null // 分析结果,可为空
@State showResult: boolean = false // 是否展示结果
@State装饰器是ArkUI响应式系统的核心。当状态变量被修改时,框架会自动触发组件的重新渲染。具体来说:
- 用户输入时,
onChange回调更新inputData,但inputData的变化不会直接触发UI变更(它没有被用于UI渲染)。 - 用户点击"生成通知书"按钮时,调用
service.generateData()方法,将返回值赋值给resultData,同时将showResult设为true。 - 框架检测到
resultData和showResult的变化,重
更多推荐

所有评论(0)