Files
digital-pilates/docs/goal-notification-implementation.md
richarjiang 20a244e375 feat: 实现目标通知功能及相关组件
- 新增目标通知功能,支持根据用户创建目标时选择的频率和开始时间自动创建本地定时推送通知
- 实现每日、每周和每月的重复类型,用户可自定义选择提醒时间和重复规则
- 集成目标通知测试组件,方便开发者测试不同类型的通知
- 更新相关文档,详细描述目标通知功能的实现和使用方法
- 优化目标页面,确保用户体验和界面一致性
2025-08-23 17:13:04 +08:00

5.8 KiB
Raw Blame History

目标通知功能实现文档

概述

本功能实现了根据用户创建目标时选择的频率和开始时间,自动创建本地定时推送通知。当用户创建目标并开启提醒功能时,系统会根据目标的重复类型(每日、每周、每月)和提醒时间,自动安排相应的本地推送通知。

功能特性

已实现功能

  • 根据目标重复类型创建定时推送
  • 支持每日重复通知
  • 支持每周重复通知(可自定义星期几)
  • 支持每月重复通知(可自定义日期)
  • 支持自定义提醒时间
  • 目标达成通知
  • 取消特定目标的通知
  • 通知点击处理
  • 开发环境测试功能

技术实现

1. 通知服务扩展 (services/notifications.ts)

新增方法

/**
 * 安排日历重复通知(支持每日、每周、每月)
 */
async scheduleCalendarRepeatingNotification(
  notification: NotificationData,
  options: {
    type: 'daily' | 'weekly' | 'monthly';
    hour: number;
    minute: number;
    weekdays?: number[]; // 0-60为周日仅用于weekly类型
    dayOfMonth?: number; // 1-31仅用于monthly类型
  }
): Promise<string>

通知处理扩展

// 处理目标提醒通知点击
else if (data?.type === 'goal_reminder') {
  console.log('用户点击了目标提醒通知', data);
  // 这里可以添加导航到目标页面的逻辑
}

2. 目标通知辅助函数 (utils/notificationHelpers.ts)

核心方法

/**
 * 根据目标设置创建定时推送
 */
static async scheduleGoalNotifications(
  goalData: {
    title: string;
    repeatType: 'daily' | 'weekly' | 'monthly';
    frequency: number;
    hasReminder: boolean;
    reminderTime?: string;
    customRepeatRule?: {
      weekdays?: number[];
      dayOfMonth?: number[];
    };
    startTime?: number;
  },
  userName: string
): Promise<string[]>

/**
 * 取消特定目标的所有通知
 */
static async cancelGoalNotifications(goalTitle: string): Promise<void>

支持的重复类型

  1. 每日重复

    • 使用 scheduleCalendarRepeatingNotificationdaily 类型
    • 每天在指定时间发送通知
  2. 每周重复

    • 支持自定义星期几(如周一、三、五)
    • 为每个选中的星期几创建单独的通知
    • 使用 scheduleCalendarRepeatingNotificationweekly 类型
  3. 每月重复

    • 支持自定义日期如每月1号和15号
    • 为每个选中的日期创建单独的通知
    • 使用 scheduleCalendarRepeatingNotificationmonthly 类型

3. 目标创建页面集成 (app/(tabs)/goals.tsx)

创建目标后的通知设置

// 创建目标成功后,设置定时推送
try {
  const notificationIds = await GoalNotificationHelpers.scheduleGoalNotifications(
    {
      title: goalData.title,
      repeatType: goalData.repeatType,
      frequency: goalData.frequency,
      hasReminder: goalData.hasReminder,
      reminderTime: goalData.reminderTime,
      customRepeatRule: goalData.customRepeatRule,
      startTime: goalData.startTime,
    },
    userName
  );
  
  console.log(`目标"${goalData.title}"的定时推送已创建通知ID`, notificationIds);
} catch (notificationError) {
  console.error('创建目标定时推送失败:', notificationError);
  // 通知创建失败不影响目标创建的成功
}

使用示例

1. 创建每日目标通知

const notificationIds = await GoalNotificationHelpers.scheduleGoalNotifications(
  {
    title: '每日运动目标',
    repeatType: 'daily',
    frequency: 1,
    hasReminder: true,
    reminderTime: '09:00',
  },
  '张三'
);

2. 创建每周目标通知

const notificationIds = await GoalNotificationHelpers.scheduleGoalNotifications(
  {
    title: '每周运动目标',
    repeatType: 'weekly',
    frequency: 1,
    hasReminder: true,
    reminderTime: '10:00',
    customRepeatRule: {
      weekdays: [1, 3, 5], // 周一、三、五
    },
  },
  '张三'
);

3. 创建每月目标通知

const notificationIds = await GoalNotificationHelpers.scheduleGoalNotifications(
  {
    title: '每月运动目标',
    repeatType: 'monthly',
    frequency: 1,
    hasReminder: true,
    reminderTime: '11:00',
    customRepeatRule: {
      dayOfMonth: [1, 15], // 每月1号和15号
    },
  },
  '张三'
);

4. 发送目标达成通知

await GoalNotificationHelpers.sendGoalAchievementNotification('张三', '每日运动目标');

5. 取消目标通知

await GoalNotificationHelpers.cancelGoalNotifications('每日运动目标');

测试功能

开发环境测试按钮

在开发环境下,目标页面会显示一个"测试通知"按钮,可以快速测试各种通知类型:

  • 每日目标通知测试
  • 每周目标通知测试
  • 目标达成通知测试

测试组件

创建了 GoalNotificationTest 组件,提供完整的测试界面:

import { GoalNotificationTest } from '@/components/GoalNotificationTest';

注意事项

  1. 权限要求: 需要用户授予通知权限才能正常工作
  2. 平台限制: Expo Notifications 的重复通知功能有一定限制,我们使用日历重复通知来绕过这些限制
  3. 时间处理: 所有时间都基于用户设备的本地时间
  4. 错误处理: 通知创建失败不会影响目标创建的成功
  5. 通知管理: 每个目标的通知都有唯一的标识,可以单独取消

未来改进

  1. 通知模板: 支持更多样化的通知内容模板
  2. 智能提醒: 根据用户行为调整提醒时间
  3. 批量管理: 支持批量管理多个目标的通知
  4. 通知历史: 记录和显示通知发送历史
  5. 自定义声音: 支持自定义通知声音