HarmonyOS 鸿蒙Next中如何实现连续打卡天数统计?

HarmonyOS 鸿蒙Next中如何实现连续打卡天数统计? 学习应用需要统计用户连续学习天数,激励用户保持学习习惯。

3 回复

原理解析

连续打卡统计需要:

  1. 记录每天的打卡日期
  2. 从最近一次打卡开始,向前检查是否连续
  3. 处理时区问题,使用本地日期

解决步骤

步骤1:获取本地日期字符串

function getLocalDateString(date?: Date): string {
  const d = date || new Date();
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
}

步骤2:计算连续打卡天数

export async function getStreakDays(): Promise<number> {
  const records = await getCheckInRecords();
  if (records.length === 0) return 0;

  // 按日期排序(降序,最新的在前)
  const sorted = records.sort((a, b) => b.date.localeCompare(a.date));
  
  // 获取今天和昨天的日期字符串
  const now = new Date();
  const todayStr = getLocalDateString(now);
  const yesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
  const yesterdayStr = getLocalDateString(yesterday);
  
  // 检查最近一次打卡是今天还是昨天
  const latestRecord = sorted[0];
  if (latestRecord.date !== todayStr && latestRecord.date !== yesterdayStr) {
    return 0;  // 连续中断
  }
  
  // 从最近的打卡日期开始计算连续天数
  let streak = 0;
  let expectedDate = new Date(latestRecord.date + 'T00:00:00');
  
  for (let i = 0; i < sorted.length; i++) {
    const recordDate = sorted[i].date;
    const expectedDateStr = getLocalDateString(expectedDate);
    
    if (recordDate === expectedDateStr) {
      streak++;
      // 期望日期往前推一天
      expectedDate.setDate(expectedDate.getDate() - 1);
    } else if (recordDate < expectedDateStr) {
      // 有断档,停止计算
      break;
    }
    // 如果 recordDate > expectedDateStr,说明有重复记录,跳过
  }
  
  return streak;
}

步骤3:自动打卡(浏览内容时触发)

async function autoCheckIn(): Promise<void> {
  const today = getLocalDateString();
  const records = await getCheckInRecords();
  const todayRecord = records.find(r => r.date === today);
  
  if (!todayRecord) {
    // 今天还没打卡,自动记录
    await saveCheckInRecord(today);
  }
}

// 在浏览内容时调用
export async function recordBrowse(contentId: string, contentType: string): Promise<boolean> {
  // ... 保存浏览记录
  await autoCheckIn();  // 自动打卡
  return true;
}

效果图

用户学习 → 自动打卡 → 首页显示"连续学习 X 天" → 激励用户保持习惯

更多关于HarmonyOS 鸿蒙Next中如何实现连续打卡天数统计?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,可通过@State装饰器定义打卡状态变量,使用PersistentStorage持久化存储每日打卡记录。通过日期计算函数判断连续打卡,例如比较最后打卡日期与当前日期。

在HarmonyOS Next中实现连续打卡天数统计,核心在于持久化存储日期逻辑判断状态更新。以下是基于ArkTS的关键实现思路和代码示例:

1. 数据存储

使用轻量级数据存储Preferences保存关键数据:

  • 上次打卡日期 (lastDate)
  • 连续打卡天数 (currentStreak)
import { preferences } from '@kit.ArkData';

// 初始化存储
const prefs = await preferences.getPreferences(this.context, 'streakData');

// 保存数据函数
async function saveStreakData(lastDate: string, streak: number) {
  await prefs.putString('lastDate', lastDate);
  await prefs.putNumber('currentStreak', streak);
  await prefs.flush();
}

2. 核心逻辑判断

打卡时进行日期连续性判断:

import { util } from '@kit.ArkTS';

async function checkIn() {
  // 获取当前日期(格式化为YYYY-MM-DD)
  const today = new util.DateTime().toString().split('T')[0];
  
  // 读取历史数据
  const lastDate = await prefs.getString('lastDate', '');
  let currentStreak = await prefs.getNumber('currentStreak', 0);

  if (lastDate === '') {
    // 首次打卡
    currentStreak = 1;
  } else {
    const last = new Date(lastDate);
    const current = new Date(today);
    const diffDays = Math.floor((current.getTime() - last.getTime()) / (1000 * 3600 * 24));

    if (diffDays === 1) {
      // 连续打卡
      currentStreak += 1;
    } else if (diffDays === 0) {
      // 今天已打卡
      return currentStreak;
    } else {
      // 中断后重新开始
      currentStreak = 1;
    }
  }

  // 保存新状态
  await saveStreakData(today, currentStreak);
  return currentStreak;
}

3. 获取展示数据

提供获取当前连续天数的接口:

async function getCurrentStreak(): Promise<number> {
  return await prefs.getNumber('currentStreak', 0);
}

async function getLastCheckInDate(): Promise<string> {
  return await prefs.getString('lastDate', '');
}

4. 高级特性(可选)

  • 历史记录:使用关系型数据库存储详细打卡记录,支持数据分析和图表展示
  • 定时任务:通过后台任务检查打卡连续性,发送提醒通知
  • 多设备同步:结合分布式数据管理实现跨设备打卡状态同步

注意事项

  1. 时区处理:确保使用用户本地时区进行日期计算
  2. 数据安全:敏感数据建议使用加密存储
  3. 性能优化:频繁操作建议批量写入

此方案通过最小化的数据存储和清晰的逻辑判断,即可实现可靠的连续打卡统计功能。

回到顶部