feat(nutrition): 添加营养数据保存功能到HealthKit,包括蛋白质、脂肪和碳水化合物
This commit is contained in:
108
utils/health.ts
108
utils/health.ts
@@ -1139,6 +1139,114 @@ export async function saveWaterIntakeToHealthKit(amount: number, recordedAt?: st
|
||||
}
|
||||
}
|
||||
|
||||
// 添加蛋白质记录到 HealthKit
|
||||
export async function saveProteinToHealthKit(grams: number, recordedAt?: string): Promise<boolean> {
|
||||
try {
|
||||
console.log('开始保存蛋白质记录到HealthKit...', { grams, recordedAt });
|
||||
|
||||
const options = {
|
||||
amount: grams,
|
||||
recordedAt: recordedAt || new Date().toISOString()
|
||||
};
|
||||
|
||||
const result = await HealthKitManager.saveProteinToHealthKit(options);
|
||||
|
||||
if (result && result.success) {
|
||||
console.log('蛋白质记录保存成功:', result);
|
||||
return true;
|
||||
} else {
|
||||
console.error('蛋白质记录保存失败:', result);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('添加蛋白质记录到 HealthKit 失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加脂肪记录到 HealthKit
|
||||
export async function saveFatToHealthKit(grams: number, recordedAt?: string): Promise<boolean> {
|
||||
try {
|
||||
console.log('开始保存脂肪记录到HealthKit...', { grams, recordedAt });
|
||||
|
||||
const options = {
|
||||
amount: grams,
|
||||
recordedAt: recordedAt || new Date().toISOString()
|
||||
};
|
||||
|
||||
const result = await HealthKitManager.saveFatToHealthKit(options);
|
||||
|
||||
if (result && result.success) {
|
||||
console.log('脂肪记录保存成功:', result);
|
||||
return true;
|
||||
} else {
|
||||
console.error('脂肪记录保存失败:', result);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('添加脂肪记录到 HealthKit 失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加碳水化合物记录到 HealthKit
|
||||
export async function saveCarbohydratesToHealthKit(grams: number, recordedAt?: string): Promise<boolean> {
|
||||
try {
|
||||
console.log('开始保存碳水化合物记录到HealthKit...', { grams, recordedAt });
|
||||
|
||||
const options = {
|
||||
amount: grams,
|
||||
recordedAt: recordedAt || new Date().toISOString()
|
||||
};
|
||||
|
||||
const result = await HealthKitManager.saveCarbohydratesToHealthKit(options);
|
||||
|
||||
if (result && result.success) {
|
||||
console.log('碳水化合物记录保存成功:', result);
|
||||
return true;
|
||||
} else {
|
||||
console.error('碳水化合物记录保存失败:', result);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('添加碳水化合物记录到 HealthKit 失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 批量保存营养数据到 HealthKit(蛋白质、脂肪和碳水化合物)
|
||||
export async function saveNutritionToHealthKit(
|
||||
nutrition: { proteinGrams?: number; fatGrams?: number; carbohydrateGrams?: number },
|
||||
recordedAt?: string
|
||||
): Promise<{ proteinSaved: boolean; fatSaved: boolean; carbohydrateSaved: boolean }> {
|
||||
try {
|
||||
console.log('开始批量保存营养数据到HealthKit...', { nutrition, recordedAt });
|
||||
|
||||
const results = await Promise.allSettled([
|
||||
nutrition.proteinGrams && nutrition.proteinGrams > 0
|
||||
? saveProteinToHealthKit(nutrition.proteinGrams, recordedAt)
|
||||
: Promise.resolve(false),
|
||||
nutrition.fatGrams && nutrition.fatGrams > 0
|
||||
? saveFatToHealthKit(nutrition.fatGrams, recordedAt)
|
||||
: Promise.resolve(false),
|
||||
nutrition.carbohydrateGrams && nutrition.carbohydrateGrams > 0
|
||||
? saveCarbohydratesToHealthKit(nutrition.carbohydrateGrams, recordedAt)
|
||||
: Promise.resolve(false),
|
||||
]);
|
||||
|
||||
const proteinSaved = results[0].status === 'fulfilled' ? results[0].value : false;
|
||||
const fatSaved = results[1].status === 'fulfilled' ? results[1].value : false;
|
||||
const carbohydrateSaved = results[2].status === 'fulfilled' ? results[2].value : false;
|
||||
|
||||
console.log('营养数据批量保存结果:', { proteinSaved, fatSaved, carbohydrateSaved });
|
||||
|
||||
return { proteinSaved, fatSaved, carbohydrateSaved };
|
||||
} catch (error) {
|
||||
console.error('批量保存营养数据到 HealthKit 失败:', error);
|
||||
return { proteinSaved: false, fatSaved: false, carbohydrateSaved: false };
|
||||
}
|
||||
}
|
||||
|
||||
// 获取 HealthKit 中的饮水记录
|
||||
export async function getWaterIntakeFromHealthKit(options: HealthDataOptions): Promise<any[]> {
|
||||
try {
|
||||
|
||||
@@ -43,6 +43,17 @@ export interface SleepDataResult {
|
||||
endDate: string;
|
||||
}
|
||||
|
||||
export interface NutritionSaveOptions {
|
||||
amount: number; // Amount in grams
|
||||
recordedAt?: string; // ISO8601 format, defaults to now
|
||||
}
|
||||
|
||||
export interface NutritionSaveResult {
|
||||
success: boolean;
|
||||
amount: number;
|
||||
recordedAt: string;
|
||||
}
|
||||
|
||||
export interface HealthKitManagerInterface {
|
||||
/**
|
||||
* Request authorization to access HealthKit data
|
||||
@@ -61,6 +72,24 @@ export interface HealthKitManagerInterface {
|
||||
* @param options Query options including date range and limit
|
||||
*/
|
||||
getSleepData(options?: SleepDataOptions): Promise<SleepDataResult>;
|
||||
|
||||
/**
|
||||
* Save protein intake to HealthKit
|
||||
* @param options Nutrition save options including amount in grams and optional timestamp
|
||||
*/
|
||||
saveProteinToHealthKit(options: NutritionSaveOptions): Promise<NutritionSaveResult>;
|
||||
|
||||
/**
|
||||
* Save fat intake to HealthKit
|
||||
* @param options Nutrition save options including amount in grams and optional timestamp
|
||||
*/
|
||||
saveFatToHealthKit(options: NutritionSaveOptions): Promise<NutritionSaveResult>;
|
||||
|
||||
/**
|
||||
* Save carbohydrates intake to HealthKit
|
||||
* @param options Nutrition save options including amount in grams and optional timestamp
|
||||
*/
|
||||
saveCarbohydratesToHealthKit(options: NutritionSaveOptions): Promise<NutritionSaveResult>;
|
||||
}
|
||||
|
||||
// Native module interface
|
||||
|
||||
@@ -187,49 +187,6 @@ export class NutritionNotificationHelpers {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送午餐记录提醒
|
||||
*/
|
||||
static async sendLunchReminder(userName: string) {
|
||||
const coachUrl = buildCoachDeepLink({
|
||||
action: 'diet',
|
||||
subAction: 'card',
|
||||
meal: 'lunch'
|
||||
});
|
||||
|
||||
return notificationService.sendImmediateNotification({
|
||||
title: '午餐记录提醒',
|
||||
body: `${userName},记得记录今天的午餐情况哦!`,
|
||||
data: {
|
||||
type: 'lunch_reminder',
|
||||
meal: '午餐',
|
||||
url: coachUrl
|
||||
},
|
||||
sound: true,
|
||||
priority: 'normal',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消午餐提醒
|
||||
*/
|
||||
static async cancelLunchReminder(): Promise<void> {
|
||||
try {
|
||||
const notifications = await notificationService.getAllScheduledNotifications();
|
||||
|
||||
for (const notification of notifications) {
|
||||
if (notification.content.data?.type === 'lunch_reminder' &&
|
||||
notification.content.data?.isDailyReminder === true) {
|
||||
await notificationService.cancelNotification(notification.identifier);
|
||||
console.log('已取消午餐提醒:', notification.identifier);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('取消午餐提醒失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安排每日晚餐提醒
|
||||
* @param userName 用户名
|
||||
|
||||
Reference in New Issue
Block a user