周末计划生成:鸿蒙AI应用,智能规划你的完美周末
一、引言
“周末到了,去哪儿玩呢?”——这是每个周五下午困扰都市人的灵魂拷问。打开点评APP刷了两小时,收藏了十几家店,最后周末却瘫在沙发上一无所获。选择困难症、预算超支、行程冲突,这些痛点让本该放松的周末变成了另一种焦虑。
周末计划生成正是为解决这一难题而生的鸿蒙原生AI应用。它基于ArkTS声明式UI框架,通过三个简单输入——城市、人数、预算——AI在1.5秒内智能生成从周六到周日的完整活动安排,以半天为颗粒度,每项活动附带精确费用说明,真正做到"输入即规划"。
本文将从架构设计、鸿蒙技术深度解析、AI应用亮点、技术挑战与解决方案、用户体验设计等维度,深入剖析这款应用的实现细节与产品哲学。
二、应用架构设计
2.1 整体架构
┌──────────────────────────────────┐ │ WeekendPlanPage.ets │ │ (@Entry @Component) │ │ @State: cityText, peopleCount, │ │ budgetText, currentData │ ├──────────────────────────────────┤ │ WeekendPlanModel.ets │ │ PlanEntry / WeekendData │ │ WPMessage 消息队列模型 │ ├──────────────────────────────────┤ │ WeekendPlanService.ets │ │ getWeekendPlan() 业务逻辑 │ │ 城市×人数×预算知识库 │ └──────────────────────────────────┘2.2 页面结构组件树
Column (根容器, 紫色主题背景) ├── @Builder buildHeader() │ ├── 图标 + 标题 + 副标题 │ └── 重置按钮 (条件渲染) ├── 城市输入: TextInput │ └── onChange → @State cityText ├── 人数选择器: Stepper组件 │ ├── "-" 减少按钮 │ ├── 数字显示 │ └── "+" 增加按钮 ├── 预算输入: TextInput │ └── onChange → @State budgetText ├── 生成按钮 (条件: cityText+budgetText均非空) ├── Loading提示 └── Scroll → buildResultCard (条件: currentData非空) └── @Builder 时间轴卡片2.3 数据模型
exportclassPlanEntry{slot:string// 时间段标识:"周六上午"、"周六下午"、"周六晚上"...activity:string// 活动描述:"参观外滩,感受上海的城市风光"cost:string// 费用说明:"免费 / 约50元"}exportclassWeekendData{plan:PlanEntry[]// 完整的周末行程数组}三、鸿蒙技术深度解析
3.1 Stepper 自增/自减组件的实现
本应用中的人数选择器采用Stepper(步进器)设计,通过自增自减按钮实现人数调整,这是鸿蒙ArkTS中为数不多需要自定义实现的交互组件:
@StatepeopleCount:number=2Row(){// 减少按钮Text('-').fontSize(20).fontWeight(FontWeight.Bold).fontColor(COLOR_PRIMARY).width(36).height(36).textAlign(TextAlign.Center).backgroundColor(COLOR_SELECTED_BG).borderRadius(18).onClick(()=>{if(this.peopleCount>1){this.peopleCount--}})// 数字显示Text(`${this.peopleCount}`).fontSize(20).fontWeight(FontWeight.Bold).fontColor(COLOR_TEXT).width(60).textAlign(TextAlign.Center)// 增加按钮Text('+').fontSize(20).fontWeight(FontWeight.Bold).fontColor(COLOR_PRIMARY).width(36).height(36).textAlign(TextAlign.Center).backgroundColor(COLOR_SELECTED_BG).borderRadius(18).onClick(()=>{if(this.peopleCount<10){this.peopleCount++}})}.width('100%').padding({left:16,top:4,bottom:8}).justifyContent(FlexAlign.Center)这个Stepper实现的关键设计要点:
- 边界控制:通过
peopleCount > 1和peopleCount < 10限制人数范围在1-10之间,防止无效操作 - 视觉反馈:按钮使用
COLOR_SELECTED_BG(浅紫)背景,与主色调形成对比 - 居中布局:通过
FlexAlign.Center将Stepper整体居中,符合移动端输入习惯 - 响应式更新:每次点击触发
@State peopleCount变化,UI自动更新数字显示
3.2 @Builder 时间轴卡片 —— 信息可视化设计
周末计划生成的结果展示采用了时间轴卡片的设计范式,这是本应用UI设计中最具特色的部分:
@BuilderbuildResultCard(data:WeekendData){Column(){Text('📅 周末行程安排').fontSize(16).fontWeight(FontWeight.Bold)ForEach(data.plan,(entry:PlanEntry,idx:number)=>{Row(){// 左侧:时间标签(固定宽度)Column(){Text(entry.slot).fontSize(14).fontWeight(FontWeight.Bold).fontColor('#FFFFFF').padding({left:10,right:10,top:4,bottom:4}).backgroundColor(COLOR_PRIMARY).borderRadius(12)}.margin({right:10}).width(70)// 右侧:活动内容 + 费用标签Column(){Text(entry.activity).fontSize(14).fontWeight(FontWeight.Bold).fontColor(COLOR_TEXT).margin({bottom:2})Text(entry.cost).fontSize(12).fontColor(COLOR_TEXT_SEC).padding({left:6,right:6,top:2,bottom:2}).backgroundColor(COLOR_SELECTED_BG).borderRadius(6)}.layoutWeight(1)}.width('100%').padding(12).backgroundColor(COLOR_CARD).borderRadius(12).border({width:1,color:COLOR_BORDER}).margin({bottom:8})},(_:PlanEntry,idx:number)=>`plan_${idx}`)}}时间轴卡片的设计亮点:
- 左时间右内容:左侧固定70px宽度的时间标签(“周六上午”“周六下午”),右侧使用
layoutWeight(1)填充剩余空间,形成呼吸感 - 紫色时间标签:时间标签采用主色调背景 + 白色文字,视觉突出
- 费用胶囊:费用说明采用浅紫底色胶囊标签,与时间标签形成颜色呼应但层级更低
3.3 多条件联动验证
本应用的生成按钮需要同时满足三个条件:城市已填写、预算已填写(人数有默认值2,非必填)。在代码中通过if条件渲染实现:
if(this.cityText!==''&&this.budgetText!==''){Text('生成周末计划').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#FFFFFF').padding({left:32,right:32,top:12,bottom:12}).backgroundColor(COLOR_PRIMARY).borderRadius(24).margin({top:16}).onClick(()=>{this.onGenerate()})}这里的设计决策是:人数为可选字段(有默认值2),所以不纳入必填验证。用户可以选择不操作人数Stepper,使用默认值直接生成计划。
3.4 加载状态与用户体验
if(this.isLoading){Row(){Text('🎉 正在规划周末行程……').fontSize(13).fontColor(COLOR_TEXT_SEC).padding(12)}.width('100%').padding({left:16})}加载提示使用 🎉 表情符号配合自然语言文案,传递积极、期待的情绪。这种"拟人化加载"比传统的进度条或转圈更符合生活服务类应用的调性。
四、AI应用亮点分析
4.1 三档预算智能适配
AI的预算处理能力是周末计划生成的核心亮点。虽然前端输入的是具体数字(如800元),但AI在内部将其映射为低/中/高三档预算,并据此调整活动推荐策略:
| 预算档位 | 金额范围(2人) | 活动特征 |
|---|---|---|
| 低预算 | 0-500元 | 免费公园、博物馆、野餐、骑行 |
| 中预算 | 500-1500元 | 主题乐园、特色餐厅、短途景点 |
| 高预算 | 1500元以上 | 高端餐厅、自驾游、付费活动体验 |
4.2 双日行程的节奏设计
AI生成的周末计划覆盖周六和周日两天,以半天为颗粒度(上午/下午/晚上),共6个时间段。节奏上遵循"张弛有度"原则:
- 周六上午:适度活动,轻松开启周末
- 周六下午:核心活动,精力最充沛时段
- 周六晚上:娱乐休闲,享受夜生活
- 周日上午:轻松惬意,避免疲劳
- 周日下午:收尾活动,为周一做准备
- 周日晚上:休整恢复,保证充足休息
4.3 费用逐项列明
每项活动都附带了明确的费用说明,让用户对整体花费有清晰预期:
- 免费活动标注:“免费”
- 估算费用标注:“约50元/人"或"约200元(含门票)”
- 精确费用标注:根据人数自动计算总价
这种透明化的费用展示策略,让预算控制变得直观可控。
五、关键技术挑战与解决方案
5.1 挑战一:数字输入的类型安全
问题:TextInput的 onChange 回调返回的是字符串类型,而AI需要的是数值类型进行预算档位判断。
解决方案:在onGenerate()中将字符串转换为数值:
privateonGenerate():void{// 将字符串转为数字传给serviceconstbudget=parseInt(this.budgetText)||0constdata=this.service.getWeekendPlan(this.cityText,this.peopleCount,this.budgetText)// ...}同时,人数选择器直接使用@State peopleCount: number = 2的数值类型,避免了类型转换的问题。
5.2 挑战二:Stepper边界的用户体验
问题:人数达到下限(1)或上限(10)时,继续点击按钮会有边界反馈。
解决方案:
// 下限保护if(this.peopleCount>1){this.peopleCount--}// 上限保护if(this.peopleCount<10){this.peopleCount++}虽然没有使用disable样式禁用按钮,但这种"静默保护"的设计更符合移动端的直觉——用户按了没反应自然会意识到到边界了。
5.3 挑战三:长时间行程的展示可读性
问题:两天的行程(6个时间段)在手机屏幕上可能会显得冗长拥挤。
解决方案:使用Scroll包裹结果区域,通过layoutWeight(1)确保可滚动区域占据合理空间。每个时间卡片保持统一高度和间距,视觉上形成节奏感。
六、用户体验设计
6.1 色彩心理学
周末计划生成采用紫色作为主色调(#D946EF),传递出创意、愉悦、放松的品牌感知:
- 紫色代表着想象力和创造力,与"规划美好周末"的应用定位吻合
- 浅紫背景
#FDF2FC营造出柔和、温馨的视觉氛围 - 紫色时间标签与绿色费用标签形成冷暖对比,增强信息层次
6.2 输入流程设计
三个输入字段的排列顺序遵循从抽象到具体的逻辑:
城市(大范围)→ 人数(规模)→ 预算(约束)这种顺序符合人类规划活动的自然思维流程——先决定去哪儿,再考虑和谁去,最后思考花多少钱。
6.3 结果的信息架构
时间轴卡片的信息层级:
📅 周末行程安排 ├── [周六上午] 参观外滩,感受城市风光 │ 免费 ├── [周六下午] 游览豫园和城隍庙 │ 约30元/人 ├── ...左侧时间标签的固定宽度(70px)设计确保所有卡片的时间信息保持对齐,形成清晰的视觉节奏。
七、总结
周末计划生成通过鸿蒙ArkTS声明式UI框架,优雅地实现了一个"输入即规划"的AI生活服务应用。@State状态管理驱动下,三个输入维度的联动验证、Stepper步进器的高效交互、时间轴卡片的可视化展示,共同构成了完整的产品体验闭环。
从AI产品设计角度来看,预算智能分档、双日行程节奏设计、费用透明化展示三大亮点,让周末计划生成跳出了简单的"活动推荐"范畴,进化为一个真正理解"如何规划一个美好周末"的智能助手。未来如果接入真实的大模型API,还可以实现基于天气、实时交通、个人兴趣偏好等更多维度的个性化推荐,让每个周末都值得期待。