diff --git a/android/app/src/main/res/drawable-v21/background.png b/android/app/src/main/res/drawable-v21/background.png
index 4ebb677..5c78b7d 100644
Binary files a/android/app/src/main/res/drawable-v21/background.png and b/android/app/src/main/res/drawable-v21/background.png differ
diff --git a/android/app/src/main/res/drawable/background.png b/android/app/src/main/res/drawable/background.png
index 4ebb677..5c78b7d 100644
Binary files a/android/app/src/main/res/drawable/background.png and b/android/app/src/main/res/drawable/background.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
index 5337d5a..a684c13 100644
Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
index 8c85bf1..0b4f2d3 100644
Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index e37e85c..33380e7 100644
Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index 342548c..c506f92 100644
Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index 7e763e2..8fad73b 100644
Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/assets/icon-apps/home_add.png b/assets/icon-apps/home_add.png
new file mode 100644
index 0000000..e529dcd
Binary files /dev/null and b/assets/icon-apps/home_add.png differ
diff --git a/assets/images/logo.png b/assets/images/logo.png
index 64c5599..48d0c80 100644
Binary files a/assets/images/logo.png and b/assets/images/logo.png differ
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index b3c07f8..c7fc0b7 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -491,7 +491,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 62;
DEVELOPMENT_TEAM = "";
@@ -503,10 +503,11 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = com.company.myapp2;
+ MARKETING_VERSION = 2.2.3;
+ PRODUCT_BUNDLE_IDENTIFIER = uni.UNI85F7A17;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "qa-zsaq";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "qa-zsaq-des";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
@@ -685,7 +686,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 62;
DEVELOPMENT_TEAM = "";
@@ -697,10 +698,11 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = com.company.myapp2;
+ MARKETING_VERSION = 2.2.3;
+ PRODUCT_BUNDLE_IDENTIFIER = uni.UNI85F7A17;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "qa-zsaq";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "qa-zsaq-des";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@@ -716,7 +718,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 62;
DEVELOPMENT_TEAM = "";
@@ -728,10 +730,11 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = com.company.myapp2;
+ MARKETING_VERSION = 2.2.3;
+ PRODUCT_BUNDLE_IDENTIFIER = uni.UNI85F7A17;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "qa-zsaq";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "qa-zsaq-des";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
index 5fa3a42..ba8b8ee 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
index 09a4baa..7e8a5a0 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
index 13b9886..d64f318 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
index f9dacfd..c425eaf 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
index 74c9145..3505ed8 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
index 470a8e1..18e4fcd 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
index 772149b..646e77f 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
index 13b9886..d64f318 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
index a30a68d..16711e2 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
index 27d32eb..2c18a84 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
index feece6d..b30478a 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
index 4fa3790..a9b673f 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
index bf80268..76d9b8a 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
index 9e5fc9d..9fccbf0 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
index 27d32eb..2c18a84 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
index fe44b93..705316e 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
index 5337d5a..a684c13 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
index 342548c..c506f92 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
index a2dd400..c1c0345 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
index ae77c36..ff4a094 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
index c429f45..9fbe461 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png b/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png
index 4ebb677..5c78b7d 100644
Binary files a/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png and b/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png differ
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 13a000c..d62a787 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -1,91 +1,91 @@
-
- CADisableMinimumFrameDurationOnPhone
-
- CFBundleDisplayName
+
+ CADisableMinimumFrameDurationOnPhone
+
+ CFBundleDisplayName
${PRODUCT_NAME}
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- 秦港双控
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- $(FLUTTER_BUILD_NAME)
- CFBundleSignature
- ????
- CFBundleVersion
- $(FLUTTER_BUILD_NUMBER)
- LSApplicationQueriesSchemes
-
- baidumap
-
- LSRequiresIPhoneOS
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ 秦港双控
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSApplicationQueriesSchemes
+
+ baidumap
+
+ LSRequiresIPhoneOS
+
+ NFCReaderUsageDescription
+ 需要NFC权限来读取和写入标签
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
- NFCReaderUsageDescription
- 需要NFC权限来读取和写入标签
- NSAppTransportSecurity
-
- NSAllowsArbitraryLoads
-
-
- NSBluetoothAlwaysUsageDescription
- app需要蓝牙权限连接设备
- NSCameraUsageDescription
- app需要相机权限来扫描二维码
- NSContactsUsageDescription
- app需要通讯录权限添加好友
- NSHealthShareUsageDescription
- app需要读取健康数据
- NSHealthUpdateUsageDescription
- app需要写入健康数据
- NSLocalNetworkUsageDescription
- app需要发现本地网络设备
- NSLocationAlwaysAndWhenInUseUsageDescription
- 我们需要访问您的位置来提供基于位置的服务,例如获取位置展示地图。您的位置数据不会用于其他目的。
- NSLocationAlwaysUsageDescription
- 我们需要访问您的位置来提供基于位置的服务,例如获取位置展示地图。您的位置数据不会用于其他目的。
- NSLocationWhenInUseUsageDescription
- 我们需要访问您的位置来提供基于位置的服务,例如获取位置展示地图。您的位置数据不会用于其他目的。
- NSMicrophoneUsageDescription
- app需要麦克风权限进行语音通话
- NSMotionUsageDescription
- app需要访问运动数据统计步数
- NSPhotoLibraryAddUsageDescription
- app需要保存图片到相册
- NSPhotoLibraryUsageDescription
- app需要访问相册以上传图片
- NSUserNotificationsUsageDescription
- app需要发送通知提醒重要信息
- UIApplicationSupportsIndirectInputEvents
-
- UIBackgroundModes
-
- remote-notification
-
- UILaunchStoryboardName
- LaunchScreen
- UIMainStoryboardFile
- Main
- UIStatusBarHidden
-
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
-
- com.apple.developer.nfc.readersession.formats
-
- TAG
- NDEF
-
-
\ No newline at end of file
+ NSBluetoothAlwaysUsageDescription
+ app需要蓝牙权限连接设备
+ NSCameraUsageDescription
+ app需要相机权限来扫描二维码
+ NSContactsUsageDescription
+ app需要通讯录权限添加好友
+ NSHealthShareUsageDescription
+ app需要读取健康数据
+ NSHealthUpdateUsageDescription
+ app需要写入健康数据
+ NSLocalNetworkUsageDescription
+ app需要发现本地网络设备
+ NSLocationAlwaysAndWhenInUseUsageDescription
+ 我们需要访问您的位置来提供基于位置的服务,例如获取位置展示地图。您的位置数据不会用于其他目的。
+ NSLocationAlwaysUsageDescription
+ 我们需要访问您的位置来提供基于位置的服务,例如获取位置展示地图。您的位置数据不会用于其他目的。
+ NSLocationWhenInUseUsageDescription
+ 我们需要访问您的位置来提供基于位置的服务,例如获取位置展示地图。您的位置数据不会用于其他目的。
+ NSMicrophoneUsageDescription
+ app需要麦克风权限进行语音通话
+ NSMotionUsageDescription
+ app需要访问运动数据统计步数
+ NSPhotoLibraryAddUsageDescription
+ app需要保存图片到相册
+ NSPhotoLibraryUsageDescription
+ app需要访问相册以上传图片
+ NSUserNotificationsUsageDescription
+ app需要发送通知提醒重要信息
+ UIApplicationSupportsIndirectInputEvents
+
+ UIBackgroundModes
+
+ remote-notification
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+
+ com.apple.developer.nfc.readersession.formats
+
+ TAG
+ NDEF
+
+
+
diff --git a/lib/customWidget/custom_alert_dialog.dart b/lib/customWidget/custom_alert_dialog.dart
index ad5c9ca..2e25d38 100644
--- a/lib/customWidget/custom_alert_dialog.dart
+++ b/lib/customWidget/custom_alert_dialog.dart
@@ -1,9 +1,12 @@
// custom_alert_dialog.dart
+import 'dart:async';
+
import 'package:flutter/material.dart';
+import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/main.dart'; // 导入全局 navigatorKey
/// 对话框模式
-enum DialogMode { text, input }
+enum DialogMode { text, input, inputWithCode }
class CustomAlertDialog extends StatefulWidget {
final String title;
@@ -17,6 +20,10 @@ class CustomAlertDialog extends StatefulWidget {
final DialogMode mode;
final bool force;
+ /// 新增:获取验证码回调,若提供则在用户点击获取验证码时调用。
+ /// 回调返回 true 表示获取成功(开始倒计时),返回 false 表示获取失败(不开始倒计时)。
+ final Future Function()? onGetCode;
+
const CustomAlertDialog({
Key? key,
required this.title,
@@ -29,85 +36,119 @@ class CustomAlertDialog extends StatefulWidget {
this.onInputConfirm,
this.mode = DialogMode.text,
this.force = false,
+ this.onGetCode,
}) : super(key: key);
// ------------------ 静态快捷方法 ------------------
static Future showConfirm(
- BuildContext context, {
- required String title,
- String content = '',
- String cancelText = '取消',
- String confirmText = '确定',
- bool barrierDismissible = true,
- VoidCallback? onConfirm,
- bool force = false,
- }) async {
+ BuildContext context, {
+ required String title,
+ String content = '',
+ String cancelText = '取消',
+ String confirmText = '确定',
+ bool barrierDismissible = true,
+ VoidCallback? onConfirm,
+ bool force = false,
+ }) async {
final result = await showDialog(
context: context,
barrierDismissible: force ? false : barrierDismissible,
- builder: (_) => PopScope(
- canPop: false,
- child: CustomAlertDialog(
- title: title,
- content: content,
- cancelText: cancelText,
- confirmText: confirmText,
- onConfirm: onConfirm,
- force: force,
- ),)
+ builder:
+ (_) => PopScope(
+ canPop: false,
+ child: CustomAlertDialog(
+ title: title,
+ content: content,
+ cancelText: cancelText,
+ confirmText: confirmText,
+ onConfirm: onConfirm,
+ force: force,
+ ),
+ ),
);
return result == true;
}
static Future showAlert(
- BuildContext context, {
- required String title,
- String content = '',
- String confirmText = '确定',
- bool barrierDismissible = true,
- VoidCallback? onConfirm,
- bool force = false,
- }) async {
+ BuildContext context, {
+ required String title,
+ String content = '',
+ String confirmText = '确定',
+ bool barrierDismissible = true,
+ VoidCallback? onConfirm,
+ bool force = false,
+ }) async {
await showDialog(
context: context,
barrierDismissible: force ? false : barrierDismissible,
- builder: (_) => CustomAlertDialog(
- title: title,
- content: content,
- cancelText: '',
- confirmText: confirmText,
- onConfirm: onConfirm,
- force: force,
- ),
+ builder:
+ (_) => CustomAlertDialog(
+ title: title,
+ content: content,
+ cancelText: '',
+ confirmText: confirmText,
+ onConfirm: onConfirm,
+ force: force,
+ ),
);
}
static Future showInput(
- BuildContext context, {
- required String title,
- String hintText = '',
- String cancelText = '取消',
- String confirmText = '确定',
- bool barrierDismissible = true,
- bool force = false,
- }) async {
+ BuildContext context, {
+ required String title,
+ String hintText = '',
+ String cancelText = '取消',
+ String confirmText = '确定',
+ bool barrierDismissible = true,
+ bool force = false,
+ }) async {
final result = await showDialog(
context: context,
barrierDismissible: force ? false : barrierDismissible,
- builder: (_) => CustomAlertDialog(
- title: title,
- hintText: hintText,
- cancelText: cancelText,
- confirmText: confirmText,
- mode: DialogMode.input,
- force: force,
- ),
+ builder:
+ (_) => CustomAlertDialog(
+ title: title,
+ hintText: hintText,
+ cancelText: cancelText,
+ confirmText: confirmText,
+ mode: DialogMode.input,
+ force: force,
+ ),
);
// 取消/点遮罩会得到 null;确认会得到 String(可能为空串)
return result;
}
+ /// 新增:快捷方法——输入框 + 获取验证码
+ static Future showInputWithCode(
+ BuildContext context, {
+ required String title,
+ String hintText = '',
+ String cancelText = '取消',
+ String confirmText = '确定',
+ bool barrierDismissible = true,
+ bool force = false,
+ Future Function()? onGetCode,
+ ValueChanged? onConfirm, // <-- 这里改为带参数的回调
+ }) async {
+ final result = await showDialog(
+ context: context,
+ barrierDismissible: force ? false : barrierDismissible,
+ builder:
+ (_) => CustomAlertDialog(
+ title: title,
+ hintText: hintText,
+ cancelText: cancelText,
+ confirmText: confirmText,
+ mode: DialogMode.inputWithCode,
+ force: force,
+ onGetCode: onGetCode,
+ onInputConfirm: onConfirm, // 把回调传给内部使用的 onInputConfirm
+ ),
+ );
+ return result;
+ }
@override
_CustomAlertDialogState createState() => _CustomAlertDialogState();
@@ -117,6 +158,11 @@ class _CustomAlertDialogState extends State {
late TextEditingController _controller;
bool _isClosing = false;
+ // 验证码计时器相关
+ Timer? _timer;
+ int _seconds = 0;
+ static const int _defaultCountdown = 60;
+
@override
void initState() {
super.initState();
@@ -125,6 +171,7 @@ class _CustomAlertDialogState extends State {
@override
void dispose() {
+ _timer?.cancel();
_controller.dispose();
super.dispose();
}
@@ -144,6 +191,41 @@ class _CustomAlertDialogState extends State {
}
}
+ void _startCountdown([int seconds = _defaultCountdown]) {
+ _timer?.cancel();
+ setState(() {
+ _seconds = seconds;
+ });
+ _timer = Timer.periodic(const Duration(seconds: 1), (t) {
+ if (!mounted) {
+ t.cancel();
+ return;
+ }
+ if (_seconds <= 1) {
+ t.cancel();
+ setState(() {
+ _seconds = 0;
+ });
+ } else {
+ setState(() {
+ _seconds -= 1;
+ });
+ }
+ });
+ }
+
+ Future _onGetCodePressed() async {
+ if (_seconds > 0) return; // 正在倒计时,忽略
+ // 如果外部提供了回调,等待其执行并根据返回值决定是否开始倒计时
+ if (widget.onGetCode != null) {
+ await widget.onGetCode!();
+ _startCountdown();
+ } else {
+ // 未提供回调:默认直接开始倒计时(方便调试)
+ _startCountdown();
+ }
+ }
+
@override
Widget build(BuildContext context) {
return PopScope(
@@ -177,14 +259,11 @@ class _CustomAlertDialogState extends State {
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Text(
widget.content,
- style: const TextStyle(
- fontSize: 16,
- color: Colors.black54,
- ),
+ style: const TextStyle(fontSize: 16, color: Colors.black54),
textAlign: TextAlign.center,
),
)
- else
+ else if (widget.mode == DialogMode.input)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: TextField(
@@ -204,6 +283,45 @@ class _CustomAlertDialogState extends State {
),
),
),
+ )
+ else // DialogMode.inputWithCode
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
+ child: Row(
+ children: [
+ Expanded(
+ child: TextField(
+ controller: _controller,
+ autofocus: true,
+ decoration: InputDecoration(
+ hintText: widget.hintText,
+ border: const OutlineInputBorder(),
+ focusedBorder: OutlineInputBorder(
+ borderSide: BorderSide(
+ color: Colors.blue,
+ width: 1,
+ ),
+ borderRadius: BorderRadius.circular(4),
+ ),
+ isDense: true,
+ contentPadding: const EdgeInsets.symmetric(
+ vertical: 10,
+ horizontal: 10,
+ ),
+ ),
+ ),
+ ),
+ const SizedBox(width: 8),
+ SizedBox(
+ height: 44,
+ width: 100,
+ child: CustomButton(
+ text: _seconds > 0 ? '$_seconds s' : '发送验证码',
+ onPressed: _seconds > 0 ? null : _onGetCodePressed,
+ ),
+ ),
+ ],
+ ),
),
const SizedBox(height: 20),
const Divider(height: 1),
@@ -298,4 +416,4 @@ class _CustomAlertDialogState extends State {
),
);
}
-}
\ No newline at end of file
+}
diff --git a/lib/http/ApiService.dart b/lib/http/ApiService.dart
index 3aea3ff..53f714c 100644
--- a/lib/http/ApiService.dart
+++ b/lib/http/ApiService.dart
@@ -18,7 +18,7 @@ class ApiService {
static final String baseImgPath =
isProduct
? "https://jpfz.qhdsafety.com/gbsFileTest/"
- : "http://192.168.20.100:9787/mnt/"; //内网图片地址
+ : "http://192.168.20.240:9787/mnt/"; //内网图片地址
static const publicKey =
'0402df2195296d4062ac85ad766994d73e871b887e18efb9a9a06b4cebc72372869b7da6c347c129dee2b46a0f279ff066b01c76208c2a052af75977c722a2ccee';
diff --git a/lib/http/HttpManager.dart b/lib/http/HttpManager.dart
index d3bf7a8..fcb71ee 100644
--- a/lib/http/HttpManager.dart
+++ b/lib/http/HttpManager.dart
@@ -76,6 +76,7 @@ class HttpManager {
CancelToken? cancelToken,
String? contentType, // Content-Type,默认为 jsonContentType
bool isHeartbeat = false,
+ bool isHaveToken = true,
}) async {
printLongString('参数:${jsonEncode(data)}');
Response resp;
@@ -87,7 +88,7 @@ class HttpManager {
};
final token = SessionService.instance.token ?? '';
// final token = 'jjb-saas-auth:oauth:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJjbGllbnRJZFwiOlwieGdmemRcIixcImFjY291bnRJZFwiOjE5OTE2NzQ0MzEzMzY4NDk0MDgsXCJ1c2VyVHlwZUVudW1cIjpcIlBMQVRGT1JNXCIsXCJ1c2VySWRcIjoxOTkxNjc0NDI4MjYxNTMxNjQ4LFwidGVuYW50SWRcIjoxOTkxNjc0NDI4MjYxNTMxNjQ4LFwidGVuYW50TmFtZVwiOlwi5Yas5rOz55u45YWz5pa5XCIsXCJ0ZW5hbnRUeXBlSWRcIjoxOTkwNjkzMzg4MDcyMTI0NDE2LFwidGVuYW50UGFyZW50SWRzXCI6XCIwLDE5ODM3NzMwMTMwODYwNDgyNTYsMTk5MTY3NDQyODI2MTUzMTY0OFwiLFwibmFtZVwiOlwi5Yas5rOz55u45YWz5pa5XCIsXCJhY2Nlc3NUaWNrZXRcIjpcIkg0YXBlMkFaRVcxZFR1OTIwOXNzSDREc3pPWjBoTkZ4eEVlZzRmYTJZaFRVUFA0QkZVZXZmSklhTVdoS1wiLFwicmVmcmVzaFRpY2tldFwiOlwiRlRlZUxIaXJVblhueTBMcXNMcUdyc2dFaGpqVlRRN0pncVptVTBLS0JHVkFCU1ExeENtT3RTWmxRbUdpXCIsXCJleHBpcmVJblwiOjYwNDgwMCxcInJlZnJlc2hFeHBpcmVzSW5cIjo2MDQ4MDAsXCJvcmdJZFwiOjE5OTE2NzQ0MjgyNjE1MzE2NDgsXCJvcmdOYW1lXCI6XCLlhqzms7Pnm7jlhbPmlrlcIixcIm9yZ0lkc1wiOlsxOTkxNjc0NDI4MjYxNTMxNjQ4XSxcInJvbGVzVHlwZXNcIjpbXCJHT1ZfQ0hJTERfQUNDT1VOVFwiXSxcInJvbGVJZHNcIjpbMTk5MDY5MjE3NTA2NjgyNDcwNV0sXCJzY29wZXNcIjpbXSxcInJwY1R5cGVFbnVtXCI6XCJIVFRQXCIsXCJiaW5kTW9iaWxlU2lnblwiOlwiRkFMU0VcIn0iLCJpc3MiOiJwcm8tc2VydmVyIiwiZXhwIjoxNzY1OTU4NDIzfQ.RphPGGnh18RdGZ2vB0-2gKHp6bQg3-rKR4xPvDgH1ek';
- if (token != null && token.isNotEmpty && !isHeartbeat) {
+ if (token != null && token.isNotEmpty && !isHeartbeat && isHaveToken) {
headers['token'] = token;
}
diff --git a/lib/http/modules/auth_api.dart b/lib/http/modules/auth_api.dart
index 748f466..9361e4a 100644
--- a/lib/http/modules/auth_api.dart
+++ b/lib/http/modules/auth_api.dart
@@ -38,6 +38,7 @@ class AuthApi {
ApiService.basePath,
'/login/captcha',
method: Method.get,
+ isHaveToken: false,
data: {},
);
}
@@ -60,7 +61,8 @@ class AuthApi {
static Future