Browse Source

第一次提交

liukai 8 months ago
commit
282a0de278
100 changed files with 3442 additions and 0 deletions
  1. 31 0
      .gitignore
  2. 10 0
      .metadata
  3. 2 0
      README.md
  4. 29 0
      analysis_options.yaml
  5. 78 0
      app/.gitignore
  6. 13 0
      app/android/.gitignore
  7. 124 0
      app/android/app/build.gradle
  8. 159 0
      app/android/app/proguard-rules.pro
  9. 149 0
      app/android/app/src/main/AndroidManifest.xml
  10. 86 0
      app/android/app/src/main/kotlin/com/hongyegroup/hotelbusiness/MainActivity.java
  11. 13 0
      app/android/app/src/main/kotlin/com/hongyegroup/hotelbusiness/MyApplication.kt
  12. 48 0
      app/android/app/src/main/kotlin/com/hongyegroup/hotelbusiness/RouterActivity.java
  13. BIN
      app/android/app/src/main/res/drawable-hdpi/back.png
  14. 12 0
      app/android/app/src/main/res/drawable-v21/launch_background.xml
  15. BIN
      app/android/app/src/main/res/drawable-xhdpi/back.png
  16. BIN
      app/android/app/src/main/res/drawable-xhdpi/check_image.png
  17. BIN
      app/android/app/src/main/res/drawable-xhdpi/login_btn_normal.png
  18. BIN
      app/android/app/src/main/res/drawable-xhdpi/login_logo_icon.png
  19. BIN
      app/android/app/src/main/res/drawable-xhdpi/logo.png
  20. BIN
      app/android/app/src/main/res/drawable-xhdpi/uncheck_image.png
  21. BIN
      app/android/app/src/main/res/drawable-xxhdpi/back.png
  22. BIN
      app/android/app/src/main/res/drawable-xxhdpi/login_logo_icon.png
  23. BIN
      app/android/app/src/main/res/drawable-xxxhdpi/login_logo_icon.png
  24. 11 0
      app/android/app/src/main/res/drawable/launch_background.xml
  25. BIN
      app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  26. BIN
      app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
  27. BIN
      app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  28. BIN
      app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
  29. BIN
      app/android/app/src/main/res/mipmap-xhdpi/launch_image.png
  30. BIN
      app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  31. BIN
      app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
  32. 20 0
      app/android/app/src/main/res/values-night/styles.xml
  33. 13 0
      app/android/app/src/main/res/values-v31/styles.xml
  34. 19 0
      app/android/app/src/main/res/values/styles.xml
  35. 9 0
      app/android/app/src/main/res/xml/network_security_config.xml
  36. 46 0
      app/android/build.gradle
  37. 4 0
      app/android/gradle.properties
  38. 6 0
      app/android/gradle/wrapper/gradle-wrapper.properties
  39. 4 0
      app/android/key.properties
  40. BIN
      app/android/key/flutterroom.jks
  41. 11 0
      app/android/settings.gradle
  42. 34 0
      app/ios/.gitignore
  43. 26 0
      app/ios/Flutter/AppFrameworkInfo.plist
  44. 2 0
      app/ios/Flutter/Debug.xcconfig
  45. 2 0
      app/ios/Flutter/Release.xcconfig
  46. 10 0
      app/ios/Gemfile
  47. 86 0
      app/ios/Podfile
  48. 567 0
      app/ios/Runner.xcodeproj/project.pbxproj
  49. 7 0
      app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  50. 8 0
      app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  51. 8 0
      app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  52. 87 0
      app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  53. 10 0
      app/ios/Runner.xcworkspace/contents.xcworkspacedata
  54. 8 0
      app/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  55. 8 0
      app/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  56. 114 0
      app/ios/Runner/AppDelegate.swift
  57. 14 0
      app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
  58. BIN
      app/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-1024.png
  59. 6 0
      app/ios/Runner/Assets.xcassets/Contents.json
  60. 21 0
      app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
  61. BIN
      app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LOGO@3x.png
  62. 5 0
      app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
  63. 22 0
      app/ios/Runner/Assets.xcassets/back.imageset/Contents.json
  64. BIN
      app/ios/Runner/Assets.xcassets/back.imageset/back 1.png
  65. BIN
      app/ios/Runner/Assets.xcassets/back.imageset/back.png
  66. 21 0
      app/ios/Runner/Assets.xcassets/check_image.imageset/Contents.json
  67. BIN
      app/ios/Runner/Assets.xcassets/check_image.imageset/check_image.png
  68. 21 0
      app/ios/Runner/Assets.xcassets/login_btn_normal.imageset/Contents.json
  69. BIN
      app/ios/Runner/Assets.xcassets/login_btn_normal.imageset/login_btn_normal.png
  70. 21 0
      app/ios/Runner/Assets.xcassets/logo.imageset/Contents.json
  71. BIN
      app/ios/Runner/Assets.xcassets/logo.imageset/logo.png
  72. 21 0
      app/ios/Runner/Assets.xcassets/uncheck_image.imageset/Contents.json
  73. BIN
      app/ios/Runner/Assets.xcassets/uncheck_image.imageset/uncheck_image.png
  74. 39 0
      app/ios/Runner/Base.lproj/LaunchScreen.storyboard
  75. 26 0
      app/ios/Runner/Base.lproj/Main.storyboard
  76. 101 0
      app/ios/Runner/Info.plist
  77. 1 0
      app/ios/Runner/Runner-Bridging-Header.h
  78. 18 0
      app/ios/Runner/Runner.entitlements
  79. 11 0
      app/ios/apple-app-site-association.plist
  80. 6 0
      app/ios/fastlane/Appfile
  81. 54 0
      app/ios/fastlane/Fastfile
  82. 6 0
      app/ios/fastlane/Pluginfile
  83. 32 0
      app/ios/fastlane/README.md
  84. 28 0
      app/ios/fastlane/report.xml
  85. 26 0
      app/lib/app_binding.dart
  86. 88 0
      app/lib/jpush/jpush_receive.dart
  87. 179 0
      app/lib/main.dart
  88. 16 0
      app/lib/modules/main/main_controller.dart
  89. 199 0
      app/lib/modules/main/main_page.dart
  90. 5 0
      app/lib/modules/main/main_state.dart
  91. 117 0
      app/lib/modules/splash/splash_controller.dart
  92. 37 0
      app/lib/modules/splash/splash_page.dart
  93. 27 0
      app/lib/router/page_router.dart
  94. 75 0
      app/pubspec.yaml
  95. 11 0
      app/test/widget_test.dart
  96. 28 0
      app/web/index.html
  97. 51 0
      melos.yaml
  98. 31 0
      packages/cpt_profile/.gitignore
  99. 204 0
      packages/cpt_profile/lib/modules/me/change_mobile/change_mobile_controller.dart
  100. 0 0
      packages/cpt_profile/lib/modules/me/change_mobile/change_mobile_page.dart

+ 31 - 0
.gitignore

@@ -0,0 +1,31 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+*.lock
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# Visual Studio Code related
+.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+proguardMapping.txt

+ 10 - 0
.metadata

@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+  revision: c860cba910319332564e1e9d470a17074c1f2dfd
+  channel: beta
+
+project_type: app

+ 2 - 0
README.md

@@ -0,0 +1,2 @@
+酒店管理系统移动端
+

+ 29 - 0
analysis_options.yaml

@@ -0,0 +1,29 @@
+# This file configures the analyzer, which statically analyzes Dart code to
+# check for errors, warnings, and lints.
+#
+# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
+# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
+# invoked from the command line by running `flutter analyze`.
+
+# The following line activates a set of recommended lints for Flutter apps,
+# packages, and plugins designed to encourage good coding practices.
+include: package:flutter_lints/flutter.yaml
+
+linter:
+  # The lint rules applied to this project can be customized in the
+  # section below to disable rules from the `package:flutter_lints/flutter.yaml`
+  # included above or to enable additional rules. A list of all available lints
+  # and their documentation is published at
+  # https://dart-lang.github.io/linter/lints/index.html.
+  #
+  # Instead of disabling a lint rule for the entire project in the
+  # section below, it can also be suppressed for a single line of code
+  # or a specific dart file by using the `// ignore: name_of_lint` and
+  # `// ignore_for_file: name_of_lint` syntax on the line or in the file
+  # producing the lint.
+  rules:
+    # avoid_print: false  # Uncomment to disable the `avoid_print` rule
+    # prefer_single_quotes: true  # Uncomment to enable the `prefer_single_quotes` rule
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options

+ 78 - 0
app/.gitignore

@@ -0,0 +1,78 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+*.lock
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# Visual Studio Code related
+.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+proguardMapping.txt
+
+# Android related
+**/android/**/gradle-wrapper.jar
+**/android/.gradle
+**/android/captures/
+**/android/gradlew
+**/android/gradlew.bat
+**/android/local.properties
+**/android/**/GeneratedPluginRegistrant.java
+
+# iOS/XCode related
+**/ios/**/*.mode1v3
+**/ios/**/*.mode2v3
+**/ios/**/*.moved-aside
+**/ios/**/*.pbxuser
+**/ios/**/*.perspectivev3
+**/ios/**/*sync/
+**/ios/**/.sconsign.dblite
+**/ios/**/.tags*
+**/ios/**/.vagrant/
+**/ios/**/DerivedData/
+**/ios/**/Icon?
+**/ios/**/Pods/
+**/ios/**/.symlinks/
+**/ios/**/profile
+**/ios/**/xcuserdata
+**/ios/.generated/
+**/ios/Flutter/App.framework
+**/ios/Flutter/Flutter.framework
+**/ios/Flutter/Generated.xcconfig
+**/ios/Flutter/app.flx
+**/ios/Flutter/app.zip
+**/ios/Flutter/flutter_assets/
+**/ios/ServiceDefinitions.json
+**/ios/Runner/GeneratedPluginRegistrant.*
+**/ios/Flutter/flutter_export_environment.sh
+**/ios/Flutter/.last_build_id
+
+# Web related
+
+# Exceptions to above rules.
+!**/ios/**/default.mode1v3
+!**/ios/**/default.mode2v3
+!**/ios/**/default.pbxuser
+!**/ios/**/default.perspectivev3
+!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
+/ios/build/

+ 13 - 0
app/android/.gitignore

@@ -0,0 +1,13 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+#key.properties
+#**/*.keystore
+#**/*.jks

+ 124 - 0
app/android/app/build.gradle

