feat: 集成推送通知功能及相关组件
- 在项目中引入expo-notifications库,支持本地推送通知功能 - 实现通知权限管理,用户可选择开启或关闭通知 - 新增通知发送、定时通知和重复通知功能 - 更新个人页面,集成通知开关和权限请求逻辑 - 编写推送通知功能实现文档,详细描述功能和使用方法 - 优化心情日历页面,确保数据实时刷新
This commit is contained in:
337
utils/notificationHelpers.ts
Normal file
337
utils/notificationHelpers.ts
Normal file
@@ -0,0 +1,337 @@
|
||||
import { notificationService, NotificationData } from '../services/notifications';
|
||||
|
||||
/**
|
||||
* 运动相关的通知辅助函数
|
||||
*/
|
||||
export class WorkoutNotificationHelpers {
|
||||
/**
|
||||
* 发送运动开始提醒
|
||||
*/
|
||||
static async sendWorkoutStartReminder(userName: string) {
|
||||
return notificationService.sendImmediateNotification({
|
||||
title: '运动时间到',
|
||||
body: `${userName},该开始今天的普拉提训练了!`,
|
||||
data: { type: 'workout_start' },
|
||||
sound: true,
|
||||
priority: 'high',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送运动完成通知
|
||||
*/
|
||||
static async sendWorkoutCompleteNotification(userName: string, duration: number) {
|
||||
return notificationService.sendImmediateNotification({
|
||||
title: '运动完成',
|
||||
body: `${userName},恭喜您完成了${duration}分钟的训练!`,
|
||||
data: { type: 'workout_complete' },
|
||||
sound: true,
|
||||
priority: 'normal',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 安排每日运动提醒
|
||||
*/
|
||||
static async scheduleDailyWorkoutReminder(userName: string, hour: number = 9, minute: number = 0) {
|
||||
const reminderTime = new Date();
|
||||
reminderTime.setHours(hour, minute, 0, 0);
|
||||
|
||||
// 如果今天的时间已经过了,设置为明天
|
||||
if (reminderTime.getTime() <= Date.now()) {
|
||||
reminderTime.setDate(reminderTime.getDate() + 1);
|
||||
}
|
||||
|
||||
return notificationService.scheduleRepeatingNotification(
|
||||
{
|
||||
title: '每日运动提醒',
|
||||
body: `${userName},该开始今天的普拉提训练了!`,
|
||||
data: { type: 'daily_workout_reminder' },
|
||||
sound: true,
|
||||
priority: 'high',
|
||||
},
|
||||
{ days: 1 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 目标相关的通知辅助函数
|
||||
*/
|
||||
export class GoalNotificationHelpers {
|
||||
/**
|
||||
* 发送目标达成通知
|
||||
*/
|
||||
static async sendGoalAchievementNotification(userName: string, goalName: string) {
|
||||
return notificationService.sendImmediateNotification({
|
||||
title: '目标达成',
|
||||
body: `${userName},恭喜您达成了目标:${goalName}!`,
|
||||
data: { type: 'goal_achievement', goalName },
|
||||
sound: true,
|
||||
priority: 'high',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送目标进度更新通知
|
||||
*/
|
||||
static async sendGoalProgressNotification(userName: string, goalName: string, progress: number) {
|
||||
return notificationService.sendImmediateNotification({
|
||||
title: '目标进度',
|
||||
body: `${userName},您的目标"${goalName}"已完成${progress}%!`,
|
||||
data: { type: 'goal_progress', goalName, progress },
|
||||
sound: true,
|
||||
priority: 'normal',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 安排目标提醒
|
||||
*/
|
||||
static async scheduleGoalReminder(userName: string, goalName: string, deadline: Date) {
|
||||
// 在截止日期前一天发送提醒
|
||||
const reminderDate = new Date(deadline);
|
||||
reminderDate.setDate(reminderDate.getDate() - 1);
|
||||
|
||||
return notificationService.scheduleNotificationAtDate(
|
||||
{
|
||||
title: '目标截止提醒',
|
||||
body: `${userName},您的目标"${goalName}"明天就要截止了,加油!`,
|
||||
data: { type: 'goal_deadline_reminder', goalName },
|
||||
sound: true,
|
||||
priority: 'high',
|
||||
},
|
||||
reminderDate
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 心情相关的通知辅助函数
|
||||
*/
|
||||
export class MoodNotificationHelpers {
|
||||
/**
|
||||
* 发送心情打卡提醒
|
||||
*/
|
||||
static async sendMoodCheckinReminder(userName: string) {
|
||||
return notificationService.sendImmediateNotification({
|
||||
title: '心情打卡',
|
||||
body: `${userName},记得记录今天的心情状态哦`,
|
||||
data: { type: 'mood_checkin_reminder' },
|
||||
sound: true,
|
||||
priority: 'normal',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 安排每日心情打卡提醒
|
||||
*/
|
||||
static async scheduleDailyMoodReminder(userName: string, hour: number = 20, minute: number = 0) {
|
||||
const reminderTime = new Date();
|
||||
reminderTime.setHours(hour, minute, 0, 0);
|
||||
|
||||
// 如果今天的时间已经过了,设置为明天
|
||||
if (reminderTime.getTime() <= Date.now()) {
|
||||
reminderTime.setDate(reminderTime.getDate() + 1);
|
||||
}
|
||||
|
||||
return notificationService.scheduleRepeatingNotification(
|
||||
{
|
||||
title: '每日心情打卡',
|
||||
body: `${userName},记得记录今天的心情状态哦`,
|
||||
data: { type: 'daily_mood_reminder' },
|
||||
sound: true,
|
||||
priority: 'normal',
|
||||
},
|
||||
{ days: 1 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 营养相关的通知辅助函数
|
||||
*/
|
||||
export class NutritionNotificationHelpers {
|
||||
/**
|
||||
* 发送营养记录提醒
|
||||
*/
|
||||
static async sendNutritionRecordReminder(userName: string) {
|
||||
return notificationService.sendImmediateNotification({
|
||||
title: '营养记录',
|
||||
body: `${userName},记得记录今天的饮食情况`,
|
||||
data: { type: 'nutrition_record_reminder' },
|
||||
sound: true,
|
||||
priority: 'normal',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 安排营养记录提醒
|
||||
*/
|
||||
static async scheduleNutritionReminders(userName: string) {
|
||||
// 安排三餐提醒
|
||||
const mealTimes = [
|
||||
{ hour: 8, minute: 0, meal: '早餐' },
|
||||
{ hour: 12, minute: 0, meal: '午餐' },
|
||||
{ hour: 18, minute: 0, meal: '晚餐' },
|
||||
];
|
||||
|
||||
const notifications = [];
|
||||
|
||||
for (const mealTime of mealTimes) {
|
||||
const reminderTime = new Date();
|
||||
reminderTime.setHours(mealTime.hour, mealTime.minute, 0, 0);
|
||||
|
||||
// 如果今天的时间已经过了,设置为明天
|
||||
if (reminderTime.getTime() <= Date.now()) {
|
||||
reminderTime.setDate(reminderTime.getDate() + 1);
|
||||
}
|
||||
|
||||
const notificationId = await notificationService.scheduleRepeatingNotification(
|
||||
{
|
||||
title: `${mealTime.meal}提醒`,
|
||||
body: `${userName},记得记录您的${mealTime.meal}情况`,
|
||||
data: { type: 'meal_reminder', meal: mealTime.meal },
|
||||
sound: true,
|
||||
priority: 'normal',
|
||||
},
|
||||
{ days: 1 }
|
||||
);
|
||||
|
||||
notifications.push(notificationId);
|
||||
}
|
||||
|
||||
return notifications;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用通知辅助函数
|
||||
*/
|
||||
export class GeneralNotificationHelpers {
|
||||
/**
|
||||
* 发送欢迎通知
|
||||
*/
|
||||
static async sendWelcomeNotification(userName: string) {
|
||||
return notificationService.sendImmediateNotification({
|
||||
title: '欢迎使用',
|
||||
body: `${userName},欢迎来到普拉提世界!开始您的健康之旅吧`,
|
||||
data: { type: 'welcome' },
|
||||
sound: true,
|
||||
priority: 'normal',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送成就通知
|
||||
*/
|
||||
static async sendAchievementNotification(userName: string, achievement: string) {
|
||||
return notificationService.sendImmediateNotification({
|
||||
title: '新成就',
|
||||
body: `${userName},恭喜您获得了新成就:${achievement}!`,
|
||||
data: { type: 'achievement', achievement },
|
||||
sound: true,
|
||||
priority: 'high',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送系统维护通知
|
||||
*/
|
||||
static async sendMaintenanceNotification(message: string) {
|
||||
return notificationService.sendImmediateNotification({
|
||||
title: '系统通知',
|
||||
body: message,
|
||||
data: { type: 'maintenance' },
|
||||
sound: true,
|
||||
priority: 'high',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消特定类型的通知
|
||||
*/
|
||||
static async cancelNotificationsByType(type: string) {
|
||||
const notifications = await notificationService.getAllScheduledNotifications();
|
||||
|
||||
for (const notification of notifications) {
|
||||
if (notification.content.data?.type === type) {
|
||||
await notificationService.cancelNotification(notification.identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量发送通知
|
||||
*/
|
||||
static async sendBatchNotifications(notifications: NotificationData[]) {
|
||||
const results = [];
|
||||
|
||||
for (const notification of notifications) {
|
||||
try {
|
||||
const id = await notificationService.sendImmediateNotification(notification);
|
||||
results.push({ success: true, id, notification });
|
||||
} catch (error) {
|
||||
results.push({ success: false, error, notification });
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知模板
|
||||
*/
|
||||
export const NotificationTemplates = {
|
||||
workout: {
|
||||
start: (userName: string) => ({
|
||||
title: '运动时间到',
|
||||
body: `${userName},该开始今天的普拉提训练了!`,
|
||||
data: { type: 'workout_start' },
|
||||
sound: true,
|
||||
priority: 'high' as const,
|
||||
}),
|
||||
complete: (userName: string, duration: number) => ({
|
||||
title: '运动完成',
|
||||
body: `${userName},恭喜您完成了${duration}分钟的训练!`,
|
||||
data: { type: 'workout_complete' },
|
||||
sound: true,
|
||||
priority: 'normal' as const,
|
||||
}),
|
||||
},
|
||||
goal: {
|
||||
achievement: (userName: string, goalName: string) => ({
|
||||
title: '目标达成',
|
||||
body: `${userName},恭喜您达成了目标:${goalName}!`,
|
||||
data: { type: 'goal_achievement', goalName },
|
||||
sound: true,
|
||||
priority: 'high' as const,
|
||||
}),
|
||||
progress: (userName: string, goalName: string, progress: number) => ({
|
||||
title: '目标进度',
|
||||
body: `${userName},您的目标"${goalName}"已完成${progress}%!`,
|
||||
data: { type: 'goal_progress', goalName, progress },
|
||||
sound: true,
|
||||
priority: 'normal' as const,
|
||||
}),
|
||||
},
|
||||
mood: {
|
||||
reminder: (userName: string) => ({
|
||||
title: '心情打卡',
|
||||
body: `${userName},记得记录今天的心情状态哦`,
|
||||
data: { type: 'mood_checkin_reminder' },
|
||||
sound: true,
|
||||
priority: 'normal' as const,
|
||||
}),
|
||||
},
|
||||
nutrition: {
|
||||
reminder: (userName: string, meal: string) => ({
|
||||
title: `${meal}提醒`,
|
||||
body: `${userName},记得记录您的${meal}情况`,
|
||||
data: { type: 'meal_reminder', meal },
|
||||
sound: true,
|
||||
priority: 'normal' as const,
|
||||
}),
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user