From 601e3ed15e393a972c57b15fa90eae589d76618a Mon Sep 17 00:00:00 2001 From: tao Date: Fri, 22 Aug 2025 17:34:51 +0800 Subject: [PATCH] =?UTF-8?q?google=E5=92=8Capple=E7=99=BB=E5=BD=95ok?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Flutter/Debug.xcconfig | 1 + ios/Flutter/Release.xcconfig | 1 + ios/GoogleService-Info.plist | 14 ++ ios/Podfile | 43 +++++ ios/Podfile.lock | 157 +++++++++++++++ ios/Runner.xcodeproj/project.pbxproj | 179 +++++++++++++++++- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- .../contents.xcworkspacedata | 3 + ios/Runner/Info.plist | 10 + ios/Runner/Runner.entitlements | 10 + lib/page/home/home_page.dart | 2 +- lib/page/record/detail/widget/error_box.dart | 1 - .../record/detail/widget/warning_box.dart | 13 ++ lib/page/record/list/widget/item_widget.dart | 2 +- lib/page/system/login/login_page.dart | 113 ++++++++--- .../system/login/widget/agreement_box.dart | 39 ++-- lib/page/system/login/widget/widget.dart | 2 +- lib/utils/common.dart | 6 + privacy_policy.html | 45 +++++ pubspec.lock | 24 +++ pubspec.yaml | 1 + terms_service.html | 35 ++++ 22 files changed, 639 insertions(+), 64 deletions(-) create mode 100644 ios/GoogleService-Info.plist create mode 100644 ios/Podfile create mode 100644 ios/Podfile.lock create mode 100644 ios/Runner/Runner.entitlements create mode 100644 lib/utils/common.dart create mode 100644 privacy_policy.html create mode 100644 terms_service.html diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index 592ceee..ec97fc6 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig index 592ceee..c4855bf 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/ios/GoogleService-Info.plist b/ios/GoogleService-Info.plist new file mode 100644 index 0000000..4c4c218 --- /dev/null +++ b/ios/GoogleService-Info.plist @@ -0,0 +1,14 @@ + + + + + CLIENT_ID + 497244455669-4c8jmohrsj81e7rpjfamv3kvr07haa6r.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.497244455669-4c8jmohrsj81e7rpjfamv3kvr07haa6r + PLIST_VERSION + 1 + BUNDLE_ID + com.curainhealth.derma + + \ No newline at end of file diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 0000000..a20f12b --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,43 @@ +# Uncomment this line to define a global platform for your project +platform :ios, '12.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/ios/Podfile.lock b/ios/Podfile.lock new file mode 100644 index 0000000..a40083f --- /dev/null +++ b/ios/Podfile.lock @@ -0,0 +1,157 @@ +PODS: + - AppAuth (2.0.0): + - AppAuth/Core (= 2.0.0) + - AppAuth/ExternalUserAgent (= 2.0.0) + - AppAuth/Core (2.0.0) + - AppAuth/ExternalUserAgent (2.0.0): + - AppAuth/Core + - AppCheckCore (11.2.0): + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/UserDefaults (~> 8.0) + - PromisesObjC (~> 2.4) + - DKImagePickerController/Core (4.3.9): + - DKImagePickerController/ImageDataManager + - DKImagePickerController/Resource + - DKImagePickerController/ImageDataManager (4.3.9) + - DKImagePickerController/PhotoGallery (4.3.9): + - DKImagePickerController/Core + - DKPhotoGallery + - DKImagePickerController/Resource (4.3.9) + - DKPhotoGallery (0.0.19): + - DKPhotoGallery/Core (= 0.0.19) + - DKPhotoGallery/Model (= 0.0.19) + - DKPhotoGallery/Preview (= 0.0.19) + - DKPhotoGallery/Resource (= 0.0.19) + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Core (0.0.19): + - DKPhotoGallery/Model + - DKPhotoGallery/Preview + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Model (0.0.19): + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Preview (0.0.19): + - DKPhotoGallery/Model + - DKPhotoGallery/Resource + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Resource (0.0.19): + - SDWebImage + - SwiftyGif + - file_picker (0.0.1): + - DKImagePickerController/PhotoGallery + - Flutter + - Flutter (1.0.0) + - google_sign_in_ios (0.0.1): + - Flutter + - FlutterMacOS + - GoogleSignIn (~> 9.0) + - GTMSessionFetcher (>= 3.4.0) + - GoogleSignIn (9.0.0): + - AppAuth (~> 2.0) + - AppCheckCore (~> 11.0) + - GTMAppAuth (~> 5.0) + - GTMSessionFetcher/Core (~> 3.3) + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GTMAppAuth (5.0.0): + - AppAuth/Core (~> 2.0) + - GTMSessionFetcher/Core (< 4.0, >= 3.3) + - GTMSessionFetcher (3.5.0): + - GTMSessionFetcher/Full (= 3.5.0) + - GTMSessionFetcher/Core (3.5.0) + - GTMSessionFetcher/Full (3.5.0): + - GTMSessionFetcher/Core + - image_picker_ios (0.0.1): + - Flutter + - PromisesObjC (2.4.0) + - SDWebImage (5.21.0): + - SDWebImage/Core (= 5.21.0) + - SDWebImage/Core (5.21.0) + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - sign_in_with_apple (0.0.1): + - Flutter + - SwiftyGif (5.4.5) + - url_launcher_ios (0.0.1): + - Flutter + - webview_flutter_wkwebview (0.0.1): + - Flutter + - FlutterMacOS + +DEPENDENCIES: + - file_picker (from `.symlinks/plugins/file_picker/ios`) + - Flutter (from `Flutter`) + - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/darwin`) + - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`) + +SPEC REPOS: + trunk: + - AppAuth + - AppCheckCore + - DKImagePickerController + - DKPhotoGallery + - GoogleSignIn + - GoogleUtilities + - GTMAppAuth + - GTMSessionFetcher + - PromisesObjC + - SDWebImage + - SwiftyGif + +EXTERNAL SOURCES: + file_picker: + :path: ".symlinks/plugins/file_picker/ios" + Flutter: + :path: Flutter + google_sign_in_ios: + :path: ".symlinks/plugins/google_sign_in_ios/darwin" + image_picker_ios: + :path: ".symlinks/plugins/image_picker_ios/ios" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + sign_in_with_apple: + :path: ".symlinks/plugins/sign_in_with_apple/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" + webview_flutter_wkwebview: + :path: ".symlinks/plugins/webview_flutter_wkwebview/darwin" + +SPEC CHECKSUMS: + AppAuth: 1c1a8afa7e12f2ec3a294d9882dfa5ab7d3cb063 + AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f + DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c + DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 + file_picker: b159e0c068aef54932bb15dc9fd1571818edaf49 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + google_sign_in_ios: 4bb0e529b167cadc6ac785b6ed943c0a0a4cc1c9 + GoogleSignIn: c7f09cfbc85a1abf69187be091997c317cc33b77 + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + GTMAppAuth: 217a876b249c3c585a54fd6f73e6b58c4f5c4238 + GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 + image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868 + shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 + sign_in_with_apple: f3bf75217ea4c2c8b91823f225d70230119b8440 + SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 + url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe + webview_flutter_wkwebview: a4af96a051138e28e29f60101d094683b9f82188 + +PODFILE CHECKSUM: 20e260c9bb3f61194c661a4ba028da86e4f3ed96 + +COCOAPODS: 1.15.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index ed265a9..e9d1e1d 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -14,6 +14,9 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + B2C1DC313184284E0ACE15C3 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FF01D3770A2B1A278D9CEA3E /* Pods_Runner.framework */; }; + BE80B2692E58584100B9D06C /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = BE80B2682E58584100B9D06C /* GoogleService-Info.plist */; }; + EF41B2B5878033BA2E2A3784 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 148C7B80FE763A1F6EC1D040 /* Pods_RunnerTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -40,11 +43,16 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 148C7B80FE763A1F6EC1D040 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 29DB5880C5E0EB319409AB88 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 2EE200226F04F725CAF69593 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 4910FEBC6E9AB543CBDE4164 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 4D4E01B3FEB7F4F92FE05370 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -55,19 +63,42 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BE80B2682E58584100B9D06C /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + BE80B26A2E58651B00B9D06C /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; + D0B0FA61A7C0225893A20AB0 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + F50981F58D16907F7D257EF9 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + FF01D3770A2B1A278D9CEA3E /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 673924360600E62C205F7EE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EF41B2B5878033BA2E2A3784 /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + B2C1DC313184284E0ACE15C3 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 2B7116C0C0DB77B84168B4F0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + FF01D3770A2B1A278D9CEA3E /* Pods_Runner.framework */, + 148C7B80FE763A1F6EC1D040 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; 331C8082294A63A400263BE5 /* RunnerTests */ = { isa = PBXGroup; children = ( @@ -76,6 +107,19 @@ path = RunnerTests; sourceTree = ""; }; + 68FE025E095F415E06B2D97C /* Pods */ = { + isa = PBXGroup; + children = ( + F50981F58D16907F7D257EF9 /* Pods-Runner.debug.xcconfig */, + 29DB5880C5E0EB319409AB88 /* Pods-Runner.release.xcconfig */, + 2EE200226F04F725CAF69593 /* Pods-Runner.profile.xcconfig */, + 4D4E01B3FEB7F4F92FE05370 /* Pods-RunnerTests.debug.xcconfig */, + D0B0FA61A7C0225893A20AB0 /* Pods-RunnerTests.release.xcconfig */, + 4910FEBC6E9AB543CBDE4164 /* Pods-RunnerTests.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -90,10 +134,13 @@ 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( + BE80B2682E58584100B9D06C /* GoogleService-Info.plist */, 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, + 68FE025E095F415E06B2D97C /* Pods */, + 2B7116C0C0DB77B84168B4F0 /* Frameworks */, ); sourceTree = ""; }; @@ -109,6 +156,7 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + BE80B26A2E58651B00B9D06C /* Runner.entitlements */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, @@ -128,8 +176,10 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + 0F3FEBDC615139468417C64E /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, + 673924360600E62C205F7EE5 /* Frameworks */, ); buildRules = ( ); @@ -145,12 +195,15 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + A32A1FBC0FE52BB5155FA83B /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + A1356966918676202870ABF7 /* [CP] Embed Pods Frameworks */, + F9976B65A146EAF1A08FD311 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -214,6 +267,7 @@ files = ( 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + BE80B2692E58584100B9D06C /* GoogleService-Info.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, ); @@ -222,6 +276,28 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 0F3FEBDC615139468417C64E /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -253,6 +329,62 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + A1356966918676202870ABF7 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A32A1FBC0FE52BB5155FA83B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + F9976B65A146EAF1A08FD311 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -361,30 +493,41 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = H7NPMTZBE4; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.curainhealth.derma.dermaFlutter; + PRODUCT_BUNDLE_IDENTIFIER = com.curainhealth.derma; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; VERSIONING_SYSTEM = "apple-generic"; }; name = Profile; }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 4D4E01B3FEB7F4F92FE05370 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.curainhealth.derma.dermaFlutter.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.curainhealth.derma.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -395,13 +538,14 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D0B0FA61A7C0225893A20AB0 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.curainhealth.derma.dermaFlutter.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.curainhealth.derma.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -410,13 +554,14 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 4910FEBC6E9AB543CBDE4164 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.curainhealth.derma.dermaFlutter.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.curainhealth.derma.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -540,18 +685,28 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = H7NPMTZBE4; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.curainhealth.derma.dermaFlutter; + PRODUCT_BUNDLE_IDENTIFIER = com.curainhealth.derma; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -562,17 +717,29 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = H7NPMTZBE4; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.curainhealth.derma.dermaFlutter; + PRODUCT_BUNDLE_IDENTIFIER = com.curainhealth.derma; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Demacare; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index e3773d4..fa4cdb6 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -52,7 +52,7 @@ + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 4be0c4f..dabb289 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -52,5 +52,15 @@ UIApplicationSupportsIndirectInputEvents + CFBundleURLTypes + + + CFBundleURLSchemes + + com.googleusercontent.apps.497244455669-4c8jmohrsj81e7rpjfamv3kvr07haa6r + + + + diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements new file mode 100644 index 0000000..a812db5 --- /dev/null +++ b/ios/Runner/Runner.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.developer.applesignin + + Default + + + diff --git a/lib/page/home/home_page.dart b/lib/page/home/home_page.dart index 0f16e61..41a9fea 100644 --- a/lib/page/home/home_page.dart +++ b/lib/page/home/home_page.dart @@ -57,7 +57,7 @@ class _HomePageState extends State with AutomaticKeepAliveClientMixin return Scaffold( resizeToAvoidBottomInset: false, body: AppBackend( - child: Column( + child: ListView( children: [ AppHeader(), UploadBox( diff --git a/lib/page/record/detail/widget/error_box.dart b/lib/page/record/detail/widget/error_box.dart index 86911a0..c4fcef7 100644 --- a/lib/page/record/detail/widget/error_box.dart +++ b/lib/page/record/detail/widget/error_box.dart @@ -1,5 +1,4 @@ import 'package:derma_flutter/api/dto/skin_check_dto.dart'; -import 'package:derma_flutter/config/theme/custom_colors.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:remixicon/remixicon.dart'; diff --git a/lib/page/record/detail/widget/warning_box.dart b/lib/page/record/detail/widget/warning_box.dart index 329160a..eb5cff2 100644 --- a/lib/page/record/detail/widget/warning_box.dart +++ b/lib/page/record/detail/widget/warning_box.dart @@ -1,9 +1,11 @@ import 'package:derma_flutter/api/dto/skin_check_dto.dart'; import 'package:derma_flutter/api/endpoints/skin_api.dart'; import 'package:derma_flutter/config/theme/custom_colors.dart'; +import 'package:derma_flutter/providers/app_store.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:go_router/go_router.dart'; +import 'package:provider/provider.dart'; import 'package:remixicon/remixicon.dart'; import 'common_box.dart'; @@ -20,6 +22,17 @@ class WarningBox extends StatefulWidget { class _WarningBoxState extends State { final _emailController = TextEditingController(); + @override + void initState() { + super.initState(); + _init(); + } + + void _init() { + var appStore = context.read(); + _emailController.text = appStore.userInfo?.email ?? ""; + } + ///提交 void _handSubmit() async { if (_emailController.text.isEmpty) { diff --git a/lib/page/record/list/widget/item_widget.dart b/lib/page/record/list/widget/item_widget.dart index 09bbd37..1a18c2e 100644 --- a/lib/page/record/list/widget/item_widget.dart +++ b/lib/page/record/list/widget/item_widget.dart @@ -90,7 +90,7 @@ class _ItemWidgetState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "health", + "healthy", style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: color), ), Container( diff --git a/lib/page/system/login/login_page.dart b/lib/page/system/login/login_page.dart index 2e05d6f..cc28551 100644 --- a/lib/page/system/login/login_page.dart +++ b/lib/page/system/login/login_page.dart @@ -9,7 +9,9 @@ import 'package:go_router/go_router.dart'; import 'package:google_sign_in/google_sign_in.dart'; import 'package:provider/provider.dart'; import 'package:remixicon/remixicon.dart'; +import 'package:sign_in_with_apple/sign_in_with_apple.dart'; import '../../../providers/app_store.dart'; +import '../../../utils/common.dart'; import '../../../widgets/common/app_backend.dart'; import '../../../widgets/ui_kit/button/custom_button.dart'; import 'widget/agreement_box.dart'; @@ -24,6 +26,7 @@ class LoginPage extends StatefulWidget { class _LoginPageState extends State { var _subLoading = false; + ///协议 bool _agree = false; @@ -31,8 +34,8 @@ class _LoginPageState extends State { final GoogleSignIn _googleSignIn = GoogleSignIn.instance; ///邮箱输入框 - final TextEditingController _emailController = TextEditingController(text: "18207394@qq.com"); - final TextEditingController _passwordController = TextEditingController(text: "111"); + final TextEditingController _emailController = TextEditingController(text: ""); + final TextEditingController _passwordController = TextEditingController(text: ""); //显示密码 var _hidePassword = true; @@ -40,14 +43,40 @@ class _LoginPageState extends State { @override void initState() { super.initState(); + _ensureNetworkPermission(); _initGoogleSign(); } + /// 预触发 iOS 网络权限弹窗 + Future _ensureNetworkPermission() async { + try { + await Dio().get( + 'https://captive.apple.com/hotspot-detect.html', + options: Options( + sendTimeout: const Duration(seconds: 3), + receiveTimeout: const Duration(seconds: 3), + headers: {'Cache-Control': 'no-cache'}, + ), + ); + return true; + } catch (_) { + return false; + } + } + void _initGoogleSign() { - _googleSignIn.initialize( - clientId: null, - serverClientId: "497244455669-sl271gkb1polqd8kqtnb6co82n95aerq.apps.googleusercontent.com", - ); + if (isAndroid()) { + _googleSignIn.initialize( + clientId: null, + serverClientId: "497244455669-sl271gkb1polqd8kqtnb6co82n95aerq.apps.googleusercontent.com", + ); + } else { + _googleSignIn.initialize( + clientId: "497244455669-4c8jmohrsj81e7rpjfamv3kvr07haa6r.apps.googleusercontent.com", + serverClientId: "497244455669-sl271gkb1polqd8kqtnb6co82n95aerq.apps.googleusercontent.com", + ); + } + _googleSignIn.authenticationEvents .listen((_) { print("登陆成功"); @@ -57,7 +86,8 @@ class _LoginPageState extends State { }); } - void _handleSignIn() async { + ///谷歌登录 + void _handleGoogleSignIn() async { if (!_agree) { EasyLoading.showToast('Please read and agree to the terms first.'); return; @@ -69,7 +99,7 @@ class _LoginPageState extends State { // 使用 authenticate() 进行认证 GoogleSignInAccount? user = await _googleSignIn.authenticate(); var auth = user.authentication; - + // var res = await Dio().get("https://oauth2.googleapis.com/tokeninfo?id_token=${auth.idToken}"); //登陆 EasyLoading.show(status: "Logging in..."); @@ -77,25 +107,50 @@ class _LoginPageState extends State { EasyLoading.dismiss(); _onLogin(res); } - // } catch (e) { - // if (e is GoogleSignInException) { - // if (e.code == GoogleSignInExceptionCode.canceled) { - // // 用户取消登录 - // print("User canceled login."); - // } else { - // // 其他错误 - // print("Google Sign-In error: $e"); - // } - // } else { - // print("Unknown error: $e"); - // } - // } + // } catch (e) { + // if (e is GoogleSignInException) { + // if (e.code == GoogleSignInExceptionCode.canceled) { + // // 用户取消登录 + // print("User canceled login."); + // } else { + // // 其他错误 + // print("Google Sign-In error: $e"); + // } + // } else { + // print("Unknown error: $e"); + // } + // } } catch (e) { EasyLoading.showError("Login failed"); print("登录错误: $e"); } } + ///apple登录 + void _handAppleSignIn() async { + if (!_agree) { + EasyLoading.showToast('Please read and agree to the terms first.'); + return; + } + + try { + final credential = await SignInWithApple.getAppleIDCredential( + scopes: [ + AppleIDAuthorizationScopes.email, + AppleIDAuthorizationScopes.fullName, + ], + ); + EasyLoading.show(status: "Logging in..."); + var res = await thirdLoginApi(credential.identityToken!, OtherLoginType.apple); + EasyLoading.dismiss(); + _onLogin(res); + print('Apple Credential: ${credential.identityToken}'); + print('Apple Email: ${credential.email}'); + } catch (e) { + print('Error during Apple sign-in: $e'); + } + } + void _handSubmit() async { if (!_agree) { EasyLoading.showToast('Please read and agree to the terms first.'); @@ -158,7 +213,7 @@ class _LoginPageState extends State { Container( width: double.infinity, padding: EdgeInsets.only( - top: 0.1.sh, + top: 0.07.sh, left: 20, right: 20, ), @@ -203,15 +258,17 @@ class _LoginPageState extends State { title: "Continue with Google", icon: "assets/image/google.png", onTap: () { - _handleSignIn(); + _handleGoogleSignIn(); }, ), SizedBox(height: 15), - // OtherButton( - // title: "Continue with Apple", - // icon: "assets/image/apple.png", - // onTap: () {}, - // ), + OtherButton( + title: "Continue with Apple", + icon: "assets/image/apple.png", + onTap: () { + _handAppleSignIn(); + }, + ), ], ), ), diff --git a/lib/page/system/login/widget/agreement_box.dart b/lib/page/system/login/widget/agreement_box.dart index 417c53d..20665f2 100644 --- a/lib/page/system/login/widget/agreement_box.dart +++ b/lib/page/system/login/widget/agreement_box.dart @@ -36,37 +36,26 @@ class AgreementBox extends StatelessWidget { style: Theme.of(context).textTheme.labelSmall, children: [ TextSpan( - text: "我已阅读并同意", - recognizer: TapGestureRecognizer() - ..onTap = () { - onChanged(!checked); - }, + text: "I agree to the ", ), TextSpan( - text: "《用户协议》", - style: TextStyle( - color: Theme.of(context).primaryColor, - ), + text: "Terms", + style: TextStyle(color: Theme.of(context).primaryColor), recognizer: TapGestureRecognizer() - ..onTap = () { - context.push( - RoutePaths.agreement, - extra: {"title": "用户协议", "url": "https://keyang2.tuzuu.com/ak-health/agreement/user_agreement.html"}, - ); - }, + ..onTap = () => context.push( + RoutePaths.agreement, + extra: {"title": "Terms of Service", "url": "https://support.curain.ai/privacy/derma/terms_service.html"}, + ), ), + TextSpan(text: " & "), TextSpan( - text: "《隐私协议》", - style: TextStyle( - color: Theme.of(context).primaryColor, - ), + text: "Privacy Policy", + style: TextStyle(color: Theme.of(context).primaryColor), recognizer: TapGestureRecognizer() - ..onTap = () { - context.push( - RoutePaths.agreement, - extra: {"title": "隐私政策", "url": "https://keyang2.tuzuu.com/ak-health/agreement/privacy_policy.html"}, - ); - }, + ..onTap = () => context.push( + RoutePaths.agreement, + extra: {"title": "Privacy", "url": "https://support.curain.ai/privacy/derma/privacy_policy.html"}, + ), ), ], ), diff --git a/lib/page/system/login/widget/widget.dart b/lib/page/system/login/widget/widget.dart index c93ea33..5ae3810 100644 --- a/lib/page/system/login/widget/widget.dart +++ b/lib/page/system/login/widget/widget.dart @@ -7,7 +7,7 @@ class LogoBox extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - margin: EdgeInsets.only(bottom: 60), + margin: EdgeInsets.only(bottom: 40), child: Column( children: [ Image.asset( diff --git a/lib/utils/common.dart b/lib/utils/common.dart new file mode 100644 index 0000000..a93925d --- /dev/null +++ b/lib/utils/common.dart @@ -0,0 +1,6 @@ +import 'dart:io'; + +///判断是否是安卓 +bool isAndroid(){ + return Platform.isAndroid; +} \ No newline at end of file diff --git a/privacy_policy.html b/privacy_policy.html new file mode 100644 index 0000000..4feeb05 --- /dev/null +++ b/privacy_policy.html @@ -0,0 +1,45 @@ + + + + + + Demacare Privacy Policy + + +

