feat: 支持将饮水记录同步到 HealthKit,新增相关功能和权限设置

This commit is contained in:
richarjiang
2025-09-03 08:42:48 +08:00
parent a70cb1e407
commit e33a690a36
2 changed files with 124 additions and 2 deletions

View File

@@ -11,6 +11,7 @@ import {
updateWaterRecordAction,
} from '@/store/waterSlice';
import { Toast } from '@/utils/toast.utils';
import { saveWaterIntakeToHealthKit, deleteWaterIntakeFromHealthKit } from '@/utils/health';
import dayjs from 'dayjs';
import { useCallback, useEffect, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
@@ -86,6 +87,18 @@ export const useWaterData = () => {
try {
await dispatch(createWaterRecordAction(dto)).unwrap();
// 同步到 HealthKit
try {
const healthKitSuccess = await saveWaterIntakeToHealthKit(amount, recordedAt);
if (!healthKitSuccess) {
console.warn('同步饮水记录到 HealthKit 失败,但应用内记录已保存');
}
} catch (healthError) {
console.error('HealthKit 同步错误:', healthError);
// HealthKit 同步失败不影响主要功能
}
// 重新获取今日统计
dispatch(fetchTodayWaterStats());
return true;
@@ -145,7 +158,27 @@ export const useWaterData = () => {
// 删除喝水记录
const removeWaterRecord = useCallback(async (id: string) => {
try {
// 在删除前,尝试获取记录信息用于 HealthKit 同步
const recordToDelete = waterRecords.find(record => record.id === id);
await dispatch(deleteWaterRecordAction(id)).unwrap();
// 同步删除到 HealthKit
if (recordToDelete) {
try {
const healthKitSuccess = await deleteWaterIntakeFromHealthKit(
id,
recordToDelete.recordedAt || recordToDelete.createdAt
);
if (!healthKitSuccess) {
console.warn('从 HealthKit 删除饮水记录失败,但应用内记录已删除');
}
} catch (healthError) {
console.error('HealthKit 删除同步错误:', healthError);
// HealthKit 同步失败不影响主要功能
}
}
// 重新获取今日统计
dispatch(fetchTodayWaterStats());
@@ -161,7 +194,7 @@ export const useWaterData = () => {
Toast.error(errorMessage);
return false;
}
}, [dispatch]);
}, [dispatch, waterRecords]);
// 更新喝水目标
const updateWaterGoal = useCallback(async (goal: number) => {
@@ -358,6 +391,17 @@ export const useWaterDataByDate = (targetDate?: string) => {
try {
await dispatch(createWaterRecordAction(dto)).unwrap();
// 同步到 HealthKit
try {
const healthKitSuccess = await saveWaterIntakeToHealthKit(amount, dto.recordedAt);
if (!healthKitSuccess) {
console.warn('同步饮水记录到 HealthKit 失败,但应用内记录已保存');
}
} catch (healthError) {
console.error('HealthKit 同步错误:', healthError);
// HealthKit 同步失败不影响主要功能
}
// 重新获取当前日期的数据
await getWaterRecordsByDate(dateToUse);
@@ -429,8 +473,27 @@ export const useWaterDataByDate = (targetDate?: string) => {
// 删除喝水记录
const removeWaterRecord = useCallback(async (id: string) => {
try {
// 在删除前,尝试获取记录信息用于 HealthKit 同步
const recordToDelete = waterRecords.find(record => record.id === id);
await dispatch(deleteWaterRecordAction(id)).unwrap();
// 同步删除到 HealthKit
if (recordToDelete) {
try {
const healthKitSuccess = await deleteWaterIntakeFromHealthKit(
id,
recordToDelete.recordedAt || recordToDelete.createdAt
);
if (!healthKitSuccess) {
console.warn('从 HealthKit 删除饮水记录失败,但应用内记录已删除');
}
} catch (healthError) {
console.error('HealthKit 删除同步错误:', healthError);
// HealthKit 同步失败不影响主要功能
}
}
// 重新获取当前日期的数据
await getWaterRecordsByDate(dateToUse);
@@ -451,7 +514,7 @@ export const useWaterDataByDate = (targetDate?: string) => {
Toast.error(errorMessage);
return false;
}
}, [dispatch, dateToUse, getWaterRecordsByDate]);
}, [dispatch, dateToUse, getWaterRecordsByDate, waterRecords]);
// 更新喝水目标
const updateWaterGoal = useCallback(async (goal: number) => {