@@ -0,0 +1,124 @@
+def keystoreProperties = new Properties()
+def keystorePropertiesFile = rootProject.file('key.properties')
+if (keystorePropertiesFile.exists()) {
+    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
+}
+
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+    localPropertiesFile.withReader('UTF-8') { reader ->
+        localProperties.load(reader)
+    }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+    throw new Exception("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+// 模拟器运行报错时尝试开启此项
+// project.setProperty('target-platform', 'android-arm')
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-kapt'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+    compileSdkVersion 34
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_11
+        targetCompatibility JavaVersion.VERSION_11
+    }
+
+    kotlinOptions {
+        jvmTarget = JavaVersion.VERSION_11
+    }
+
+    sourceSets {
+        main.java.srcDirs += 'src/main/kotlin'
+    }
+
+    lintOptions {
+        // 如打包出现Failed to transform libs.jar to match attributes
+        checkReleaseBuilds false
+    }
+
+    defaultConfig {
+        applicationId "com.hongyegroup.hotelbusiness"
+        minSdkVersion 21
+        targetSdkVersion 33
+        versionCode 100          //Android打包上线记得要加固并重新签名再传
+        versionName "1.0.0"
+
+        multiDexEnabled true
+
+        ndk {
+            //选择要添加的对应 cpu 类型的 .so 库。
+//            abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
+            abiFilters 'armeabi-v7a', 'arm64-v8a'
+//            abiFilters 'armeabi-v7a'
+//            abiFilters 'arm64-v8a'
+        }
+
+        manifestPlaceholders = [
+                JPUSH_PKGNAME   : applicationId,
+                JPUSH_APPKEY    : "1234567890",
+                JPUSH_CHANNEL   : "developer-default",
+                queryAllPackages: ""
+        ]
+    }
+
+    //配置keystore签名
+    signingConfigs {
+        release {
+            keyAlias keystoreProperties['keyAlias']
+            keyPassword keystoreProperties['keyPassword']
+            storeFile file(keystoreProperties['storeFile'])
+            storePassword keystoreProperties['storePassword']
+        }
+        debug {
+
+        }
+    }
+
+    buildTypes {
+        release {
+            signingConfig signingConfigs.release
+            //默认系统混淆
+            minifyEnabled true
+            // 不显示Log
+            buildConfigField "boolean", "LOG_DEBUG", "false"
+            //是否可调试
+            debuggable false
+            //Zipalign优化
+            zipAlignEnabled true
+            //移除无用的resource文件
+            shrinkResources true
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+        debug {
+            signingConfig signingConfigs.release
+            //是否可调试
+            debuggable true
+        }
+    }
+}
+
+flutter {
+    source '../..'
+}
+
+dependencies {
+    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
+
+    implementation 'com.github.bumptech.glide:glide:4.11.0'
+    kapt 'com.github.bumptech.glide:compiler:4.11.0'
+
+    implementation 'com.android.support:multidex:1.0.3'
+
+//    implementation 'androidx.core:core-splashscreen:1.0.0' //启动12兼容
+}

+ 159 - 0
app/android/app/proguard-rules.pro

@@ -0,0 +1,159 @@
+
+#---------------------------------基本指令区----------------------------------
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontskipnonpubliclibraryclassmembers
+-dontpreverify
+-verbose
+-printmapping proguardMapping.txt
+-optimizations !code/simplification/cast,!field/*,!class/merging/*
+-keepattributes *Annotation*,InnerClasses
+-keepattributes Signature
+-keepattributes SourceFile,LineNumberTable
+
+-printmapping proguardMapping.txt
+-optimizations !code/simplification/cast,!field/*,!class/merging/*
+-keepattributes *Annotation*,InnerClasses
+-keepattributes Signature
+-keepattributes SourceFile,LineNumberTable
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class * extends android.view.View
+-keep public class com.android.vending.licensing.ILicensingService
+-keep class android.support.** {*;}
+-keep public class * extends android.view.View{
+*** get*();
+void set*(***);
+public <init>(android.content.Context);
+public <init>(android.content.Context, android.util.AttributeSet);
+public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+-keepclasseswithmembers class * {
+public <init>(android.content.Context, android.util.AttributeSet);
+public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+-keepclassmembers class * implements java.io.Serializable {
+static final long serialVersionUID;
+private static final java.io.ObjectStreamField[] serialPersistentFields;
+private void writeObject(java.io.ObjectOutputStream);
+private void readObject(java.io.ObjectInputStream);
+java.lang.Object writeReplace();
+java.lang.Object readResolve();
+}
+-keep class **.R$* {
+*;
+}
+-keepclassmembers class * {
+void *(**On*Event);
+}
+-keepclassmembers class fqcn.of.javascript.interface.for.Webview {
+public *;
+}
+-keepclassmembers class * extends android.webkit.WebViewClient {
+public void *(android.webkit.WebView, java.lang.String,
+android.graphics.Bitmap);
+public boolean *(android.webkit.WebView, java.lang.String);
+}
+-keepclassmembers class * extends android.webkit.WebViewClient {
+public void *(android.webkit.WebView, jav.lang.String);
+}
+
+#---------------------------------默认保留区---------------------------------
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class * extends android.view.View
+-keep class android.support.** {*;}
+-keepclasseswithmembernames class * {
+    native <methods>;
+}
+-keepclassmembers class * extends android.app.Activity{
+    public void *(android.view.View);
+}
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+-keep public class * extends android.view.View{
+    *** get*();
+    void set*(***);
+    public <init>(android.content.Context);
+    public <init>(android.content.Context, android.util.AttributeSet);
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+-keepclasseswithmembers class * {
+    public <init>(android.content.Context, android.util.AttributeSet);
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+-keep class * implements android.os.Parcelable {
+  public static final android.os.Parcelable$Creator *;
+}
+-keepclassmembers class * implements java.io.Serializable {
+    static final long serialVersionUID;
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+    private void writeObject(java.io.ObjectOutputStream);
+    private void readObject(java.io.ObjectInputStream);
+    java.lang.Object writeReplace();
+    java.lang.Object readResolve();
+}
+
+-keep class android.support.** { *; }
+-keep interface android.support.** { *; }
+-keep class com.actionbarsherlock.** { *; }
+-keep interface com.actionbarsherlock.** { *; }
+-renamesourcefileattribute SourceFile
+
+-keep class **.R$* {
+ *;
+}
+
+-ignorewarnings
+
+-keep class * {
+    public private *;
+}
+
+-keepclassmembers class * {
+    void *(**On*Event);
+}
+
+-dontwarn javax.annotation.**
+-dontwarn javax.inject.**
+
+
+-dontwarn com.google.**
+-keep class com.google.gson.** {*;}
+-keep class com.google.protobuf.** {*;}
+-keep class androidx.arch.core.** { *; }
+
+
+-keep class net.sqlcipher.** { *; }
+-keep class net.sqlcipher.database.** { *; }
+-keep class io.flutter.app.** { *; }
+-keep class io.flutter.plugin.**  { *; }
+-keep class io.flutter.util.**  { *; }
+-keep class io.flutter.view.**  { *; }
+-keep class io.flutter.**  { *; }
+-keep class io.flutter.plugins.**  { *; }
+
+#==================其他==========================
+
+#极光推送
+-dontoptimize
+-dontpreverify
+-dontwarn cn.jpush.**
+-keep class cn.jpush.** { *; }
+
+
+

+ 149 - 0
app/android/app/src/main/AndroidManifest.xml

@@ -0,0 +1,149 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.hongyegroup.hotelbusiness">
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
+    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+<!--    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />-->
+
+    <!-- Provide required visibility configuration for API level 30 and above -->
+    <queries>
+        <intent>
+            <action android:name="android.intent.action.VIEW" />
+            <data android:scheme="lehuoer" />
+        </intent>
+        <intent>
+            <action android:name="android.intent.action.VIEW" />
+            <data android:scheme="https" />
+        </intent>
+        <intent>
+            <action android:name="android.intent.action.DIAL" />
+            <data android:scheme="tel" />
+        </intent>
+        <intent>
+            <action android:name="android.intent.action.SENDTO" />
+            <data android:scheme="smsto" />
+        </intent>
+        <intent>
+            <action android:name="android.intent.action.SEND" />
+            <data android:mimeType="*/*" />
+        </intent>
+    </queries>
+
+    <application
+        android:name=".MyApplication"
+        android:allowBackup="false"
+        android:icon="@mipmap/ic_launcher"
+        android:label="YYBusiness-ER"
+        android:networkSecurityConfig="@xml/network_security_config"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:usesCleartextTraffic="true">
+
+        <activity
+            android:name="app.android.app.src.main.kotlin.com.hongyegroup.hotelbusiness.MainActivity"
+            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
+            android:exported="true"
+            android:hardwareAccelerated="true"
+            android:launchMode="singleTop"
+            android:theme="@style/LaunchTheme"
+            android:windowSoftInputMode="adjustResize">
+
+            <meta-data
+                android:name="io.flutter.embedding.android.NormalTheme"
+                android:resource="@style/NormalTheme" />
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+        </activity>
+
+        <!--        <activity-->
+        <!--            android:name=".RouterActivity"-->
+        <!--            android:exported="true"-->
+        <!--            android:launchMode="singleTop"-->
+        <!--            android:theme="@style/Theme.AppCompat.Light.NoActionBar">-->
+
+        <!--            <intent-filter>-->
+        <!--                <action android:name="android.intent.action.VIEW" />-->
+
+        <!--                <category android:name="android.intent.category.BROWSABLE" />-->
+        <!--                <category android:name="android.intent.category.DEFAULT" />-->
+
+        <!--                <data-->
+        <!--                    android:host="router"-->
+        <!--                    android:scheme="app" />-->
+        <!--            </intent-filter>-->
+
+        <!--        </activity>-->
+
+        <!--    UCrop图片裁剪    -->
+        <activity
+            android:exported="false"
+            android:name="com.yalantis.ucrop.UCropActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
+
+        <!-- Don't delete the meta-data below.
+             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
+        <meta-data
+            android:name="flutterEmbedding"
+            android:value="2" />
+
+        <!--    百度地图API-Key    -->
+        <meta-data
+            android:name="com.baidu.lbsapi.API_KEY"
+            android:value="STkWzGuoErywxby5BkfwiRlPwnCnDwxd" />
+
+        <!--9.0兼容http-->
+        <uses-library
+            android:name="org.apache.http.legacy"
+            android:required="false" />
+
+        <!--本项目mate配置-->
+        <meta-data
+            android:name="android.max_aspect"
+            android:value="2.5" />
+
+        <meta-data
+            android:name="android.webkit.WebView.EnableSafeBrowing"
+            android:value="true" />
+
+
+    </application>
+
+    <queries>
+        <intent>
+            <action android:name="android.intent.action.SEND" />
+            <data android:mimeType="image/jpeg" />
+        </intent>
+        <intent>
+            <action android:name="android.intent.action.SEND" />
+            <data android:mimeType="text/plain" />
+        </intent>
+    </queries>
+
+    <!-- Android 11 使用相机适配  -->
+    <queries package="com.monstarlab.yyjobs">
+        <intent>
+            <action android:name="android.media.action.IMAGE_CAPTURE">
+
+            </action>
+        </intent>
+        <intent>
+            <action android:name="android.media.action.ACTION_VIDEO_CAPTURE">
+
+            </action>
+        </intent>
+    </queries>
+
+</manifest>

+ 86 - 0
app/android/app/src/main/kotlin/com/hongyegroup/hotelbusiness/MainActivity.java

@@ -0,0 +1,86 @@
+package app.android.app.src.main.kotlin.com.hongyegroup.hotelbusiness;
+
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+//import androidx.core.splashscreen.SplashScreen;
+
+import io.flutter.embedding.android.FlutterActivity;
+import io.flutter.embedding.engine.FlutterEngine;
+import io.flutter.plugin.common.MethodChannel;
+
+public class MainActivity extends FlutterActivity {
+
+//    private SplashScreen mSplashScreen;
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+//        mSplashScreen = SplashScreen.installSplashScreen(this);
+//        mSplashScreen.setKeepOnScreenCondition(() -> true);
+
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
+        super.configureFlutterEngine(flutterEngine);
+
+        MethodChannel methodChannel = new MethodChannel(flutterEngine.getDartExecutor(), "com.room/opapp");
+
+        methodChannel.setMethodCallHandler((call, result) -> {
+            //检查人脸数量
+           if (call.method.equals("bringAppToForeground")) {
+                //启动MainActivity自己
+                Log.d("MainActivity", "执行 methodChannel -> bringAppToForeground");
+
+//                Intent intent = new Intent(this, MainActivity.class);
+//                intent.setAction(Intent.ACTION_MAIN);
+//                intent.addCategory(Intent.CATEGORY_LAUNCHER);
+//                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+//                intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+//                startActivity(intent);
+
+//                ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+//                List<ActivityManager.AppTask> appTasks = activityManager.getAppTasks();
+//                if (!appTasks.isEmpty()) {
+//                    appTasks.get(0).moveToFront();
+//                }
+
+//                PackageManager packageManager = getPackageManager();
+//                Intent intent = packageManager.getLaunchIntentForPackage("com.hongyegroup.zhurijob");
+//                if (intent != null) {
+//                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+//                    startActivity(intent);
+//                }
+
+            } else if (call.method.equals("getNativeRouterName")) {
+                // 获取当前需要跳转的子路由
+                Log.d("MainActivity", "执行 methodChannel -> getNativeRouterName");
+//                result.success(RouterActivity.ROUTER_NAME);
+                result.success("");
+
+            } else if (call.method.equals("clearNativeRouterName")) {
+                // 清除当前需要跳转的子路由
+                Log.d("MainActivity", "执行 methodChannel -> clearNativeRouterName");
+//                RouterActivity.ROUTER_NAME = "";
+                result.success(true);
+            } else if (call.method.equals("appleLogin")) {
+                // 苹果登录-Android空实现
+                result.success(null);
+            } else if (call.method.equals("skipAndroidSplashScreen")) {
+                // 跳过Android的SplashScreen
+                Log.d("MainActivity", "执行 methodChannel -> skipAndroidSplashScreen");
+//                if (mSplashScreen != null) {
+//                    mSplashScreen.setKeepOnScreenCondition(() -> false);
+//                }
+                result.success(true);
+            } else {
+                result.notImplemented();
+            }
+        });
+
+    }
+
+}