Demacare Privacy Policy

+

Effective Date: [Insert Date]

+ +

At Demacare, we value your privacy. This privacy policy outlines how we collect, use, and protect your personal data.

+ +

1. Information We Collect

+

We collect personal information such as:

+
    +
  • Photos you upload for skin analysis
  • +
  • Device information
  • +
  • Usage data (such as features used and app performance)
  • +
+ +

2. How We Use Your Data

+

Your data is used to:

+
    +
  • Provide skin analysis and personalized recommendations
  • +
  • Improve the app's performance and functionality
  • +
  • Send notifications or updates related to our services
  • +
+ +

3. Data Storage and Security

+

We store your data securely and take appropriate measures to protect it from unauthorized access. However, no method of transmission over the internet is 100% secure.

+ +

4. Sharing Your Data

+

We do not share your personal data with third parties except when required by law or to provide essential services such as app functionality or customer support.

+ +

5. Your Rights

+

You have the right to access, update, or delete your personal data. You may also withdraw your consent for data collection at any time by contacting us.

+ +

6. Changes to Privacy Policy

+

We may update this Privacy Policy from time to time. Changes will be posted in this document with the date of the most recent update.

+ +

7. Contact Us

+

If you have any questions or concerns about your privacy, please contact us at: [Insert Contact Information]

