From 74b49efe23f49e2f08d11bdebe783253fa633515 Mon Sep 17 00:00:00 2001 From: richarjiang Date: Fri, 5 Dec 2025 16:09:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(app):=20=E5=90=AF=E7=94=A8Expo=20Updates?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=9B=B4=E6=96=B0=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8C=BB=E7=96=97=E8=AE=B0=E5=BD=95=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E6=B5=81=E7=A8=8B=E4=B8=8EAPI=E9=9B=86=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.json | 5 + app/_layout.tsx | 41 ++++-- components/health/tabs/MedicalRecordsTab.tsx | 35 +++-- ios/OutLive.xcodeproj/project.pbxproj | 4 + ios/OutLive/Supporting/Expo.plist | 6 +- ios/Podfile.lock | 63 +++++++++ package-lock.json | 135 +++++++++++++++++++ package.json | 1 + services/healthProfile.ts | 19 +-- store/healthSlice.ts | 2 +- 10 files changed, 279 insertions(+), 32 deletions(-) diff --git a/app.json b/app.json index 4558aef..8a124a6 100644 --- a/app.json +++ b/app.json @@ -72,6 +72,11 @@ }, "android": { "package": "com.anonymous.digitalpilates" + }, + "updates": { + "enabled": true, + "checkAutomatically": "ON_LOAD", + "url": "https://pilate.richarjiang.com/api/expo-updates/manifest" } } } \ No newline at end of file diff --git a/app/_layout.tsx b/app/_layout.tsx index 84c68eb..7104727 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -1,14 +1,7 @@ -import '@/i18n'; -import { DefaultTheme, ThemeProvider } from '@react-navigation/native'; -import { useFonts } from 'expo-font'; -import { Stack, useRouter } from 'expo-router'; -import { StatusBar } from 'expo-status-bar'; -import { GestureHandlerRootView } from 'react-native-gesture-handler'; -import 'react-native-reanimated'; - import PrivacyConsentModal from '@/components/PrivacyConsentModal'; import { useAppDispatch, useAppSelector } from '@/hooks/redux'; import { useQuickActions } from '@/hooks/useQuickActions'; +import '@/i18n'; import { hrvMonitorService } from '@/services/hrvMonitor'; import { cleanupLegacyMedicationNotifications } from '@/services/medicationNotificationCleanup'; import { clearBadgeCount, notificationService } from '@/services/notifications'; @@ -26,8 +19,15 @@ import { initializeHealthPermissions } from '@/utils/health'; import { MoodNotificationHelpers, NutritionNotificationHelpers, WaterNotificationHelpers } from '@/utils/notificationHelpers'; import { getMoodReminderEnabled, getNutritionReminderEnabled, getWaterReminderSettings } from '@/utils/userPreferences'; import { clearPendingWaterRecords, syncPendingWidgetChanges } from '@/utils/widgetDataSync'; +import { DefaultTheme, ThemeProvider } from '@react-navigation/native'; +import { useFonts } from 'expo-font'; +import { Stack, useRouter } from 'expo-router'; +import { StatusBar } from 'expo-status-bar'; +import * as Updates from 'expo-updates'; import React, { useEffect } from 'react'; import { AppState, AppStateStatus } from 'react-native'; +import { GestureHandlerRootView } from 'react-native-gesture-handler'; +import 'react-native-reanimated'; import { DialogProvider } from '@/components/ui/DialogProvider'; import { MembershipModalProvider } from '@/contexts/MembershipModalContext'; @@ -485,6 +485,31 @@ function Bootstrapper({ children }: { children: React.ReactNode }) { getPrivacyAgreed(); }, []); + useEffect(() => { + async function checkUpdate() { + try { + logger.info("Checking for updates..."); + const update = await Updates.checkForUpdateAsync(); + logger.info("Update check:", update); + + if (update.isAvailable) { + logger.info("Update available, fetching..."); + const result = await Updates.fetchUpdateAsync(); + logger.info("Fetch result:", result); + + if (result.isNew) { + logger.info("Reloading app to apply update..."); + Updates.reloadAsync(); + } + } + } catch (e) { + logger.error("Update error:", e); + } + } + + checkUpdate(); + }, []); + const handlePrivacyAgree = () => { dispatch(setPrivacyAgreed()); setShowPrivacyModal(false); diff --git a/components/health/tabs/MedicalRecordsTab.tsx b/components/health/tabs/MedicalRecordsTab.tsx index 965525d..1a6623a 100644 --- a/components/health/tabs/MedicalRecordsTab.tsx +++ b/components/health/tabs/MedicalRecordsTab.tsx @@ -1,6 +1,7 @@ import { MedicalRecordCard } from '@/components/health/MedicalRecordCard'; import { palette } from '@/constants/Colors'; import { useAppDispatch, useAppSelector } from '@/hooks/redux'; +import { useCosUpload } from '@/hooks/useCosUpload'; import { MedicalRecordItem, MedicalRecordType } from '@/services/healthProfile'; import { addNewMedicalRecord, @@ -38,6 +39,11 @@ export function MedicalRecordsTab() { const prescriptions = medicalRecords?.prescriptions || []; const isLoading = useAppSelector(selectHealthLoading); + // COS 上传 + const { upload: uploadToCos, uploading: isUploading } = useCosUpload({ + prefix: 'images/health/medical-records' + }); + const [activeTab, setActiveTab] = useState('medical_record'); const [isModalVisible, setModalVisible] = useState(false); const [isDatePickerVisible, setDatePickerVisibility] = useState(false); @@ -139,16 +145,29 @@ export function MedicalRecordsTab() { setIsSubmitting(true); try { + // 1. 上传所有图片到 COS + const uploadPromises = images.map(async (uri) => { + const result = await uploadToCos({ uri }); + return result.url; + }); + + const uploadedUrls = await Promise.all(uploadPromises); + + // 2. 创建就医资料记录 await dispatch(addNewMedicalRecord({ type: activeTab, - title, + title: title.trim(), date: dayjs(date).format('YYYY-MM-DD'), - images, - note, + images: uploadedUrls, + note: note.trim() || undefined, })).unwrap(); + setModalVisible(false); - } catch (error) { - Alert.alert('错误', '保存失败,请重试'); + resetForm(); + } catch (error: any) { + console.error('保存失败:', error); + const errorMessage = error?.message || '保存失败,请重试'; + Alert.alert('错误', errorMessage); } finally { setIsSubmitting(false); } @@ -275,10 +294,10 @@ export function MedicalRecordsTab() { - {isSubmitting ? ( + {(isSubmitting || isUploading) ? ( ) : ( 保存 diff --git a/ios/OutLive.xcodeproj/project.pbxproj b/ios/OutLive.xcodeproj/project.pbxproj index 97fe0af..cf659dd 100644 --- a/ios/OutLive.xcodeproj/project.pbxproj +++ b/ios/OutLive.xcodeproj/project.pbxproj @@ -404,6 +404,7 @@ "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/ExpoConstants_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/EXNotifications/ExpoNotifications_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/EXTaskManager/ExpoTaskManager_privacy.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/EXUpdates/EXUpdates.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoLocalization/ExpoLocalization_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoMediaLibrary/ExpoMediaLibrary_privacy.bundle", @@ -412,6 +413,7 @@ "${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage/RNCAsyncStorage_resources.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo/RNDeviceInfoPrivacyInfo.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/RNSVG/RNSVGFilters.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/ReachabilitySwift/ReachabilitySwift.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/RevenueCat/RevenueCat.bundle", @@ -427,6 +429,7 @@ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoConstants_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoNotifications_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoTaskManager_privacy.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXUpdates.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoLocalization_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoMediaLibrary_privacy.bundle", @@ -435,6 +438,7 @@ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCAsyncStorage_resources.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNDeviceInfoPrivacyInfo.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ReachabilitySwift.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RevenueCat.bundle", diff --git a/ios/OutLive/Supporting/Expo.plist b/ios/OutLive/Supporting/Expo.plist index 750be02..4f34201 100644 --- a/ios/OutLive/Supporting/Expo.plist +++ b/ios/OutLive/Supporting/Expo.plist @@ -2,10 +2,12 @@ + EXUpdatesEnabled + + EXUpdatesURL + https://pilate.richarjiang.com/api/expo-updates/manifest EXUpdatesCheckOnLaunch ALWAYS - EXUpdatesEnabled - EXUpdatesLaunchWaitMs 0 diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e729190..d113283 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,4 +1,6 @@ PODS: + - EASClient (1.0.7): + - ExpoModulesCore - EXApplication (7.0.7): - ExpoModulesCore - EXConstants (18.0.10): @@ -6,6 +8,9 @@ PODS: - EXImageLoader (6.0.0): - ExpoModulesCore - React-Core + - EXJSONUtils (0.15.0) + - EXManifests (1.0.9): + - ExpoModulesCore - EXNotifications (0.32.13): - ExpoModulesCore - Expo (54.0.26): @@ -117,9 +122,40 @@ PODS: - ExpoModulesCore - ExpoWebBrowser (15.0.9): - ExpoModulesCore + - EXStructuredHeaders (5.0.0) - EXTaskManager (14.0.8): - ExpoModulesCore - UMAppLoader + - EXUpdates (29.0.14): + - EASClient + - EXManifests + - ExpoModulesCore + - EXStructuredHeaders + - EXUpdatesInterface + - hermes-engine + - RCTRequired + - RCTTypeSafety + - ReachabilitySwift + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga + - EXUpdatesInterface (2.0.0): + - ExpoModulesCore - FBLazyVector (0.81.5) - hermes-engine (0.81.5): - hermes-engine/Pre-built (= 0.81.5) @@ -173,6 +209,7 @@ PODS: - FBLazyVector (= 0.81.5) - RCTRequired (= 0.81.5) - React-Core (= 0.81.5) + - ReachabilitySwift (5.2.4) - React (0.81.5): - React-Core (= 0.81.5) - React-Core/DevSupport (= 0.81.5) @@ -2311,9 +2348,12 @@ PODS: - ZXingObjC/Core DEPENDENCIES: + - EASClient (from `../node_modules/expo-eas-client/ios`) - EXApplication (from `../node_modules/expo-application/ios`) - EXConstants (from `../node_modules/expo-constants/ios`) - EXImageLoader (from `../node_modules/expo-image-loader/ios`) + - EXJSONUtils (from `../node_modules/expo-json-utils/ios`) + - EXManifests (from `../node_modules/expo-manifests/ios`) - EXNotifications (from `../node_modules/expo-notifications/ios`) - Expo (from `../node_modules/expo`) - ExpoAppleAuthentication (from `../node_modules/expo-apple-authentication/ios`) @@ -2343,7 +2383,10 @@ DEPENDENCIES: - ExpoSystemUI (from `../node_modules/expo-system-ui/ios`) - "ExpoUI (from `../node_modules/@expo/ui/ios`)" - ExpoWebBrowser (from `../node_modules/expo-web-browser/ios`) + - EXStructuredHeaders (from `../node_modules/expo-structured-headers/ios`) - EXTaskManager (from `../node_modules/expo-task-manager/ios`) + - EXUpdates (from `../node_modules/expo-updates/ios`) + - EXUpdatesInterface (from `../node_modules/expo-updates-interface/ios`) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - lottie-react-native (from `../node_modules/lottie-react-native`) @@ -2439,6 +2482,7 @@ SPEC REPOS: - libwebp - lottie-ios - PurchasesHybridCommon + - ReachabilitySwift - RevenueCat - SDWebImage - SDWebImageAVIFCoder @@ -2448,12 +2492,18 @@ SPEC REPOS: - ZXingObjC EXTERNAL SOURCES: + EASClient: + :path: "../node_modules/expo-eas-client/ios" EXApplication: :path: "../node_modules/expo-application/ios" EXConstants: :path: "../node_modules/expo-constants/ios" EXImageLoader: :path: "../node_modules/expo-image-loader/ios" + EXJSONUtils: + :path: "../node_modules/expo-json-utils/ios" + EXManifests: + :path: "../node_modules/expo-manifests/ios" EXNotifications: :path: "../node_modules/expo-notifications/ios" Expo: @@ -2512,8 +2562,14 @@ EXTERNAL SOURCES: :path: "../node_modules/@expo/ui/ios" ExpoWebBrowser: :path: "../node_modules/expo-web-browser/ios" + EXStructuredHeaders: + :path: "../node_modules/expo-structured-headers/ios" EXTaskManager: :path: "../node_modules/expo-task-manager/ios" + EXUpdates: + :path: "../node_modules/expo-updates/ios" + EXUpdatesInterface: + :path: "../node_modules/expo-updates-interface/ios" FBLazyVector: :path: "../node_modules/react-native/Libraries/FBLazyVector" hermes-engine: @@ -2689,9 +2745,12 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: + EASClient: 68127f1248d2b25fdc82dbbfb17be95d1c4700be EXApplication: 296622817d459f46b6c5fe8691f4aac44d2b79e7 EXConstants: fd688cef4e401dcf798a021cfb5d87c890c30ba3 EXImageLoader: 189e3476581efe3ad4d1d3fb4735b7179eb26f05 + EXJSONUtils: 1d3e4590438c3ee593684186007028a14b3686cd + EXManifests: 26e15640538c3d5ef028077ebcaf004b744d4932 EXNotifications: a62e1f8e3edd258dc3b155d3caa49f32920f1c6c Expo: 7af24402df45b9384900104e88a11896ffc48161 ExpoAppleAuthentication: bc9de6e9ff3340604213ab9031d4c4f7f802623e @@ -2721,7 +2780,10 @@ SPEC CHECKSUMS: ExpoSystemUI: 2761aa6875849af83286364811d46e8ed8ea64c7 ExpoUI: b99a1d1ef5352a60bebf4f4fd3a50d2f896ae804 ExpoWebBrowser: b973e1351fdcf5fec0c400997b1851f5a8219ec3 + EXStructuredHeaders: c951e77f2d936f88637421e9588c976da5827368 EXTaskManager: cbbb80cbccea6487ccca0631809fbba2ed3e5271 + EXUpdates: 9042dc213f17593a02d59ef7dd9d297edf621936 + EXUpdatesInterface: 5adf50cb41e079c861da6d9b4b954c3db9a50734 FBLazyVector: e95a291ad2dadb88e42b06e0c5fb8262de53ec12 hermes-engine: 9f4dfe93326146a1c99eb535b1cb0b857a3cd172 libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7 @@ -2733,6 +2795,7 @@ SPEC CHECKSUMS: RCTDeprecation: 943572d4be82d480a48f4884f670135ae30bf990 RCTRequired: 8f3cfc90cc25cf6e420ddb3e7caaaabc57df6043 RCTTypeSafety: 16a4144ca3f959583ab019b57d5633df10b5e97c + ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda React: 914f8695f9bf38e6418228c2ffb70021e559f92f React-callinvoker: 1c0808402aee0c6d4a0d8e7220ce6547af9fba71 React-Core: c61410ef0ca6055e204a963992e363227e0fd1c5 diff --git a/package-lock.json b/package-lock.json index e76af39..7c22f6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,6 +49,7 @@ "expo-symbols": "~1.0.7", "expo-system-ui": "~6.0.8", "expo-task-manager": "~14.0.8", + "expo-updates": "^29.0.14", "expo-web-browser": "~15.0.7", "i18next": "^25.6.2", "lodash": "^4.17.21", @@ -7410,6 +7411,12 @@ "expo": "*" } }, + "node_modules/expo-eas-client": { + "version": "1.0.7", + "resolved": "https://mirrors.tencent.com/npm/expo-eas-client/-/expo-eas-client-1.0.7.tgz", + "integrity": "sha512-Q/b1X0fM+3beqqvffok14pjxMF600NxopdSr9WJY61fF4xllcVnALS0kEudffp9ihMOfcb5xWYqzKj6jMqYDIw==", + "license": "MIT" + }, "node_modules/expo-file-system": { "version": "19.0.19", "resolved": "https://mirrors.tencent.com/npm/expo-file-system/-/expo-file-system-19.0.19.tgz", @@ -7492,6 +7499,12 @@ "expo": "*" } }, + "node_modules/expo-json-utils": { + "version": "0.15.0", + "resolved": "https://mirrors.tencent.com/npm/expo-json-utils/-/expo-json-utils-0.15.0.tgz", + "integrity": "sha512-duRT6oGl80IDzH2LD2yEFWNwGIC2WkozsB6HF3cDYNoNNdUvFk6uN3YiwsTsqVM/D0z6LEAQ01/SlYvN+Fw0JQ==", + "license": "MIT" + }, "node_modules/expo-keep-awake": { "version": "15.0.7", "resolved": "https://mirrors.tencent.com/npm/expo-keep-awake/-/expo-keep-awake-15.0.7.tgz", @@ -7540,6 +7553,19 @@ "react": "*" } }, + "node_modules/expo-manifests": { + "version": "1.0.9", + "resolved": "https://mirrors.tencent.com/npm/expo-manifests/-/expo-manifests-1.0.9.tgz", + "integrity": "sha512-5uVgvIo0o+xBcEJiYn4uVh72QSIqyHePbYTWXYa4QamXd+AmGY/yWmtHaNqCqjsPLCwXyn4OxPr7jXJCeTWLow==", + "license": "MIT", + "dependencies": { + "@expo/config": "~12.0.10", + "expo-json-utils": "~0.15.0" + }, + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-media-library": { "version": "18.2.0", "resolved": "https://mirrors.tencent.com/npm/expo-media-library/-/expo-media-library-18.2.0.tgz", @@ -7913,6 +7939,12 @@ "react-native": "*" } }, + "node_modules/expo-structured-headers": { + "version": "5.0.0", + "resolved": "https://mirrors.tencent.com/npm/expo-structured-headers/-/expo-structured-headers-5.0.0.tgz", + "integrity": "sha512-RmrBtnSphk5REmZGV+lcdgdpxyzio5rJw8CXviHE6qH5pKQQ83fhMEcigvrkBdsn2Efw2EODp4Yxl1/fqMvOZw==", + "license": "MIT" + }, "node_modules/expo-symbols": { "version": "1.0.7", "resolved": "https://mirrors.tencent.com/npm/expo-symbols/-/expo-symbols-1.0.7.tgz", @@ -7959,6 +7991,109 @@ "react-native": "*" } }, + "node_modules/expo-updates": { + "version": "29.0.14", + "resolved": "https://mirrors.tencent.com/npm/expo-updates/-/expo-updates-29.0.14.tgz", + "integrity": "sha512-VgXtjczQ4A/r4Jy/XEj+jWimk0vSd+GdDsYfLzl3CG/9fyQ6NXDP20PgiGfeF+A9rfA4IU3VyWdNJFBPyPPIgg==", + "license": "MIT", + "dependencies": { + "@expo/code-signing-certificates": "0.0.5", + "@expo/plist": "^0.4.7", + "@expo/spawn-async": "^1.7.2", + "arg": "4.1.0", + "chalk": "^4.1.2", + "debug": "^4.3.4", + "expo-eas-client": "~1.0.7", + "expo-manifests": "~1.0.9", + "expo-structured-headers": "~5.0.0", + "expo-updates-interface": "~2.0.0", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "ignore": "^5.3.1", + "resolve-from": "^5.0.0" + }, + "bin": { + "expo-updates": "bin/cli.js" + }, + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, + "node_modules/expo-updates-interface": { + "version": "2.0.0", + "resolved": "https://mirrors.tencent.com/npm/expo-updates-interface/-/expo-updates-interface-2.0.0.tgz", + "integrity": "sha512-pTzAIufEZdVPKql6iMi5ylVSPqV1qbEopz9G6TSECQmnNde2nwq42PxdFBaUEd8IZJ/fdJLQnOT3m6+XJ5s7jg==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-updates/node_modules/@expo/plist": { + "version": "0.4.7", + "resolved": "https://mirrors.tencent.com/npm/@expo/plist/-/plist-0.4.7.tgz", + "integrity": "sha512-dGxqHPvCZKeRKDU1sJZMmuyVtcASuSYh1LPFVaM1DuffqPL36n6FMEL0iUqq2Tx3xhWk8wCnWl34IKplUjJDdA==", + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.2.3", + "xmlbuilder": "^15.1.1" + } + }, + "node_modules/expo-updates/node_modules/arg": { + "version": "4.1.0", + "resolved": "https://mirrors.tencent.com/npm/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==" + }, + "node_modules/expo-updates/node_modules/getenv": { + "version": "2.0.0", + "resolved": "https://mirrors.tencent.com/npm/getenv/-/getenv-2.0.0.tgz", + "integrity": "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/expo-updates/node_modules/glob": { + "version": "13.0.0", + "resolved": "https://mirrors.tencent.com/npm/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/expo-updates/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://mirrors.tencent.com/npm/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/expo-updates/node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://mirrors.tencent.com/npm/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "engines": { + "node": ">=8.0" + } + }, "node_modules/expo-web-browser": { "version": "15.0.9", "resolved": "https://mirrors.tencent.com/npm/expo-web-browser/-/expo-web-browser-15.0.9.tgz", diff --git a/package.json b/package.json index 91aabe8..5da37cd 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "expo-symbols": "~1.0.7", "expo-system-ui": "~6.0.8", "expo-task-manager": "~14.0.8", + "expo-updates": "^29.0.14", "expo-web-browser": "~15.0.7", "i18next": "^25.6.2", "lodash": "^4.17.21", diff --git a/services/healthProfile.ts b/services/healthProfile.ts index 8e9bc13..f0a43c0 100644 --- a/services/healthProfile.ts +++ b/services/healthProfile.ts @@ -166,6 +166,8 @@ export interface MedicalRecordItem { date: string; // YYYY-MM-DD images: string[]; // Image URLs note?: string; + createdAt: string; // ISO 8601 + updatedAt: string; // ISO 8601 } export interface MedicalRecordsData { @@ -177,30 +179,21 @@ export interface MedicalRecordsData { * 获取就医资料列表 */ export async function getMedicalRecords(): Promise { - // Mock implementation for now - // return api.get('/api/health-profiles/medical-records'); - return { - records: [], - prescriptions: [] - }; + return api.get('/api/health-profiles/medical-records'); } /** * 添加就医资料 */ -export async function addMedicalRecord(data: Omit): Promise { - // return api.post('/api/health-profiles/medical-records', data); - return { - id: Date.now().toString(), - ...data - }; +export async function addMedicalRecord(data: Omit): Promise { + return api.post('/api/health-profiles/medical-records', data); } /** * 删除就医资料 */ export async function deleteMedicalRecord(id: string): Promise { - // return api.delete(`/api/health-profiles/medical-records/${id}`); + return api.delete(`/api/health-profiles/medical-records/${id}`); } // ==================== 家庭健康管理 API ==================== diff --git a/store/healthSlice.ts b/store/healthSlice.ts index 49e506f..42f8494 100644 --- a/store/healthSlice.ts +++ b/store/healthSlice.ts @@ -387,7 +387,7 @@ export const fetchMedicalRecords = createAsyncThunk( */ export const addNewMedicalRecord = createAsyncThunk( 'health/addMedicalRecord', - async (data: Omit, { rejectWithValue }) => { + async (data: Omit, { rejectWithValue }) => { try { const result = await healthProfileApi.addMedicalRecord(data); return result;