feat(health): 新增日照时长监测卡片与 HealthKit 集成
- iOS 端集成 HealthKit 日照时间 (TimeInDaylight) 数据获取接口 - 新增 SunlightCard 组件,支持查看今日数据及最近30天历史趋势图表 - 更新统计页和自定义设置页,支持开启/关闭日照卡片 - 优化 HealthDataCard 组件,支持自定义图标组件和副标题显示 - 更新多语言文件及应用版本号至 1.1.6
This commit is contained in:
@@ -801,6 +801,50 @@ export async function fetchOxygenSaturation(options: HealthDataOptions): Promise
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchTimeInDaylight(options: HealthDataOptions): Promise<number | null> {
|
||||
try {
|
||||
const result = await HealthKitManager.getTimeInDaylight(options);
|
||||
|
||||
if (result && result.totalValue !== undefined) {
|
||||
logSuccess('晒太阳时长', result);
|
||||
return result.totalValue;
|
||||
} else {
|
||||
logWarning('晒太阳时长', '为空或格式错误');
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
logError('晒太阳时长', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export interface SunlightHistoryPoint {
|
||||
date: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export async function fetchTimeInDaylightHistory(options: HealthDataOptions): Promise<SunlightHistoryPoint[]> {
|
||||
try {
|
||||
const result = await HealthKitManager.getTimeInDaylightSamples(options);
|
||||
|
||||
if (result && result.data && Array.isArray(result.data)) {
|
||||
logSuccess('晒太阳历史', result);
|
||||
return result.data
|
||||
.filter((item: any) => item && typeof item.value === 'number' && item.date)
|
||||
.map((item: any) => ({
|
||||
date: item.date,
|
||||
value: Number(item.value)
|
||||
}));
|
||||
} else {
|
||||
logWarning('晒太阳历史', '为空或格式错误');
|
||||
return [];
|
||||
}
|
||||
} catch (error) {
|
||||
logError('晒太阳历史', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchWristTemperature(options: HealthDataOptions, targetDate?: Date): Promise<number | null> {
|
||||
try {
|
||||
const result = await HealthKitManager.getWristTemperatureSamples(options);
|
||||
|
||||
@@ -29,6 +29,7 @@ const PREFERENCES_KEYS = {
|
||||
SHOW_WEIGHT_CARD: 'user_preference_show_weight_card',
|
||||
SHOW_CIRCUMFERENCE_CARD: 'user_preference_show_circumference_card',
|
||||
SHOW_WRIST_TEMPERATURE_CARD: 'user_preference_show_wrist_temperature_card',
|
||||
SHOW_SUNLIGHT_CARD: 'user_preference_show_sunlight_card',
|
||||
|
||||
// 首页身体指标卡片排序设置
|
||||
STATISTICS_CARD_ORDER: 'user_preference_statistics_card_order',
|
||||
@@ -48,6 +49,7 @@ export interface StatisticsCardsVisibility {
|
||||
showWeight: boolean;
|
||||
showCircumference: boolean;
|
||||
showWristTemperature: boolean;
|
||||
showSunlight: boolean;
|
||||
}
|
||||
|
||||
// 默认卡片顺序
|
||||
@@ -56,6 +58,7 @@ export const DEFAULT_CARD_ORDER: string[] = [
|
||||
'steps',
|
||||
'stress',
|
||||
'sleep',
|
||||
'sunlight',
|
||||
'fitness',
|
||||
'water',
|
||||
'metabolism',
|
||||
@@ -113,6 +116,7 @@ const DEFAULT_PREFERENCES: UserPreferences = {
|
||||
showWeight: true,
|
||||
showCircumference: true,
|
||||
showWristTemperature: true,
|
||||
showSunlight: true,
|
||||
|
||||
// 默认卡片顺序
|
||||
cardOrder: DEFAULT_CARD_ORDER,
|
||||
@@ -150,6 +154,7 @@ export const getUserPreferences = async (): Promise<UserPreferences> => {
|
||||
const showWeight = await AsyncStorage.getItem(PREFERENCES_KEYS.SHOW_WEIGHT_CARD);
|
||||
const showCircumference = await AsyncStorage.getItem(PREFERENCES_KEYS.SHOW_CIRCUMFERENCE_CARD);
|
||||
const showWristTemperature = await AsyncStorage.getItem(PREFERENCES_KEYS.SHOW_WRIST_TEMPERATURE_CARD);
|
||||
const showSunlight = await AsyncStorage.getItem(PREFERENCES_KEYS.SHOW_SUNLIGHT_CARD);
|
||||
const cardOrderStr = await AsyncStorage.getItem(PREFERENCES_KEYS.STATISTICS_CARD_ORDER);
|
||||
const cardOrder = cardOrderStr ? JSON.parse(cardOrderStr) : DEFAULT_PREFERENCES.cardOrder;
|
||||
|
||||
@@ -180,6 +185,7 @@ export const getUserPreferences = async (): Promise<UserPreferences> => {
|
||||
showWeight: showWeight !== null ? showWeight === 'true' : DEFAULT_PREFERENCES.showWeight,
|
||||
showCircumference: showCircumference !== null ? showCircumference === 'true' : DEFAULT_PREFERENCES.showCircumference,
|
||||
showWristTemperature: showWristTemperature !== null ? showWristTemperature === 'true' : DEFAULT_PREFERENCES.showWristTemperature,
|
||||
showSunlight: showSunlight !== null ? showSunlight === 'true' : DEFAULT_PREFERENCES.showSunlight,
|
||||
cardOrder,
|
||||
};
|
||||
} catch (error) {
|
||||
@@ -618,6 +624,7 @@ export const getStatisticsCardsVisibility = async (): Promise<StatisticsCardsVis
|
||||
showWeight: userPreferences.showWeight,
|
||||
showCircumference: userPreferences.showCircumference,
|
||||
showWristTemperature: userPreferences.showWristTemperature,
|
||||
showSunlight: userPreferences.showSunlight,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('获取首页卡片显示设置失败:', error);
|
||||
@@ -634,6 +641,7 @@ export const getStatisticsCardsVisibility = async (): Promise<StatisticsCardsVis
|
||||
showWeight: DEFAULT_PREFERENCES.showWeight,
|
||||
showCircumference: DEFAULT_PREFERENCES.showCircumference,
|
||||
showWristTemperature: DEFAULT_PREFERENCES.showWristTemperature,
|
||||
showSunlight: DEFAULT_PREFERENCES.showSunlight,
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -682,6 +690,7 @@ export const setStatisticsCardVisibility = async (key: keyof StatisticsCardsVisi
|
||||
case 'showWeight': storageKey = PREFERENCES_KEYS.SHOW_WEIGHT_CARD; break;
|
||||
case 'showCircumference': storageKey = PREFERENCES_KEYS.SHOW_CIRCUMFERENCE_CARD; break;
|
||||
case 'showWristTemperature': storageKey = PREFERENCES_KEYS.SHOW_WRIST_TEMPERATURE_CARD; break;
|
||||
case 'showSunlight': storageKey = PREFERENCES_KEYS.SHOW_SUNLIGHT_CARD; break;
|
||||
default: return;
|
||||
}
|
||||
await AsyncStorage.setItem(storageKey, value.toString());
|
||||
|
||||
Reference in New Issue
Block a user