+ + diff --git a/pubspec.lock b/pubspec.lock index cc97006..1e852d6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -600,6 +600,30 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.4.1" + sign_in_with_apple: + dependency: "direct main" + description: + name: sign_in_with_apple + sha256: "8bd875c8e8748272749eb6d25b896f768e7e9d60988446d543fe85a37a2392b8" + url: "https://pub.flutter-io.cn" + source: hosted + version: "7.0.1" + sign_in_with_apple_platform_interface: + dependency: transitive + description: + name: sign_in_with_apple_platform_interface + sha256: "981bca52cf3bb9c3ad7ef44aace2d543e5c468bb713fd8dda4275ff76dfa6659" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.0" + sign_in_with_apple_web: + dependency: transitive + description: + name: sign_in_with_apple_web + sha256: f316400827f52cafcf50d00e1a2e8a0abc534ca1264e856a81c5f06bd5b10fed + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.0" skeletonizer: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 811e6ab..cf3d286 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,6 +26,7 @@ dependencies: file_picker: ^10.3.2 image_picker: ^1.2.0 markdown_widget: ^2.3.2+8 + sign_in_with_apple: ^7.0.1 dev_dependencies: diff --git a/terms_service.html b/terms_service.html new file mode 100644 index 0000000..a44a510 --- /dev/null +++ b/terms_service.html @@ -0,0 +1,35 @@ + + + + + + Demacare Terms of Service + + +

Demacare Terms of Service

+

Effective Date: [Insert Date]

+ +

Welcome to Demacare! By using our app, you agree to the following Terms of Service:

+ +

1. Acceptance of Terms

+

By accessing or using Demacare, you agree to be bound by these terms and conditions. If you do not agree, you should not use our app.

+ +

2. Services Provided

+

Demacare allows users to analyze their skin by taking photos and receiving skin care recommendations. The app may also provide access to additional features such as health tips or product recommendations.

+ +

3. Privacy and Data Collection

+

We take your privacy seriously. Please review our Privacy Policy to understand how we collect, use, and protect your personal information.

+ +

4. User Responsibilities

+

You are responsible for all activities associated with your account. You agree not to misuse the app or use it for illegal activities.

+ +

5. Limitation of Liability

+

Demacare is not responsible for any damage to your device or loss of data. We do not guarantee that our app will always be error-free or available.

+ +

6. Changes to Terms

+

We may update these terms from time to time. All changes will be reflected in this document, and the date of the most recent update will be provided at the top.

+ +

7. Contact Us

+

If you have any questions about these terms, please contact us at: [Insert Contact Information]

+ +