+ 13 - 0
app/android/app/src/main/kotlin/com/hongyegroup/hotelbusiness/MyApplication.kt

@@ -0,0 +1,13 @@
+package com.hongyegroup.hotelbusiness
+
+import android.content.Context
+import androidx.multidex.MultiDex
+import io.flutter.app.FlutterApplication
+
+class MyApplication : FlutterApplication() {
+
+    override fun attachBaseContext(base: Context?) {
+        super.attachBaseContext(base)
+        MultiDex.install(this)
+    }
+}

+ 48 - 0
app/android/app/src/main/kotlin/com/hongyegroup/hotelbusiness/RouterActivity.java

@@ -0,0 +1,48 @@
+//package com.hongyegroup.hotelbusiness;
+//
+//import android.app.Activity;
+//import android.content.Intent;
+//import android.net.Uri;
+//import android.os.Bundle;
+//import android.util.Log;
+//import android.view.WindowManager;
+//
+//import androidx.annotation.Nullable;
+//
+//public class RouterActivity extends Activity {
+//
+//    public static String ROUTER_NAME = "";
+//
+//    @Override
+//    protected void onCreate(@Nullable Bundle savedInstanceState) {
+//        super.onCreate(savedInstanceState);
+//
+//        // 设置Activity为1像素大小及透明背景
+//        WindowManager.LayoutParams params = getWindow().getAttributes();
+//        params.height = 1;
+//        params.width = 1;
+//        params.alpha = 0;
+//        getWindow().setAttributes(params);
+//
+//        // 接收传递的参数
+//        Bundle extras = getIntent().getExtras();
+//        if (extras != null && extras.containsKey("name")) {
+//            String name = extras.getString("name");
+//            Log.w("RouterActivity","RouterActivity Bundle拿到路由名称参数为: " + name);
+//            ROUTER_NAME = name;
+//        }
+//
+//        Intent intent = getIntent();
+//        if (intent != null && intent.getData() != null) {
+//            Uri uri = intent.getData();
+//            Log.w("RouterActivity","RouterActivity 拿到 Scheme Uri: " + uri);
+//            String name = uri.getQueryParameter("name");
+//            Log.w("RouterActivity","RouterActivity Uri拿到路由名称参数为: " + name);
+//            ROUTER_NAME = name;
+//        }
+//
+//        // 关闭Activity
+//        finish();
+//
+//    }
+//}

BIN
app/android/app/src/main/res/drawable-hdpi/back.png


+ 12 - 0
app/android/app/src/main/res/drawable-v21/launch_background.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Modify this file to customize your launch splash screen -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="?android:colorBackground" />
+
+    <!-- You can insert your own image assets here -->
+     <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@mipmap/launch_image" />
+    </item>
+</layer-list>

BIN
app/android/app/src/main/res/drawable-xhdpi/back.png


BIN
app/android/app/src/main/res/drawable-xhdpi/check_image.png


BIN
app/android/app/src/main/res/drawable-xhdpi/login_btn_normal.png


BIN
app/android/app/src/main/res/drawable-xhdpi/login_logo_icon.png


BIN
app/android/app/src/main/res/drawable-xhdpi/logo.png


BIN
app/android/app/src/main/res/drawable-xhdpi/uncheck_image.png


BIN
app/android/app/src/main/res/drawable-xxhdpi/back.png


BIN
app/android/app/src/main/res/drawable-xxhdpi/login_logo_icon.png


BIN
app/android/app/src/main/res/drawable-xxxhdpi/login_logo_icon.png


+ 11 - 0
app/android/app/src/main/res/drawable/launch_background.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Modify this file to customize your launch splash screen -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@android:color/white" />
+
+    <!-- You can insert your own image assets here -->
+    <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@mipmap/launch_image" />
+    </item>
+</layer-list>

BIN
app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png


BIN
app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png


BIN
app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png


BIN
app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png


BIN
app/android/app/src/main/res/mipmap-xhdpi/launch_image.png


BIN
app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png


BIN
app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png


+ 20 - 0
app/android/app/src/main/res/values-night/styles.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
+    <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
+        <!-- Show a splash screen on the activity. Automatically removed when
+             Flutter draws its first frame -->
+        <item name="android:windowBackground">@drawable/launch_background</item>
+    </style>
+    <!-- Theme applied to the Android Window as soon as the process has started.
+         This theme determines the color of the Android Window while your
+         Flutter UI initializes, as well as behind your Flutter UI while its
+         running.
+
+         This Theme is only used starting with V2 of Flutter's Android embedding. -->
+    <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
+        <item name="android:windowBackground">?android:colorBackground</item>
+    </style>
+
+
+</resources>

+ 13 - 0
app/android/app/src/main/res/values-v31/styles.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <!-- Android 12 SplashScreen  -->
+<!--    <style name="LaunchTheme" parent="Theme.SplashScreen">-->
+<!--        <item name="windowSplashScreenBackground">@android:color/white</item>-->
+<!--        <item name="windowSplashScreenAnimatedIcon">@drawable/login_logo_icon</item>-->
+<!--&lt;!&ndash;        <item name="windowSplashScreenAnimationDuration">1000</item>&ndash;&gt;-->
+<!--        <item name="postSplashScreenTheme">@style/NormalTheme</item>-->
+<!--        &lt;!&ndash;        <item name="android:windowSplashScreenBehavior">icon_preferred</item>&ndash;&gt;-->
+<!--    </style>-->
+
+</resources>

+ 19 - 0
app/android/app/src/main/res/values/styles.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
+    <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
+        <!-- Show a splash screen on the activity. Automatically removed when
+             Flutter draws its first frame -->
+        <item name="android:windowBackground">@drawable/launch_background</item>
+    </style>
+    <!-- Theme applied to the Android Window as soon as the process has started.
+         This theme determines the color of the Android Window while your
+         Flutter UI initializes, as well as behind your Flutter UI while its
+         running.
+
+         This Theme is only used starting with V2 of Flutter's Android embedding. -->
+    <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
+        <item name="android:windowBackground">?android:colorBackground</item>
+    </style>
+
+</resources>

+ 9 - 0
app/android/app/src/main/res/xml/network_security_config.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <!--允许使用http进行网络请求-->
+    <base-config cleartextTrafficPermitted="true" >
+        <trust-anchors>
+            <certificates src="system" />
+        </trust-anchors>
+    </base-config>
+</network-security-config>

+ 46 - 0
app/android/build.gradle

@@ -0,0 +1,46 @@
+
+buildscript {
+    ext.kotlin_version = '1.8.0'
+    repositories {
+//        maven { url 'https://maven.aliyun.com/repository/public' }//jcenter
+//        maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }//gradle-plugin
+//        maven { url 'https://maven.aliyun.com/repository/central' }//central
+//        maven { url 'https://maven.aliyun.com/repository/google' }//google
+//        maven { url 'https://maven.aliyun.com/repository/jcenter' }
+//        maven { url 'https://maven.aliyun.com/nexus/content/groups/public'}
+        google()
+        mavenCentral()
+        maven { url 'https://jitpack.io' }
+    }
+
+    dependencies {
+        classpath 'com.android.tools.build:gradle:7.1.2'
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+    }
+}
+
+allprojects {
+    repositories {
+//        maven { url 'https://maven.aliyun.com/repository/public' }
+//        maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
+//        maven { url 'https://maven.aliyun.com/repository/central' }
+//        maven { url 'https://maven.aliyun.com/repository/google' }
+//        maven { url 'https://maven.aliyun.com/repository/jcenter' }
+//        maven { url 'https://maven.aliyun.com/nexus/content/groups/public'}
+        google()
+        mavenCentral()
+        maven { url 'https://jitpack.io' }
+    }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+    project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+    project.evaluationDependsOn(':app')
+}
+
+tasks.register("clean", Delete) {
+    delete rootProject.buildDir
+}

+ 4 - 0
app/android/gradle.properties

@@ -0,0 +1,4 @@
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
+maven={ url 'https://maven.aliyun.com/repository/public' }

+ 6 - 0
app/android/gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Sun Jan 24 20:08:12 CST 2021
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME

+ 4 - 0
app/android/key.properties

@@ -0,0 +1,4 @@
+storeFile=../key/flutterroom.jks
+storePassword=123456
+keyAlias=guadou
+keyPassword=123456

BIN
app/android/key/flutterroom.jks


+ 11 - 0
app/android/settings.gradle

@@ -0,0 +1,11 @@
+include ':app'
+
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
+
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
+
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"

+ 34 - 0
app/ios/.gitignore

@@ -0,0 +1,34 @@
+**/dgph
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/ephemeral/
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3

+ 26 - 0
app/ios/Flutter/AppFrameworkInfo.plist

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>App</string>
+	<key>CFBundleIdentifier</key>
+	<string>io.flutter.flutter.app</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>App</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>MinimumOSVersion</key>
+	<string>12.0</string>
+</dict>
+</plist>

+ 2 - 0
app/ios/Flutter/Debug.xcconfig

@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "Generated.xcconfig"

+ 2 - 0
app/ios/Flutter/Release.xcconfig

@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "Generated.xcconfig"

+ 10 - 0
app/ios/Gemfile

@@ -0,0 +1,10 @@
+# Autogenerated by fastlane
+#
+# Ensure this file is checked in to source control!
+
+source "https://rubygems.org"
+
+gem 'fastlane'
+
+plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
+eval_gemfile(plugins_path) if File.exist?(plugins_path)

+ 86 - 0
app/ios/Podfile

