feat: 实现目标通知功能及相关组件

- 新增目标通知功能,支持根据用户创建目标时选择的频率和开始时间自动创建本地定时推送通知
- 实现每日、每周和每月的重复类型,用户可自定义选择提醒时间和重复规则
- 集成目标通知测试组件,方便开发者测试不同类型的通知
- 更新相关文档,详细描述目标通知功能的实现和使用方法
- 优化目标页面,确保用户体验和界面一致性
This commit is contained in:
2025-08-23 17:13:04 +08:00
parent 4382fb804f
commit 20a244e375
15 changed files with 957 additions and 156 deletions

View File

@@ -1,4 +1,4 @@
import { notificationService, NotificationData } from '../services/notifications';
import { NotificationData, notificationService } from '../services/notifications';
/**
* 运动相关的通知辅助函数
@@ -104,6 +104,164 @@ export class GoalNotificationHelpers {
reminderDate
);
}
/**
* 根据目标设置创建定时推送
* @param goalData 目标数据
* @param userName 用户名
* @returns 通知ID数组
*/
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[]> {
const notificationIds: string[] = [];
// 如果没有开启提醒,直接返回
if (!goalData.hasReminder || !goalData.reminderTime) {
console.log('目标未开启提醒或未设置提醒时间');
return notificationIds;
}
try {
// 解析提醒时间
const [hours, minutes] = goalData.reminderTime.split(':').map(Number);
// 创建通知内容
const notification: NotificationData = {
title: '目标提醒',
body: `${userName},该完成您的目标"${goalData.title}"了!`,
data: {
type: 'goal_reminder',
goalTitle: goalData.title,
repeatType: goalData.repeatType,
frequency: goalData.frequency
},
sound: true,
priority: 'high',
};
// 根据重复类型创建不同的通知
switch (goalData.repeatType) {
case 'daily':
// 每日重复 - 使用日历重复通知
const dailyId = await notificationService.scheduleCalendarRepeatingNotification(
notification,
{
type: 'daily',
hour: hours,
minute: minutes,
}
);
notificationIds.push(dailyId);
console.log(`已安排每日目标提醒通知ID${dailyId}`);
break;
case 'weekly':
// 每周重复 - 为每个选中的星期几创建单独的通知
if (goalData.customRepeatRule?.weekdays && goalData.customRepeatRule.weekdays.length > 0) {
for (const weekday of goalData.customRepeatRule.weekdays) {
const weeklyId = await notificationService.scheduleCalendarRepeatingNotification(
notification,
{
type: 'weekly',
hour: hours,
minute: minutes,
weekdays: [weekday],
}
);
notificationIds.push(weeklyId);
console.log(`已安排每周目标提醒,星期${weekday}通知ID${weeklyId}`);
}
} else {
// 默认每周重复
const weeklyId = await notificationService.scheduleCalendarRepeatingNotification(
notification,
{
type: 'weekly',
hour: hours,
minute: minutes,
}
);
notificationIds.push(weeklyId);
console.log(`已安排每周目标提醒通知ID${weeklyId}`);
}
break;
case 'monthly':
// 每月重复 - 为每个选中的日期创建单独的通知
if (goalData.customRepeatRule?.dayOfMonth && goalData.customRepeatRule.dayOfMonth.length > 0) {
for (const dayOfMonth of goalData.customRepeatRule.dayOfMonth) {
const monthlyId = await notificationService.scheduleCalendarRepeatingNotification(
notification,
{
type: 'monthly',
hour: hours,
minute: minutes,
dayOfMonth: dayOfMonth,
}
);
notificationIds.push(monthlyId);
console.log(`已安排每月目标提醒,${dayOfMonth}通知ID${monthlyId}`);
}
} else {
// 默认每月重复
const monthlyId = await notificationService.scheduleCalendarRepeatingNotification(
notification,
{
type: 'monthly',
hour: hours,
minute: minutes,
dayOfMonth: 1,
}
);
notificationIds.push(monthlyId);
console.log(`已安排每月目标提醒通知ID${monthlyId}`);
}
break;
}
console.log(`目标"${goalData.title}"的定时推送已创建完成,共${notificationIds.length}个通知`);
return notificationIds;
} catch (error) {
console.error('创建目标定时推送失败:', error);
throw error;
}
}
/**
* 取消特定目标的所有通知
*/
static async cancelGoalNotifications(goalTitle: string): Promise<void> {
try {
const notifications = await notificationService.getAllScheduledNotifications();
for (const notification of notifications) {
if (notification.content.data?.type === 'goal_reminder' &&
notification.content.data?.goalTitle === goalTitle) {
await notificationService.cancelNotification(notification.identifier);
console.log(`已取消目标"${goalTitle}"的通知:${notification.identifier}`);
}
}
} catch (error) {
console.error('取消目标通知失败:', error);
throw error;
}
}
}
/**