feat: 支持将饮水记录同步到 HealthKit,新增相关功能和权限设置
This commit is contained in:
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user