【OpenHarmony/HarmonyOs 】每日学习目标系统:todayCount、连续学习与本地激励反馈

【OpenHarmony/HarmonyOs 】每日学习目标系统:todayCount、连续学习与本地激励反馈

项目类型:OpenHarmony / HarmonyOS ArkTS 数学学习应用
项目名称:数学视界
对应主题:全新视觉与交互体验、端侧 AI、全场景智慧学习
关键词:ArkTS、每日目标、学习进度、连续学习、成就激励、本地统计 🎯

一、为什么每日目标值得写?

学习类应用最难的不是做功能,而是让用户持续回来。数学视界里有计算器、公式库、单位换算、挑战答题、趣味百科、曲线画板,但如果没有一个持续激励机制,这些功能容易变成“用完即走”的工具。

每日学习目标就是把工具型应用变成学习型应用的关键。

项目中围绕每日目标做了几件事:

  • 首页展示今日进度;
  • 我的页面展示目标进度;
  • 用户可以修改每日目标;
  • 计算、换算、绘图等行为会增加todayCount
  • 达成目标后更新连续达标天数;
  • 连续完成目标可以解锁成就。

这篇文章就聚焦这个本地激励系统。

二、StudyData:每日目标的数据基础

每日目标相关数据定义在AppState.ets

export interfaceStudyData{totalStudyDays:numbercurrentStreak:numbertotalDrawings:numbertotalCalculations:numbertotalFunctions:numbertotalFormulasViewed:numbertotalUnitsConverted:numberlastStudyDate:stringdailyGoal:numbertodayCount:numberconsecutiveGoalMetDays:numberfunFactsViewed:number}

这里最关键的是:

  • dailyGoal:每天目标数量;
  • todayCount:今日已完成数量;
  • currentStreak:连续学习天数;
  • consecutiveGoalMetDays:连续达成目标天数;
  • lastStudyDate:最后学习日期。

这些数据全部在端侧维护,不需要账号系统,也不需要云端学习画像。

三、哪些行为算一次学习?

项目中多个功能会增加学习计数。例如单位换算:

recordUnitConversion(): void {this.studyData.totalUnitsConverted++this.studyData.todayCount++this.updateStudyStreak()this.checkAchievement('11')this.checkDailyGoalMet() }

计算器也会记录:

recordCalculation(): void {this.studyData.totalCalculations++this.studyData.todayCount++this.updateStudyStreak()this.checkAchievement('2')this.checkDailyGoalMet() }

画板绘制也会记录:

recordDrawing(): void {this.studyData.totalDrawings++this.studyData.todayCount++this.updateStudyStreak()this.checkDailyGoalMet() }

这说明每日目标不是只服务于答题,而是覆盖整个数学学习行为。

四、首页进度卡:打开 App 就知道还差多少

首页的进度卡直接读取todayCountdailyGoal

Column() .width(Math.min( AppState.studyData.todayCount / AppState.studyData.dailyGoal *100,100) +'%') .height('100%') .backgroundColor('#FFFFFF') .borderRadius(10)

这段代码把学习进度转成进度条宽度。

底部文案也会根据目标完成情况变化:

Text( AppState.studyData.todayCount >= AppState.studyData.dailyGoal ?'🎉 太棒了!今日目标达成!':'💪 再完成 '+ Math.max(AppState.studyData.dailyGoal - AppState.studyData.todayCount,0) +' 次即可达成今日目标!')

这就是一个典型的轻量激励设计:不用弹窗打扰用户,但用户能随时看到当前进度。

五、我的页面进度:更完整的目标反馈

MyPage.ets中,今日学习数量通过日期判断:

getTodayStudyCount(): number { const today:string=newDate().toISOString().split('T')[0]if(AppState.studyData.lastStudyDate===today) { returnAppState.studyData.todayCount } return0}

进度百分比:

getGoalProgress():number{constgoal:number=AppState.settings.dailyGoalconsttoday:number=this.getTodayStudyCount()if(goal <=0)return0returnMath.min(Math.round((today / goal) *100),100) }

然后用Progress组件展示:

Progress({ value:this.getGoalProgress(), total:100, type: ProgressType.Linear }) .color(this.getGoalProgress() >=100?'#2ECC71':'#FF9A8B') .backgroundColor(this.getColor('#F0F0F0','#333333')) .height(8) .borderRadius(4)

首页负责快速提醒,我的页面负责完整查看。两个入口互补。

六、连续学习:跨天逻辑如何处理?

连续学习依赖updateStudyStreak()

privateupdateStudyStreak(): void {consttoday: string = new Date().toISOString().split('T')[0]if(this.studyData.lastStudyDate ==='') {this.studyData.lastStudyDate = todaythis.studyData.totalStudyDays =1this.studyData.currentStreak =1this.goalMetCheckedToday =false}elseif(this.studyData.lastStudyDate !== today) {constlastDate: Date = new Date(this.studyData.lastStudyDate)consttodayDate: Date = new Date(today)constdiffDays: number = Math.floor((todayDate.getTime() - lastDate.getTime()) / (1000*60*60*24))if(diffDays ===1) {this.studyData.currentStreak++ }elseif(diffDays >1) {this.studyData.currentStreak =1this.studyData.consecutiveGoalMetDays =0}this.studyData.totalStudyDays++this.studyData.lastStudyDate = todaythis.studyData.todayCount =0this.goalMetCheckedToday =false} }

这个逻辑处理了三种情况:

  • 第一次学习:初始化日期和连续天数;
  • 第二天继续学习:连续天数加一;
  • 中断多天后回来:连续天数重置。

七、目标达成:一天只检查一次

为了避免同一天重复触发目标成就,项目使用了goalMetCheckedToday

privategoalMetCheckedToday: boolean =falsecheckDailyGoalMet(): void {if(!this.goalMetCheckedToday &&this.studyData.todayCount >=this.studyData.dailyGoal) {this.goalMetCheckedToday =truethis.studyData.consecutiveGoalMetDays++this.checkGoalAchievement() } }

这个细节很重要。假设每日目标是 5 次,用户完成第 6 次、第 7 次时,不应该反复增加连续达标天数。

八、目标成就:连续 7 天完成目标

目标成就逻辑如下:

checkGoalAchievement(): void {for(let i: number =0; i <this.achievements.length; i++) {if(this.achievements[i].id ==='13'&& !this.achievements[i].isUnlocked) {this.achievements[i].progress =this.studyData.consecutiveGoalMetDaysif(this.studyData.consecutiveGoalMetDays >=7) {this.achievements[i].progress =7this.achievements[i].isUnlocked =truethis.recentUnlock =this.achievements[i]this.showUnlockToast =true}break} } }

这让每日目标从“今天做几次”升级成“连续坚持”的长期激励。

九、隐私友好:不需要账号也能激励

很多学习 App 会把每日打卡、排名、学习报告上传到服务器。但数学视界当前的目标系统完全可以本地完成:

  • 本地记录学习次数;
  • 本地计算连续天数;
  • 本地判断目标达成;
  • 本地解锁成就。

这对学习工具来说非常友好。用户不需要登录,也能获得持续反馈。

十、总结

每日目标系统对应“全新视觉与交互体验”和“端侧 AI”主题,它把分散的工具功能串成了学习路径。

核心实现包括:

  • 🎯 用dailyGoaltodayCount表达每日目标;
  • 📈 首页用进度条和鼓励文案做即时反馈;
  • 👤 我的页面用Progress展示完整进度;
  • 📅 用lastStudyDatecurrentStreak计算连续学习;
  • 🏆 用consecutiveGoalMetDays解锁目标成就;
  • 🔐 所有统计都在端侧完成,不依赖账号和云端。

对数学学习 App 来说,每日目标不是一个小组件,而是让用户持续学习的核心机制。✨