@@ -0,0 +1,86 @@
+# 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!
+  use_modular_headers!
+  
+  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+end
+
+$iOSVersion = '12.0'
+
+post_install do |installer|
+  
+  
+  installer.pods_project.targets.each do |target|
+    flutter_additional_ios_build_settings(target)
+    
+    # Start of the permission_handler configuration
+    target.build_configurations.each do |config|
+      
+      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
+      '$(inherited)',
+      
+      
+      ## dart: PermissionGroup.camera
+      'PERMISSION_CAMERA=1',
+      
+      
+      ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
+      'PERMISSION_LOCATION=1',
+      
+      ]
+    end
+    
+    
+    installer.pods_project.build_configurations.each do |config|
+      config.build_settings["EXCLUDED_ARCHS[sdk=*]"] = "armv7"
+      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = $iOSVersion
+    end
+    
+    installer.pods_project.targets.each do |target|
+      flutter_additional_ios_build_settings(target)
+      
+      # add these lines:
+      target.build_configurations.each do |config|
+        if Gem::Version.new($iOSVersion) > Gem::Version.new(config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'])
+          config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = $iOSVersion
+        end
+      end
+      
+    end
+    
+    
+  end
+  
+  
+  
+end

+ 567 - 0
app/ios/Runner.xcodeproj/project.pbxproj

@@ -0,0 +1,567 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 54;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+		27DBCD0F7C9EBFC0F6BE4B99 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 170B930EF1FAA0602CCBFC69 /* Pods_Runner.framework */; };
+		3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+		74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
+		77F6D3242AE26F2C006D74CD /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77F6D3222AE26F25006D74CD /* AuthenticationServices.framework */; };
+		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 */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
+		1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
+		170B930EF1FAA0602CCBFC69 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		1BEC344927FDA4FD1E70B590 /* 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 = "<group>"; };
+		3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
+		3E1E524A98C4C35F938991E4 /* 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 = "<group>"; };
+		74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
+		74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
+		776500082ABD7998008C323B /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
+		77F6D3222AE26F25006D74CD /* AuthenticationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AuthenticationServices.framework; path = System/Library/Frameworks/AuthenticationServices.framework; sourceTree = SDKROOT; };
+		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
+		9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
+		9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
+		97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+		97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+		97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+		97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		C710FA3786AA4068C6F89E86 /* 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 = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		97C146EB1CF9000F007C117D /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				77F6D3242AE26F2C006D74CD /* AuthenticationServices.framework in Frameworks */,
+				27DBCD0F7C9EBFC0F6BE4B99 /* Pods_Runner.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		2413C548AABC2ABBFAD6F321 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				77F6D3222AE26F25006D74CD /* AuthenticationServices.framework */,
+				170B930EF1FAA0602CCBFC69 /* Pods_Runner.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		4B18F87853DC2A64DA973B87 /* Pods */ = {
+			isa = PBXGroup;
+			children = (
+				C710FA3786AA4068C6F89E86 /* Pods-Runner.debug.xcconfig */,
+				1BEC344927FDA4FD1E70B590 /* Pods-Runner.release.xcconfig */,
+				3E1E524A98C4C35F938991E4 /* Pods-Runner.profile.xcconfig */,
+			);
+			path = Pods;
+			sourceTree = "<group>";
+		};
+		9740EEB11CF90186004384FC /* Flutter */ = {
+			isa = PBXGroup;
+			children = (
+				3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+				9740EEB21CF90195004384FC /* Debug.xcconfig */,
+				7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+				9740EEB31CF90195004384FC /* Generated.xcconfig */,
+			);
+			name = Flutter;
+			sourceTree = "<group>";
+		};
+		97C146E51CF9000F007C117D = {
+			isa = PBXGroup;
+			children = (
+				9740EEB11CF90186004384FC /* Flutter */,
+				97C146F01CF9000F007C117D /* Runner */,
+				97C146EF1CF9000F007C117D /* Products */,
+				4B18F87853DC2A64DA973B87 /* Pods */,
+				2413C548AABC2ABBFAD6F321 /* Frameworks */,
+			);
+			sourceTree = "<group>";
+		};
+		97C146EF1CF9000F007C117D /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				97C146EE1CF9000F007C117D /* Runner.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		97C146F01CF9000F007C117D /* Runner */ = {
+			isa = PBXGroup;
+			children = (
+				776500082ABD7998008C323B /* Runner.entitlements */,
+				97C146FA1CF9000F007C117D /* Main.storyboard */,
+				97C146FD1CF9000F007C117D /* Assets.xcassets */,
+				97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+				97C147021CF9000F007C117D /* Info.plist */,
+				1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+				1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+				74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
+				74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
+			);
+			path = Runner;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		97C146ED1CF9000F007C117D /* Runner */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+			buildPhases = (
+				3105295E4DADBC89CA330491 /* [CP] Check Pods Manifest.lock */,
+				9740EEB61CF901F6004384FC /* Run Script */,
+				97C146EA1CF9000F007C117D /* Sources */,
+				97C146EB1CF9000F007C117D /* Frameworks */,
+				97C146EC1CF9000F007C117D /* Resources */,
+				3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+				F4664E1960AB5AF20D861E87 /* [CP] Embed Pods Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Runner;
+			productName = Runner;
+			productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		97C146E61CF9000F007C117D /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 1300;
+				ORGANIZATIONNAME = "";
+				TargetAttributes = {
+					97C146ED1CF9000F007C117D = {
+						CreatedOnToolsVersion = 7.3.1;
+						LastSwiftMigration = 1100;
+					};
+				};
+			};
+			buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+			compatibilityVersion = "Xcode 9.3";
+			developmentRegion = en;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = 97C146E51CF9000F007C117D;
+			productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				97C146ED1CF9000F007C117D /* Runner */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		97C146EC1CF9000F007C117D /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+				3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+				97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+				97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		3105295E4DADBC89CA330491 /* [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;
+		};
+		3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+			isa = PBXShellScriptBuildPhase;
+			alwaysOutOfDate = 1;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
+			);
+			name = "Thin Binary";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
+		};
+		9740EEB61CF901F6004384FC /* Run Script */ = {
+			isa = PBXShellScriptBuildPhase;
+			alwaysOutOfDate = 1;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Run Script";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+		};
+		F4664E1960AB5AF20D861E87 /* [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;
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		97C146EA1CF9000F007C117D /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+				1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+		97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				97C146FB1CF9000F007C117D /* Base */,
+			);
+			name = Main.storyboard;
+			sourceTree = "<group>";
+		};
+		97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				97C147001CF9000F007C117D /* Base */,
+			);
+			name = LaunchScreen.storyboard;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		249021D3217E4FDB00AE95B9 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = iphoneos;
+				SUPPORTED_PLATFORMS = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Profile;
+		};
+		249021D4217E4FDB00AE95B9 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
+				CURRENT_PROJECT_VERSION = 1;
+				DEVELOPMENT_TEAM = CW4J9W8LB6;
+				ENABLE_BITCODE = NO;
+				INFOPLIST_FILE = Runner/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				MARKETING_VERSION = 1.0.2;
+				PRODUCT_BUNDLE_IDENTIFIER = com.guadoutech.lehuoer;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+				SUPPORTS_MACCATALYST = NO;
+				SUPPORTS_MAC_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;
+		};
+		97C147031CF9000F007C117D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Debug;
+		};
+		97C147041CF9000F007C117D /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = iphoneos;
+				SUPPORTED_PLATFORMS = iphoneos;
+				SWIFT_COMPILATION_MODE = wholemodule;
+				SWIFT_OPTIMIZATION_LEVEL = "-O";
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
+		97C147061CF9000F007C117D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
+				CURRENT_PROJECT_VERSION = 1;
+				DEVELOPMENT_TEAM = CW4J9W8LB6;
+				ENABLE_BITCODE = NO;
+				INFOPLIST_FILE = Runner/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				MARKETING_VERSION = 1.0.2;
+				PRODUCT_BUNDLE_IDENTIFIER = com.guadoutech.lehuoer;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+				SUPPORTS_MACCATALYST = NO;
+				SUPPORTS_MAC_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;
+		};
+		97C147071CF9000F007C117D /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
+				CURRENT_PROJECT_VERSION = 1;
+				DEVELOPMENT_TEAM = CW4J9W8LB6;
+				ENABLE_BITCODE = NO;
+				INFOPLIST_FILE = Runner/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				MARKETING_VERSION = 1.0.2;
+				PRODUCT_BUNDLE_IDENTIFIER = com.guadoutech.lehuoer;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+				SUPPORTS_MACCATALYST = NO;
+				SUPPORTS_MAC_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;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				97C147031CF9000F007C117D /* Debug */,
+				97C147041CF9000F007C117D /* Release */,
+				249021D3217E4FDB00AE95B9 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				97C147061CF9000F007C117D /* Debug */,
+				97C147071CF9000F007C117D /* Release */,
+				249021D4217E4FDB00AE95B9 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}

+ 7 - 0
app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:">
+   </FileRef>
+</Workspace>

+ 8 - 0
app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>

+ 8 - 0
app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PreviewsEnabled</key>
+	<false/>
+</dict>
+</plist>

+ 87 - 0
app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1300"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+               BuildableName = "Runner.app"
+               BlueprintName = "Runner"
+               ReferencedContainer = "container:Runner.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+            BuildableName = "Runner.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+            BuildableName = "Runner.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Profile"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+            BuildableName = "Runner.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 10 - 0
app/ios/Runner.xcworkspace/contents.xcworkspacedata

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:Runner.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:Pods/Pods.xcodeproj">
+   </FileRef>
+</Workspace>

+ 8 - 0
app/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>

+ 8 - 0
app/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PreviewsEnabled</key>
+	<false/>
+</dict>
+</plist>

+ 114 - 0
app/ios/Runner/AppDelegate.swift

@@ -0,0 +1,114 @@
+import UIKit
+import AppTrackingTransparency
+import Flutter
+import AuthenticationServices
+
+@UIApplicationMain
+@objc class AppDelegate: FlutterAppDelegate {
+    
+    var channel:FlutterMethodChannel!
+    
+    var appleLoginResultBlock:((Dictionary<String, String>)->())!
+    
+  override func application(
+    _ application: UIApplication,
+    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+  ) -> Bool {
+      GeneratedPluginRegistrant.register(with: self)
+      self.initPlatformMethods()
+    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+  }
+    
+    override func applicationDidBecomeActive(_ application: UIApplication) {
+        if #available(iOS 14, *) {
+            ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
+                
+            })
+        }
+        UIApplication.shared.applicationIconBadgeNumber = 0;
+    }
+    
+    func initPlatformMethods(){
+        self.channel = FlutterMethodChannel.init(name: "com.room/opapp", binaryMessenger: self.window.rootViewController as! FlutterBinaryMessenger)
+        self.channel.setMethodCallHandler { call, result in
+            if (call.method == "checkFace"){
+                result(self.checkFace(path: call.arguments as! String));
+            }else if (call.method == "appleLogin"){
+                self.appleLogin()
+                self.appleLoginResultBlock = { dic in
+                    result(dic);
+                }
+                
+            }else if (call.method == "getNativeRouterName"){
+                result("");
+            }else if (call.method == "skipAndroidSplashScreen"){
+                result(true);
+            }
+        }
+    }
+    func checkFace(path:String) -> Int{
+        var image = CIImage.init(image: .init(contentsOfFile: path)!)
+        var detector = CIDetector.init(ofType: CIDetectorTypeFace, context: nil, options: [CIDetectorAccuracy:CIDetectorAccuracyHigh])
+        var features = detector!.features(in: image!);
+        return features.count;
+    }
+    
+    func appleLogin() {
+        if #available(iOS 13.0, *) {
+            let appleIDProvider = ASAuthorizationAppleIDProvider()
+            let request = appleIDProvider.createRequest()
+            request.requestedScopes = [.fullName, .email] // 可根据需求选择请求的范围
+            
+            let authorizationController = ASAuthorizationController(authorizationRequests: [request])
+            authorizationController.delegate = self
+            authorizationController.presentationContextProvider = self
+            authorizationController.performRequests()
+        } else {
+            // Fallback on earlier versions
+        }
+
+    }
+}
+
+@available(iOS 13.0, *)
+extension AppDelegate: ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
+    func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
+        return UIApplication.shared.windows.filter({ $0.isKeyWindow }).last!
+    }
+    
+    func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
+        if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
+            let identityToken = String.init(data: appleIDCredential.identityToken!, encoding: .utf8) ?? ""
+//            let authorizationCode = String.init(data: appleIDCredential.authorizationCode!, encoding: .utf8) ?? ""
+            self.appleLoginResultBlock(["identityToken":identityToken,"authorizationCode":appleIDCredential.user,"error":""])
+        }else{
+            self.appleLoginResultBlock(["error":"授权信息不符"]);
+        }
+    }
+    
+    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
+        // 处理登录错误
+//        self.appleLoginResultBlock(["error":error.localizedDescription])
+        
+        var msg = "未知错误,请稍后重试";
+        
+        switch error {
+        case ASAuthorizationError.unknown:
+            //未知错误
+            break;
+        case ASAuthorizationError.canceled:
+            //用户取消
+            msg = "";
+        case ASAuthorizationError.failed:
+            msg = "授权请求失败";
+        case ASAuthorizationError.invalidResponse:
+            msg = "授权请求无响应";
+        case ASAuthorizationError.notHandled:
+            msg = "授权请求未处理";
+        default:
+            break;
+        }
+        
+        self.appleLoginResultBlock(["error":msg])
+    }
+}

+ 14 - 0
app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json

@@ -0,0 +1,14 @@
+{
+  "images" : [
+    {
+      "filename" : "icon-1024.png",
+      "idiom" : "universal",
+      "platform" : "ios",
+      "size" : "1024x1024"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
app/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-1024.png


+ 6 - 0
app/ios/Runner/Assets.xcassets/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 21 - 0
app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "LOGO@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LOGO@3x.png


+ 5 - 0
app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md

@@ -0,0 +1,5 @@
+# Launch Screen Assets
+
+You can customize the launch screen with your own desired assets by replacing the image files in this directory.
+
+You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.

+ 22 - 0
app/ios/Runner/Assets.xcassets/back.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "back.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "back 1.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
app/ios/Runner/Assets.xcassets/back.imageset/back 1.png


BIN
app/ios/Runner/Assets.xcassets/back.imageset/back.png


+ 21 - 0
app/ios/Runner/Assets.xcassets/check_image.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "check_image.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
app/ios/Runner/Assets.xcassets/check_image.imageset/check_image.png


+ 21 - 0
app/ios/Runner/Assets.xcassets/login_btn_normal.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "login_btn_normal.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
app/ios/Runner/Assets.xcassets/login_btn_normal.imageset/login_btn_normal.png


+ 21 - 0
app/ios/Runner/Assets.xcassets/logo.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "logo.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
app/ios/Runner/Assets.xcassets/logo.imageset/logo.png


+ 21 - 0
app/ios/Runner/Assets.xcassets/uncheck_image.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "uncheck_image.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
app/ios/Runner/Assets.xcassets/uncheck_image.imageset/uncheck_image.png


+ 39 - 0
app/ios/Runner/Base.lproj/LaunchScreen.storyboard

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22130"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <!--View Controller-->
+        <scene sceneID="EHf-IW-A2E">
+            <objects>
+                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+                        <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
+                                <rect key="frame" x="135" y="224" width="123" height="158"/>
+                            </imageView>
+                        </subviews>
+                        <viewLayoutGuide key="safeArea" id="UaE-PJ-QZk"/>
+                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                        <constraints>
+                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="UaE-PJ-QZk" secondAttribute="centerX" id="1a2-6s-vTC"/>
+                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="top" secondItem="UaE-PJ-QZk" secondAttribute="top" constant="165" id="96v-7G-RGG"/>
+                        </constraints>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="80.916030534351137" y="264.08450704225356"/>
+        </scene>
+    </scenes>
+    <resources>
+        <image name="LaunchImage" width="123" height="158"/>
+    </resources>
+</document>

+ 26 - 0
app/ios/Runner/Base.lproj/Main.storyboard

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+    </dependencies>
+    <scenes>
+        <!--Flutter View Controller-->
+        <scene sceneID="tne-QT-ifu">
+            <objects>
+                <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
+                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+            </objects>
+        </scene>
+    </scenes>
+</document>

+ 101 - 0
app/ios/Runner/Info.plist

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CADisableMinimumFrameDurationOnPhone</key>
+	<true/>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
+	<key>CFBundleDisplayName</key>
+	<string>room</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>$(MARKETING_VERSION)</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleURLTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>wx3449abcf85910464</string>
+			</array>
+		</dict>
+		<dict>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>tencent102019408</string>
+			</array>
+		</dict>
+	</array>
+	<key>CFBundleVersion</key>
+	<string>$(CURRENT_PROJECT_VERSION)</string>
+	<key>LSApplicationQueriesSchemes</key>
+	<array>
+		<string>qqmap</string>
+		<string>mqqopensdknopasteboard</string>
+		<string>mqqopensdkapiV2</string>
+		<string>mqq</string>
+		<string>tim</string>
+		<string>baidumap</string>
+		<string>iosamap</string>
+		<string>whatsapp</string>
+		<string>https</string>
+		<string>http</string>
+		<string>wechat</string>
+		<string>weixin</string>
+		<string>weixinULAPI</string>
+		<string>weixinURLParamsAPI</string>
+	</array>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>NSAppTransportSecurity</key>
+	<dict>
+		<key>NSAllowsArbitraryLoads</key>
+		<true/>
+	</dict>
+	<key>NSCameraUsageDescription</key>
+	<string>“YYBusiness”申请调用您的相机权限 用于使用拍摄头像,视频上传,图片上传保存,实名认证等功能</string>
+	<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
+	<string>“YYBusiness”需要获取您的位置来推荐附近工作</string>
+	<key>NSLocationWhenInUseUsageDescription</key>
+	<string>“YYBusiness”需要获取您的位置来推荐附近工作</string>
+	<key>NSMicrophoneUsageDescription</key>
+	<string>请求录音权限</string>
+	<key>NSPhotoLibraryAddUsageDescription</key>
+	<string>“YYBusiness”想访问你的照片 用于图片上传,图片保存等功能,请允许我获取您的权限</string>
+	<key>NSPhotoLibraryUsageDescription</key>
+	<string>“YYBusiness”想访问你的照片 用于图片上传,图片保存等功能,请允许我获取您的权限</string>
+	<key>NSUserTrackingUsageDescription</key>
+	<string>为了优化您的使用体验与确保账户安全,需要您允许room使用相关权限</string>
+	<key>UIApplicationSupportsIndirectInputEvents</key>
+	<true/>
+	<key>UIBackgroundModes</key>
+	<array>
+		<string>remote-notification</string>
+	</array>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>UIMainStoryboardFile</key>
+	<string>Main</string>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+	</array>
+	<key>UIViewControllerBasedStatusBarAppearance</key>
+	<false/>
+</dict>
+</plist>

+ 1 - 0
app/ios/Runner/Runner-Bridging-Header.h

@@ -0,0 +1 @@
+#import "GeneratedPluginRegistrant.h"

+ 18 - 0
app/ios/Runner/Runner.entitlements

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>aps-environment</key>
+	<string>development</string>
+	<key>com.apple.developer.applesignin</key>
+	<array>
+		<string>Default</string>
+	</array>
+	<key>com.apple.developer.associated-domains</key>
+	<array>
+		<string>applinks:api.lehuoer.cn</string>
+	</array>
+	<key>com.apple.developer.networking.wifi-info</key>
+	<true/>
+</dict>
+</plist>

+ 11 - 0
app/ios/apple-app-site-association.plist

@@ -0,0 +1,11 @@
+{
+    "applinks": {
+        "apps": [],
+        "details": [
+            {
+                "appID": "CW4J9W8LB6.com.guadoutech.lehuoer",
+                "paths": [ "/qq_conn/102019408/*"]
+            }
+        ]
+    }
+}

+ 6 - 0
app/ios/fastlane/Appfile

@@ -0,0 +1,6 @@
+# app_identifier("[[APP_IDENTIFIER]]") # The bundle identifier of your app
+# apple_id("[[APPLE_ID]]") # Your Apple Developer Portal username
+
+
+# For more information about the Appfile, see:
+#     https://docs.fastlane.tools/advanced/#appfile

+ 54 - 0
app/ios/fastlane/Fastfile

@@ -0,0 +1,54 @@
+# This file contains the fastlane.tools configuration
+# You can find the documentation at https://docs.fastlane.tools
+#
+# For a list of all available actions, check out
+#
+#     https://docs.fastlane.tools/actions
+#
+# For a list of all available plugins, check out
+#
+#     https://docs.fastlane.tools/plugins/available-plugins
+#
+
+# Uncomment the line if you want fastlane to automatically update itself
+# update_fastlane
+
+default_platform(:ios)
+
+platform :ios do
+    desc "测试环境上传到蒲公英"
+  # 打包时候用的名称   例如 fastlane app
+  lane :dev do 
+    # add actions here: https://docs.fastlane.tools/actions
+    gym(
+    # 每次打包之前clean一下
+    clean: true,    
+    # 打包出 ipa 文件的路径,我放到了桌面文件夹,你自行更改文件夹
+    output_directory: '/Volumes/Data/IPA/TestIPA/'++ Time.new.strftime("%Y-%m-%d %H-%M-%S"), 
+    # 打包的名称,可任意取 
+    output_name: 'FulltimeEmployer', 
+    # 项目包含iCloud指定环境 Development 或者 Production
+    #export_options:{
+    #    "iCloudContainerEnvironment":"Development"
+    #},
+    # 项目的 scheme,自己项目名   target名称
+    scheme: "Runner",      
+    # 默认 Release,Release or Debug     
+    configuration: 'Release', 
+    # 是否包含 bitcode  
+    include_bitcode: false,  
+    # 是否包含 symbols 
+    include_symbols: true, 
+    # 打包导出方式,包含 app-store, validation, ad-hoc, package, enterprise, development, developer-id and mac-application   
+    export_method: 'development',  
+    # 这个设置是为了设置 xcode 自动配置证书和配置文件,当然也可以手动配置,可以参考文档
+    export_xcargs: '-allowProvisioningUpdates' 
+    )
+    #配置上传蒲公英账号  蒲公英的 api_key和 user_key  
+    pgyer(api_key:'12345678', update_description: "fastlane自动打包")
+
+    # mac上的通知弹窗,通知打包完毕
+    notification(app_icon: "./fastlane/icon.png", title: "manager", subtitle: "测试环境打包成功,已导出安装包", message: "")
+
+  end
+ end

+ 6 - 0
app/ios/fastlane/Pluginfile

@@ -0,0 +1,6 @@
+# Autogenerated by fastlane
+#
+# Ensure this file is checked in to source control!
+
+gem 'fastlane-plugin-pgyer'
+gem 'fastlane-plugin-pgyer'

+ 32 - 0
app/ios/fastlane/README.md

@@ -0,0 +1,32 @@
+fastlane documentation
+----
+
+# Installation
+
+Make sure you have the latest version of the Xcode command line tools installed:
+
+```sh
+xcode-select --install
+```
+
+For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
+
+# Available Actions
+
+## iOS
+
+### ios dev
+
+```sh
+[bundle exec] fastlane ios dev
+```
+
+测试环境上传到蒲公英
+
+----
+
+This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
+
+More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
+
+The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).

+ 28 - 0
app/ios/fastlane/report.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuites>
+  <testsuite name="fastlane.lanes">
+    
+    
+    
+      
+      <testcase classname="fastlane.lanes" name="0: default_platform" time="0.000267">
+        
+      </testcase>
+    
+      
+      <testcase classname="fastlane.lanes" name="1: gym" time="159.525949">
+        
+      </testcase>
+    
+      
+      <testcase classname="fastlane.lanes" name="2: pgyer" time="13.375774">
+        
+      </testcase>
+    
+      
+      <testcase classname="fastlane.lanes" name="3: notification" time="0.237306">
+        
+      </testcase>
+    
+  </testsuite>
+</testsuites>

+ 26 - 0
app/lib/app_binding.dart

@@ -0,0 +1,26 @@
+//
+// import 'package:domain/constants/api_constants.dart';
+// import 'package:domain/repository/auth_repository.dart';
+// import 'package:get/get.dart';
+// import 'package:cpt_auth/intercept/interceptor_status_code_dio.dart';
+// import 'package:plugin_basic/service/user_service.dart';
+// import 'package:plugin_platform/http/http_provider.dart';
+//
+// ///异步注入构造方法中的对象 用于Api网络请求相关的注入
+// ///主要是在App初始化的时候就注入到依赖注入的池里面,并单例持久化
+// class AppBinding extends Bindings {
+//   @override
+//   void dependencies() async {
+//     Get.put(HttpProvider(ApiConstants.baseUrl, interceptors: [StatusCodeDioInterceptors()]), permanent: true);
+//
+//     Get.put(AuthRepository(httpProvider: Get.find()));
+//
+//     // 用户信息服务(用户信息相关业务类)
+//     Get.put(UserService(Get.find()));
+//     // Get.lazyPut(() => WXPlatformService());
+//     // Get.lazyPut(() => QQPlatformService());
+//     // Get.lazyPut(() => JVerifyService());
+//
+//     // Get.lazyPut<ProfileService>(() => ProfileServiceImpl());
+//   }
+// }

+ 88 - 0
app/lib/jpush/jpush_receive.dart

@@ -0,0 +1,88 @@
+import 'dart:convert';
+
+import 'package:jpush_flutter/jpush_flutter.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_basic/service/user_service.dart';
+import 'package:shared/utils/log_utils.dart';
+
+
+/// 处理极光推送的逻辑
+class JPushReceive {
+  JPushReceive._internal();
+
+  //保存单例
+  static final JPushReceive _singleton = JPushReceive._internal();
+
+  //工厂构造函数
+  factory JPushReceive() => _singleton;
+
+  /// 初始化极光推送,并设置监听回调
+  void init() {
+    JPush jpush = JPush();
+
+    jpush.addEventHandler(
+      // 接收通知回调方法。
+      onReceiveNotification: (Map<String, dynamic> message) async {
+        Log.d("flutter-jpush: onReceiveNotification: $message");
+      },
+      // 点击通知回调方法。
+      onOpenNotification: (Map<String, dynamic> message) async {
+        Log.d("flutter-jpush: onOpenNotification: $message");
+
+        //拿到后端设置的内容Json对象
+        dynamic extrasJson = message['extras'];
+        dynamic extrasChildJson = extrasJson['cn.jpush.android.EXTRA'];
+        Map<String, dynamic> jsonMap = jsonDecode(extrasChildJson.toString());
+
+        //根据后端返回的type类型跳转到不同的路由页面
+
+      },
+      // 接收自定义消息回调方法。
+      onReceiveMessage: (Map<String, dynamic> message) async {
+        Log.d("flutter-jpush: onReceiveMessage: $message");
+      },
+      // 通知授权的回调
+      onReceiveNotificationAuthorization: (Map<String, dynamic> message) async {
+        Log.d("flutter-jpush: onReceiveNotificationAuthorization: $message");
+        if (message.containsKey('isEnabled')) {
+
+          //不管有没有开启通知权限,通知开关,先拿到 RegistrationId 赋值了再说
+          final registrationId = await getRegistrationId();
+          Log.d('flutter-jpush: 获取到registrationId:$registrationId');
+
+          //设置给 RxString 对象,并保存到 UserService 中。
+          UserService.to.registrationId.value = registrationId;
+        } else {
+          Log.d("flutter-jpush: onReceiveNotificationAuthorization 没有isEnable字段");
+        }
+      },
+
+      // // 通知不显示的回调
+      // onNotifyMessageUnShow: (Map<String, dynamic> message) async {
+      //   Log.d("flutter-refruiter: onNotifyMessageUnShow: $message");
+      // },
+      // // 极光推送连接的回调
+      // onConnected: (Map<String, dynamic> message) async {
+      //   Log.d("flutter-refruiter: onConnected: $message");
+      // },
+    );
+
+    jpush.setup(
+      appKey: "23dedb30175208f894d3756f",
+      channel: "developer-default",
+      production: AppConstant.inProduction,
+      debug: !AppConstant.inProduction, // 设置是否打印 debug 日志
+    );
+
+    //申请iOS授权
+    jpush.applyPushAuthority(const NotificationSettingsIOS(sound: true, alert: true, badge: true));
+  }
+
+  /// 获取极光推送的id
+  Future<String> getRegistrationId() async {
+    JPush jpush = JPush();
+    return jpush.getRegistrationID();
+  }
+}
+
+var jpush = JPushReceive();

+ 179 - 0
app/lib/main.dart

@@ -0,0 +1,179 @@
+import 'package:cpt_profile/router/page_router.dart';
+import 'package:cpt_profile/router/profile_service_impl.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_bugly/flutter_bugly.dart';
+import 'package:flutter_localizations/flutter_localizations.dart';
+import 'package:initializer/global_services_injection.dart';
+import 'package:initializer/app_initializer.dart';
+import 'package:plugin_basic/basic_export.dart';
+import 'package:router/componentRouter/auth_service.dart';
+import 'package:router/componentRouter/mall_service.dart';
+import 'package:router/componentRouter/profile_service.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:plugin_platform/engine/sp/sp_util.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:cs_resources/local/theme/theme_config.dart';
+import 'package:cs_resources/local/language/translation_service.dart';
+import 'package:router/path/router_path.dart';
+import 'package:router/observer/getx_router_observer.dart';
+import 'package:plugin_basic/router/basic_page_router.dart';
+import 'package:widgets/dialog/custom_toast_widget.dart';
+import 'package:widgets/dialog/custom_error_widget.dart';
+import 'package:widgets/dialog/custom_failure_widget.dart';
+import 'package:widgets/dialog/custom_success_widget.dart';
+import 'package:widgets/dialog/custom_loading_widget.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'app_binding.dart';
+import 'router/page_router.dart';
+
+void main() {
+  //运行App
+  FlutterBugly.postCatchedException(() async {
+    //交给初始化构造器去统一初始化
+    AppInitializer.initialize();
+
+    //全局自定义单例服务的注入
+    GlobalServicesInjection.init(additionalDependencies: () {
+      Get.lazyPut<ProfileService>(() => ProfileServiceImpl());
+    });
+
+    runApp(MyApp());
+  });
+}
+
+class MyApp extends StatelessWidget {
+  MyApp({Key? key}) : super(key: key) {
+    /// 全局设置 EasyRefresh 的样式
+    EasyRefresh.defaultHeaderBuilder = () => ClassicHeader(
+          dragText: '下拉刷新'.tr,
+          armedText: '释放刷新'.tr,
+          readyText: '刷新中...'.tr,
+          processingText: '刷新中...'.tr,
+          processedText: '成功'.tr,
+          noMoreText: '没有更多数据'.tr,
+          failedText: '失败'.tr,
+          messageText: '最近更新于 %T'.tr,
+        );
+    EasyRefresh.defaultFooterBuilder = () => ClassicFooter(
+          dragText: '上拉加载更多'.tr,
+          armedText: '释放刷新'.tr,
+          readyText: '加载中...'.tr,
+          processingText: '加载中...'.tr,
+          processedText: '成功'.tr,
+          noMoreText: '没有更多数据'.tr,
+          failedText: '成功'.tr,
+          showMessage: false,
+          triggerOffset: 50,
+          iconDimension: 22,
+        );
+
+    /// SmartDialog 配置
+    SmartDialog.config
+      ..custom = SmartConfigCustom(
+        maskColor: Colors.black.withOpacity(0.35),
+        useAnimation: true,
+      )
+      ..attach = SmartConfigAttach(
+        animationType: SmartAnimationType.scale,
+        usePenetrate: false,
+      )
+      ..loading = SmartConfigLoading(
+        backDismiss: true,
+        clickMaskDismiss: true,
+      )
+      ..toast = SmartConfigToast(
+        intervalTime: const Duration(milliseconds: 100),
+        displayTime: const Duration(milliseconds: 2000),
+      );
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    int? darkModel = SPUtil.getInt(AppConstant.storagedarkmodel, defValue: 0);
+    if (GetPlatform.isAndroid) {
+      //根据SP存入的暗色模式,指定全局页面的状态栏,导航栏等设置
+      switch (darkModel) {
+        case 1:
+          Log.d("main.dart - 指定亮色模式");
+          SystemChrome.setSystemUIOverlayStyle(ThemeConfig.systemUiOverlayStyleLightThemeBlack);
+          break;
+        case 2:
+          Log.d("main.dart - 指定暗色模式");
+          SystemChrome.setSystemUIOverlayStyle(ThemeConfig.systemUiOverlayStyleDarkTheme);
+          break;
+        default:
+          Brightness currentBrightness = MediaQuery.of(context).platformBrightness;
+          if (currentBrightness == Brightness.dark) {
+            Log.d("main.dart - 跟随系统模式-暗色模式");
+            SystemChrome.setSystemUIOverlayStyle(ThemeConfig.systemUiOverlayStyleDarkTheme);
+          } else {
+            Log.d("main.dart - 跟随系统模式-亮色模式");
+            SystemChrome.setSystemUIOverlayStyle(ThemeConfig.systemUiOverlayStyleLightThemeBlack);
+          }
+          break;
+      }
+    }
+
+    //路由管理,状态管理,依赖管理一切都始于GetMaterialApp
+    return KeyboardVisibilityBuilder(builder: (context, isKeyboardVisible) {
+      return KeyboardDismissOnTap(
+        dismissOnCapturedTaps: true,
+        child: GetMaterialApp(
+          //顶部是否展示Debug图标
+          debugShowCheckedModeBanner: true,
+          //是否展示Log
+          enableLog: true,
+          //默认路由与路由表的加载
+          initialRoute: RouterPath.SPLASH,
+          getPages: PageRouter.routes + BasicPageRouter.routes +  ProfilePageRouter.routes,
+          //对原生导航的兼容;SmartDialog路由配置生命周期处理
+          navigatorObservers: [GetXRouterObserver(), FlutterSmartDialog.observer, routeObserver],
+          //默认页面动画
+          defaultTransition: Transition.rightToLeft,
+          smartManagement: SmartManagement.keepFactory,
+          //网页Title显示
+          title: 'FlutterRoom'.tr,
+          //样式相关
+          theme: ThemeConfig.lightTheme,
+          darkTheme: ThemeConfig.darkTheme,
+          themeMode: darkModel == 1
+              ? ThemeMode.light
+              : darkModel == 2
+                  ? ThemeMode.dark
+                  : ThemeMode.system,
+          //本地化相关
+          locale: TranslationService.locale,
+          fallbackLocale: TranslationService.fallbackLocale,
+          localizationsDelegates: const [
+            GlobalMaterialLocalizations.delegate,
+            GlobalWidgetsLocalizations.delegate,
+            GlobalCupertinoLocalizations.delegate,
+          ],
+          supportedLocales: const [
+            Locale('zh', 'CH'),
+            Locale('en', 'US'),
+          ],
+          translations: TranslationService(),
+          //SmartDialog初始化默认Loading与Toast
+          builder: FlutterSmartDialog.init(
+            toastBuilder: (String msg) {
+              return CustomToastWidget(msg: msg);
+            },
+            loadingBuilder: (String msg) {
+              return CustomLoadingWidget(msg: msg == 'loading...' ? '加载中...'.tr : msg);
+            },
+            notifyStyle: FlutterSmartNotifyStyle(
+              successBuilder: (String msg) => CustomSuccessWidget(msg: msg),
+              failureBuilder: (String msg) => CustomFailureWidget(msg: msg),
+              errorBuilder: (String msg) => CustomErrorWidget(msg: msg),
+              alertBuilder: (String msg) => CustomErrorWidget(msg: msg),
+              warningBuilder: (String msg) => CustomErrorWidget(msg: msg),
+            ),
+          ),
+        ),
+      );
+    });
+  }
+}

+ 16 - 0
app/lib/modules/main/main_controller.dart

@@ -0,0 +1,16 @@
+
+import 'package:get/get.dart';
+
+import 'main_state.dart';
+
+class MainController extends GetxController {
+
+  final MainState state = MainState();
+
+
+  @override
+  void onReady() async {
+    super.onReady();
+
+  }
+}

+ 199 - 0
app/lib/modules/main/main_page.dart

@@ -0,0 +1,199 @@
+import 'package:cpt_profile/modules/me/form_filed/form_filed_page.dart';
+import 'package:cpt_profile/modules/me/setting/setting_page.dart';
+
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:get/get.dart';
+import 'package:app/modules/main/main_state.dart';
+import 'package:plugin_basic/base/base_stateful_page.dart';
+import 'package:plugin_basic/base/base_state.dart';
+import 'package:plugin_basic/base/mixin_state_lifecycle.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_basic/utils/ext_get_nav.dart';
+import 'package:plugin_platform/engine/media/image_picker_utils.dart';
+import 'package:plugin_platform/engine/sp/sp_util.dart';
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:cs_resources/local/theme/theme_config.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:router/componentRouter/component_router_service.dart';
+import 'package:router/path/router_path.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/double_tap_back_exit_app.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'main_controller.dart';
+
+/*
+   App首页页面
+   底部5个 Tab + PageView 切换
+ */
+class MainPage extends BaseStatefulPage<MainController> {
+  MainPage({super.key});
+
+  //启动当前页面
+  static void startInstance() {
+    return Get.start(RouterPath.MAIN, launchModel: LaunchModel.singleTask);
+  }
+
+  static void startWithPopAll() {
+    Get.offAllNamed(RouterPath.MAIN);
+  }
+
+  @override
+  State<MainPage> createState() => _MainPageState();
+
+  @override
+  MainController createRawController() {
+    return MainController();
+  }
+}
+
+class _MainPageState extends BaseState<MainPage, MainController> with StateLifecycle {
+  late MainState state;
+
+  @override
+  void initState() {
+    super.initState();
+    state = controller.state;
+  }
+
+  @override
+  void dispose() {
+    Get.delete<MainController>();
+    super.dispose();
+  }
+
+  @override
+  void onResume() {
+    super.onResume();
+    Log.d("MainPage Lifecycle - onResume");
+  }
+
+  @override
+  void onPause() {
+    super.onPause();
+    Log.d("MainPage Lifecycle - onPause");
+  }
+
+  @override
+  void onStop() {
+    super.onStop();
+    Log.d("MainPage Lifecycle - onStop");
+  }
+
+  @override
+  void onStart() {
+    super.onStart();
+    Log.d("MainPage Lifecycle - onStart");
+  }
+
+  //黑暗模式的切换监听
+  @override
+  void didChangePlatformBrightness() {
+    int? darkModel = SPUtil.getInt(AppConstant.storagedarkmodel, defValue: 0);
+    //当跟随系统的时候,监听系统当前的黑暗模式
+    if (darkModel == 0) {
+      //延时拿到当前的值,否则可能获取的值不对
+      Future.delayed(const Duration(milliseconds: 250), () {
+        Brightness currentBrightness = MediaQuery.of(context).platformBrightness;
+        //切换全部的Theme并刷新
+        if (currentBrightness == Brightness.dark) {
+          ThemeConfig.changeThemeDark();
+        } else {
+          ThemeConfig.changeThemeLight();
+        }
+      });
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    Log.d("MainPage Lifecycle - build走了一遍");
+
+    //双击退出应用
+    return DoubleTapBackExitApp(
+      child: AnnotatedRegion<SystemUiOverlayStyle>(
+        value: Get.isDarkMode ? ThemeConfig.systemUiOverlayStyleDarkTheme : ThemeConfig.systemUiOverlayStyleLightThemeWhite,
+        child: autoCtlGetBuilder(builder: (controller) {
+          return Scaffold(
+            appBar: MyAppBar.appBar(context, "首页".tr, backCallback: () {
+              SmartDialog.showToast("你别点我了,没用!");
+            }),
+            body: SafeArea(
+              bottom: true,
+              top: false,
+              //真正的 Content 布局,使用PageView保存状态
+              child: Scrollbar(
+                  child: SingleChildScrollView(
+                child: Column(mainAxisSize: MainAxisSize.min, children: [
+                  MyButton(
+                    onPressed: () {
+
+                    },
+                    text: "去登陆页面",
+                    minWidth: 150,
+                    fontSize: 15,
+                    backgroundColor: ColorConstants.appBlue,
+                    textColor: ColorConstants.white,
+                    elevation: 3,
+                  ).center().marginOnly(top: 10),
+                  MyButton(
+                    onPressed: () {
+                      SettingPage.startInstance();
+                    },
+                    text: "去设置页面",
+                    minWidth: 150,
+                    fontSize: 15,
+                    backgroundColor: ColorConstants.appBlue,
+                    textColor: ColorConstants.white,
+                    elevation: 3,
+                  ).center().marginOnly(top: 10),
+                  MyButton(
+                    onPressed: () {
+                      FormFiledPage.startInstance();
+                    },
+                    text: "Form表单页面",
+                    minWidth: 150,
+                    fontSize: 15,
+                    backgroundColor: ColorConstants.appBlue,
+                    textColor: ColorConstants.white,
+                    elevation: 3,
+                  ).center().marginOnly(top: 10),
+                  MyButton(
+                    onPressed: () async {
+                      bool isLogin = await ComponentRouterServices.profileService.isUserLogin();
+                      String count = await ComponentRouterServices.mallService.getMallCount();
+                      ComponentRouterServices.authService.gotoLoginPage();
+                      Log.d("isLogin:$isLogin count:$count");
+                    },
+                    text: "路由获取",
+                    minWidth: 150,
+                    fontSize: 15,
+                    backgroundColor: ColorConstants.appBlue,
+                    textColor: ColorConstants.white,
+                    elevation: 3,
+                  ).center().marginOnly(top: 10),
+                  MyButton(
+                    onPressed: () {
+                      ImagePickerUtils().show((filePath) {
+                        ToastEngine.show("图片路径:$filePath");
+                      });
+                    },
+                    text: "申请多媒体权限,进入相册选择",
+                    minWidth: 150,
+                    fontSize: 15,
+                    backgroundColor: ColorConstants.appBlue,
+                    textColor: ColorConstants.white,
+                    elevation: 3,
+                  ).center().marginOnly(top: 10),
+                ]),
+              )),
+            ),
+          );
+        }),
+      ),
+    );
+  }
+}

+ 5 - 0
app/lib/modules/main/main_state.dart

@@ -0,0 +1,5 @@
+
+
+class MainState {
+
+}

+ 117 - 0
app/lib/modules/splash/splash_controller.dart

@@ -0,0 +1,117 @@
+import 'package:flutter_bugly/flutter_bugly.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:get/get.dart';
+
+import 'package:app/jpush/jpush_receive.dart';
+import 'package:app/modules/main/main_page.dart';
+import 'package:initializer/app_initializer.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_basic/service/config_services_injection.dart';
+import 'package:plugin_platform/engine/directory/directory_util.dart';
+import 'package:plugin_platform/engine/sp/sp_util.dart';
+import 'package:shared/utils/device_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+
+class SplashController extends GetxController {
+  @override
+  void onReady() {
+    super.onReady();
+
+    //是否是第一次进入App,需要同意协议弹窗,否则退出App
+    final isFirstOpen = SPUtil.getBool(AppConstant.storageFirstOpen) ?? false;
+    Log.d('isFirstOpen:$isFirstOpen');
+    if (!isFirstOpen) {
+      //展示协议弹窗
+      _showAgreementDialog();
+      if (DeviceUtils.isAndroid) {
+        // AppChannel.skipAndroidSplashScreen();
+      }
+    } else {
+      _gotoNextPage();
+    }
+  }
+
+  // 展示协议弹窗
+  void _showAgreementDialog() {
+    // SmartDialog.show(
+    //   usePenetrate: false,
+    //   clickMaskDismiss: false,
+    //   backDismiss: false,
+    //   keepSingle: true,
+    //   builder: (context) => PrivacyPolicyDialog(
+    //     confirmAction: () {
+    //       Log.d('同意协议了');
+    //       SPUtil.putBool(AppConstant.storageFirstOpen, true);
+    //       _gotoNextPage();
+    //     },
+    //     cancelAction: () {
+    //       //提示是否进入基础功能
+    //       _showSimpleModelDialog();
+    //     },
+    //   ),
+    // );
+
+    SPUtil.putBool(AppConstant.storageFirstOpen, true);
+    _gotoNextPage();
+  }
+
+  // 展示基础功能弹窗
+  void _showSimpleModelDialog() {
+    // SmartDialog.show(
+    //   usePenetrate: false,
+    //   clickMaskDismiss: false,
+    //   backDismiss: false,
+    //   keepSingle: true,
+    //   builder: (context) => SimpleModelDialog(
+    //     confirmAction: () {
+    //       Log.d('同意协议了');
+    //       SpUtil.putBool(AppConstant.storageFirstOpen, true);
+    //       _gotoNextPage();
+    //     },
+    //     cancelAction: () {
+    //       //进入基础功能
+    //       Log.d('进入基础功能');
+    //     },
+    //   ),
+    // );
+  }
+
+  /// 同意了协议之后的初始化第三方与真正跳转逻辑判断
+  void _gotoNextPage() async {
+
+    await AppInitializer.delayInitialize(futureTasks: [
+      () async {
+        await FlutterBugly.init(
+          androidAppId: "12345678",
+          iOSAppId: "12345678",
+        );
+      },
+    ], normalTasks: [
+      () {
+        if (DeviceUtils.isIOS || DeviceUtils.isAndroid) {
+          jpush.init();
+        }
+      },
+    ]);
+
+    // 先查询原生平台有没有保存需要跳转的子路由
+    // String routerName = await AppChannel.getNativeRouterName();
+    // Log.d('SplashController - 查询原生平台有没有保存需要跳转的子路由:$routerName');
+
+    MainPage.startWithPopAll();
+
+    // if (!Utils.isEmpty(routerName)) {
+    //   // 只跳转一次
+    //   Get.offAllNamed(routerName);
+    //   AppChannel.clearNativeRouterName();
+    // } else {
+    //   // 如果没有经历过GUIDE页面,进入GUIDE,否则进入首页
+    //     MainPage.startWithPopAll();
+    // }
+
+    //跳转页面之后清除 Android 的 SplashScreen 库
+    // if (Device.isAndroid) {
+    //   AppChannel.skipAndroidSplashScreen();
+    // }
+  }
+}

+ 37 - 0
app/lib/modules/splash/splash_page.dart

@@ -0,0 +1,37 @@
+
+import 'package:flutter/material.dart';
+import 'package:app/modules/splash/splash_controller.dart';
+import 'package:plugin_basic/base/base_stateless_page.dart';
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:shared/utils/size_config.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/utils/dark_theme_util.dart';
+
+class SplashPage extends BaseStatelessPage<SplashController> {
+  SplashPage({super.key});
+
+  @override
+  SplashController createRawController() {
+    return SplashController();
+  }
+
+  @override
+  void initState() {}
+
+  @override
+  Widget buildWidget(BuildContext context) {
+    SizeConfig().init(context);
+
+    return Container(
+        color: DarkThemeUtil.multiColors(ColorConstants.white, darkColor: ColorConstants.darkBlackBg),
+        child: const Center(
+          child: MyAssetImage(
+            Assets.assetsSplashiCenterBlueLogo,
+            width: 144,
+            height: 144,
+            fit: BoxFit.contain,
+          ),
+        ));
+  }
+}

+ 27 - 0
app/lib/router/page_router.dart

@@ -0,0 +1,27 @@
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:router/path/router_path.dart';
+
+import '../modules/main/main_page.dart';
+import '../modules/splash/splash_page.dart';
+
+class PageRouter {
+
+  static final routes = [
+
+    //闪屏页
+    GetPage(
+      name: RouterPath.SPLASH,
+      page: () => SplashPage(),
+    ),
+
+    //首页
+    GetPage(
+      name: RouterPath.MAIN,
+      page: () => MainPage(
+        key: const ValueKey(RouterPath.MAIN),
+      ),
+    ),
+
+  ];
+}

+ 75 - 0
app/pubspec.yaml

@@ -0,0 +1,75 @@
+name: app  #宿主App命名空间
+description: Flutter Room 临时项目
+
+version: 1.0.0
+
+environment:
+  sdk: '>=3.0.2 <4.0.0'
+
+dependencies:
+
+  flutter_localizations:
+    sdk: flutter
+
+  flutter:
+    sdk: flutter
+
+  #基础组件的依赖
+  domain:
+    path: ../packages/cs_domain
+
+  plugin_basic:
+    path: ../packages/cs_plugin_basic
+
+  plugin_platform:
+    path: ../packages/cs_plugin_platform
+
+  shared:
+    path: ../packages/cs_shared
+
+  cs_resources:
+    path: ../packages/cs_resources
+
+  router:
+    path: ../packages/cs_router
+
+  widgets:
+    path: ../packages/cs_widgets
+
+  #业务子组件的依赖
+  cpt_profile:
+    path: ../packages/cpt_profile
+
+
+  initializer:
+    path: ../packages/cs_initializer
+
+
+  # 极光推送  https://github.com/jpush/jpush-flutter-plugin
+  jpush_flutter: 2.5.1
+
+  #  https://pub-web.flutter-io.cn/packages/flutter_bugly
+  flutter_bugly: 0.4.4
+
+  # 定位,反地理编码
+  flutter_bmflocation: 3.6.0
+
+  #手写签名 https://pub.dev/packages/hand_signature
+  hand_signature: ^3.0.2
+
+  #密码输入框 https://pub.dev/packages/hb_password_input_textfield
+  hb_password_input_textfield: ^1.0.1
+
+  #视频播放 https://pub.dev/packages/video_player
+  chewie: 1.7.5
+
+
+#  开发环境依赖的库
+dev_dependencies:
+  flutter_test:
+    sdk: flutter
+
+  flutter_lints: ^1.0.0
+
+flutter:
+  uses-material-design: true

+ 11 - 0
app/test/widget_test.dart

@@ -0,0 +1,11 @@
+// This is a basic Flutter widget test.
+//
+// To perform an interaction with a widget in your test, use the WidgetTester
+// utility that Flutter provides. For example, you can send tap and scroll
+// gestures. You can also use WidgetTester to find child widgets in the widget
+// tree, read text, and verify that the values of widget properties are correct.
+
+
+void main() {
+
+}

+ 28 - 0
app/web/index.html

@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <meta content="IE=Edge" http-equiv="X-UA-Compatible">
+
+    <!-- iOS meta tags & icons -->
+    <meta name="apple-mobile-web-app-capable" content="yes">
+    <meta name="apple-mobile-web-app-status-bar-style" content="black">
+    <meta name="apple-mobile-web-app-title" content="EasyRefresh">
+    <link rel="apple-touch-icon" href="icons/Icon-192.png">
+
+    <title>YY Employer</title>
+
+</head>
+<body>
+
+<script>
+    if ('serviceWorker' in navigator) {
+      window.addEventListener('load', function () {
+        navigator.serviceWorker.register('flutter_service_worker.js');
+      });
+    }
+  </script>
+
+<script src="main.dart.js" type="application/javascript"></script>
+</body>
+</html>

+ 51 - 0
melos.yaml

@@ -0,0 +1,51 @@
+name: flutter_room
+packages:
+  - "app/**"
+  - "packages/cs_domain/**"
+  - "packages/cs_initializer/**"
+  - "packages/cs_plugin_basic/**"
+  - "packages/cs_plugin_platform/**"
+  - "packages/cs_resources/**"
+  - "packages/cs_router/**"
+  - "packages/cs_shared/**"
+  - "packages/cs_widgets/**"
+  - "packages/cpt_auth/"
+  - "packages/cpt_mall/"
+  - "packages/cpt_profile/"
+  - "packages/cpt_mall/runalone/**"
+  - "packages/cpt_auth/runalone/**"
+
+
+command:
+  bootstrap:
+    usePubspecOverrides: true
+
+
+scripts:
+  analyze:
+    run: melos exec -- "flutter analyze"
+    description: Run `flutter analyze` in all packages
+
+  pub_get:
+    run: dart pub global run melos exec --flutter "flutter pub get"
+    description: pub get
+
+  build_all:
+    run: dart pub global run melos exec --depends-on="build_runner" "flutter packages pub run build_runner build --delete-conflicting-outputs"
+    description: build_runner build all modules
+
+  format:
+    run: melos exec -- "flutter format . --set-exit-if-changed"
+    description: Run `flutter format .` in all packages
+
+  test:
+    run: melos exec --dir-exists=test -- "flutter test"
+    description: Run `flutter test` in all packages
+
+  runalone_auth:
+    run: cd "$MELOS_ROOT_PATH/packages/cpt_auth/runalone" && flutter run
+    description: runalone auth module.
+
+  runalone_mall:
+    run: cd "$MELOS_ROOT_PATH/packages/cpt_mall/runalone" && flutter run
+    description: runalone mall module.

+ 31 - 0
packages/cpt_profile/.gitignore

@@ -0,0 +1,31 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+*.lock
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# Visual Studio Code related
+.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+proguardMapping.txt

+ 204 - 0
packages/cpt_profile/lib/modules/me/change_mobile/change_mobile_controller.dart

@@ -0,0 +1,204 @@
+import 'dart:async';
+
+import 'package:domain/repository/auth_repository.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:get/get.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:shared/utils/ext_dart.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
+
+
+
+import 'change_mobile_state.dart';
+
+class ChangeMobileController extends GetxController {
+  final ChangeMobileState state = ChangeMobileState();
+  final AuthRepository authRepository = Get.find();
+
+  String? mobilePhoneErrorText; //表单的错误信息展示
+  String? codeErrorText;
+
+  String? phone;
+  String? code;
+
+
+  /// 执行手机号码的绑定
+  void doChangePhone() {
+    mobilePhoneErrorText = null;
+    codeErrorText = null;
+    update();
+
+    var phoneController = state.formData['phone']!['controller'];
+    var codeController = state.formData['code']!['controller'];
+
+    phone = phoneController.text;
+    code = codeController.text;
+
+    Log.d('phone:$phone code:$code');
+
+    if (Utils.isEmpty(phone)) {
+      mobilePhoneErrorText = "电话号码不能为空";
+      update();
+    } else if (Utils.isEmpty(code)) {
+      codeErrorText = "验证码不能为空";
+      update();
+    }  else {
+      _requestForgetPsd();
+    }
+  }
+
+  /// 请求接口,普通的密码注册
+  void _requestForgetPsd() async {
+    // //获取到数据
+    // SmartDialog.showLoading();
+    // var result = await authRepository.updateMobilePhone(phone, code);
+    // SmartDialog.dismiss(status: SmartStatus.loading);
+    //
+    // //处理数据
+    // if (result.isSuccess) {
+    //   SmartDialog.showNotify(msg:'修改手机号码成功',notifyType: NotifyType.success);
+    //
+    //   //发送通知刷新用户详情信息
+    //   bus.emit(AppConstant.eventProfile2Refresh, true);
+    //
+    //   //成功了返回
+    //   Get.back();
+    // } else {
+    //   _handleErrorMessage(result);
+    // }
+  }
+
+  /// 处理网络请求注册的表单错误
+  void _handleErrorMessage(HttpResult<dynamic> result) {
+    String? errorMessage = result.errorMsg;
+    SmartDialog.showToast(errorMessage ?? '未知错误'.tr);
+
+    Map<String, dynamic>? json = result.getErrorJson();
+    handleFormError(json, 'phone', (str) {
+      mobilePhoneErrorText = str;
+    });
+    handleFormError(json, 'sms_verification_code', (str) {
+      codeErrorText = str;
+    });
+  }
+
+  /// 默认的App Dialog
+  void showVerifyCodedDialog() {
+    //隐藏全部的软键盘与焦点
+    _phoneFocusNode?.unfocus();
+    _codeFocusNode?.unfocus();
+
+    //校验手机号码不能为空
+    phone = state.formData['phone']!['controller'].text;
+    if (Utils.isEmpty(phone)) {
+      mobilePhoneErrorText = "电话号码不能为空";
+      update();
+    } else {
+      // SmartDialog.show(
+      //   usePenetrate: false,
+      //   debounce: true,
+      //   clickMaskDismiss: false,
+      //   onDismiss: () {
+      //     //每次取消弹窗都要手动删除弹窗的Controller,不然无法每次弹出都请求接口
+      //     Get.delete<VerifyCodeDialogController>();
+      //   },
+      //   builder: (context) => VerifyCodeDialog(
+      //     confirmAction: (key, code) {
+      //       //发送验证码
+      //       _requestSendSMS(key, code);
+      //     },
+      //   ),
+      // );
+    }
+  }
+
+  /// 请求接口,发送验证码
+  void _requestSendSMS(String? key, String? code) async {
+    // //获取到数据
+    // SmartDialog.showLoading();
+    // var result = await authRepository.sendPhoneSMS('update_phone', phone, key, code);
+    // SmartDialog.dismiss(status: SmartStatus.loading);
+    //
+    // //处理数据
+    // if (result.isSuccess) {
+    //   //成功之后开始倒计时
+    //   _startCountDown();
+    // } else {
+    //   String? errorMessage = result.errorMsg;
+    //   SmartDialog.showToast(errorMessage ?? '未知错误'.tr);
+    // }
+  }
+
+  // =========================== 倒计时控制 ===========================
+
+  final int _initialTime = 60; // 初始倒计时时间(秒)
+  int countdownTime = 0; // 当前倒计时剩余时间(秒)
+  Timer? countdownTimer;
+  bool isCounting = false;
+
+  /// 开启倒计时
+  void _startCountDown() {
+    countdownTime = _initialTime;
+    isCounting = true;
+    update();
+
+    //每秒的倒计时
+    countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
+      if (countdownTime > 0) {
+        countdownTime--;
+      } else {
+        isCounting = false;
+        countdownTimer?.cancel(); // 取消计时器
+      }
+      update();
+    });
+  }
+
+  // =========================== 焦点控制 ===========================
+
+  FocusNode? _phoneFocusNode;
+  FocusNode? _codeFocusNode;
+
+  void _onPhoneFocusChange() {
+    if (_phoneFocusNode?.hasFocus == true) {
+      mobilePhoneErrorText = null;
+      update();
+    }
+  }
+
+  void _onCodeFocusChange() {
+    if (_codeFocusNode?.hasFocus == true) {
+      codeErrorText = null;
+      update();
+    }
+  }
+
+
+  @override
+  void onInit() {
+    super.onInit();
+    _phoneFocusNode = state.formData['phone']!['focusNode'];
+    _codeFocusNode = state.formData['code']!['focusNode'];
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
+    _phoneFocusNode?.addListener(_onPhoneFocusChange);
+    _codeFocusNode?.addListener(_onCodeFocusChange);
+  }
+
+  @override
+  void onClose() {
+    super.onClose();
+    _phoneFocusNode?.removeListener(_onPhoneFocusChange);
+    _codeFocusNode?.removeListener(_onCodeFocusChange);
+    _phoneFocusNode = null;
+    _codeFocusNode = null;
+
+    countdownTimer?.cancel(); // 取消计时器
+  }
+
+}

+ 0 - 0
packages/cpt_profile/lib/modules/me/change_mobile/change_mobile_page.dart


Some files were not shown because too many files changed in this diff