统一用户暂存

master
hs 2025-12-24 16:07:53 +08:00
parent d39a355ede
commit bb4bf15dc6
58 changed files with 1609 additions and 406 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 KiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 KiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 334 KiB

View File

@ -491,7 +491,7 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 62; CURRENT_PROJECT_VERSION = 62;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
@ -503,10 +503,11 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.company.myapp2; MARKETING_VERSION = 2.2.3;
PRODUCT_BUNDLE_IDENTIFIER = uni.UNI85F7A17;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; 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_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
@ -685,7 +686,7 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 62; CURRENT_PROJECT_VERSION = 62;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
@ -697,10 +698,11 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.company.myapp2; MARKETING_VERSION = 2.2.3;
PRODUCT_BUNDLE_IDENTIFIER = uni.UNI85F7A17;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; 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_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -716,7 +718,7 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 62; CURRENT_PROJECT_VERSION = 62;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
@ -728,10 +730,11 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.company.myapp2; MARKETING_VERSION = 2.2.3;
PRODUCT_BUNDLE_IDENTIFIER = uni.UNI85F7A17;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; 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_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 363 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 802 B

After

Width:  |  Height:  |  Size: 950 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 KiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -1,91 +1,91 @@
<?xml version="1.0" encoding="UTF-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"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CADisableMinimumFrameDurationOnPhone</key> <key>CADisableMinimumFrameDurationOnPhone</key>
<true/> <true/>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string> <string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>秦港双控</string> <string>秦港双控</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string> <string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string> <string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSApplicationQueriesSchemes</key> <key>LSApplicationQueriesSchemes</key>
<array> <array>
<string>baidumap</string> <string>baidumap</string>
</array> </array>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/>
<key>NFCReaderUsageDescription</key>
<string>需要NFC权限来读取和写入标签</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/> <true/>
<key>NFCReaderUsageDescription</key>
<string>需要NFC权限来读取和写入标签</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>app需要蓝牙权限连接设备</string>
<key>NSCameraUsageDescription</key>
<string>app需要相机权限来扫描二维码</string>
<key>NSContactsUsageDescription</key>
<string>app需要通讯录权限添加好友</string>
<key>NSHealthShareUsageDescription</key>
<string>app需要读取健康数据</string>
<key>NSHealthUpdateUsageDescription</key>
<string>app需要写入健康数据</string>
<key>NSLocalNetworkUsageDescription</key>
<string>app需要发现本地网络设备</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>我们需要访问您的位置来提供基于位置的服务,例如获取位置展示地图。您的位置数据不会用于其他目的。</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>我们需要访问您的位置来提供基于位置的服务,例如获取位置展示地图。您的位置数据不会用于其他目的。</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>我们需要访问您的位置来提供基于位置的服务,例如获取位置展示地图。您的位置数据不会用于其他目的。</string>
<key>NSMicrophoneUsageDescription</key>
<string>app需要麦克风权限进行语音通话</string>
<key>NSMotionUsageDescription</key>
<string>app需要访问运动数据统计步数</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>app需要保存图片到相册</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>app需要访问相册以上传图片</string>
<key>NSUserNotificationsUsageDescription</key>
<string>app需要发送通知提醒重要信息</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>UIStatusBarHidden</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
<string>NDEF</string>
</array>
</dict> </dict>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>app需要蓝牙权限连接设备</string>
<key>NSCameraUsageDescription</key>
<string>app需要相机权限来扫描二维码</string>
<key>NSContactsUsageDescription</key>
<string>app需要通讯录权限添加好友</string>
<key>NSHealthShareUsageDescription</key>
<string>app需要读取健康数据</string>
<key>NSHealthUpdateUsageDescription</key>
<string>app需要写入健康数据</string>
<key>NSLocalNetworkUsageDescription</key>
<string>app需要发现本地网络设备</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>我们需要访问您的位置来提供基于位置的服务,例如获取位置展示地图。您的位置数据不会用于其他目的。</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>我们需要访问您的位置来提供基于位置的服务,例如获取位置展示地图。您的位置数据不会用于其他目的。</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>我们需要访问您的位置来提供基于位置的服务,例如获取位置展示地图。您的位置数据不会用于其他目的。</string>
<key>NSMicrophoneUsageDescription</key>
<string>app需要麦克风权限进行语音通话</string>
<key>NSMotionUsageDescription</key>
<string>app需要访问运动数据统计步数</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>app需要保存图片到相册</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>app需要访问相册以上传图片</string>
<key>NSUserNotificationsUsageDescription</key>
<string>app需要发送通知提醒重要信息</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>UIStatusBarHidden</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
<string>NDEF</string>
</array>
</dict>
</plist> </plist>

View File

@ -1,9 +1,12 @@
// custom_alert_dialog.dart // custom_alert_dialog.dart
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/main.dart'; // navigatorKey import 'package:qhd_prevention/main.dart'; // navigatorKey
/// ///
enum DialogMode { text, input } enum DialogMode { text, input, inputWithCode }
class CustomAlertDialog extends StatefulWidget { class CustomAlertDialog extends StatefulWidget {
final String title; final String title;
@ -17,6 +20,10 @@ class CustomAlertDialog extends StatefulWidget {
final DialogMode mode; final DialogMode mode;
final bool force; final bool force;
///
/// true false
final Future<bool> Function()? onGetCode;
const CustomAlertDialog({ const CustomAlertDialog({
Key? key, Key? key,
required this.title, required this.title,
@ -29,85 +36,119 @@ class CustomAlertDialog extends StatefulWidget {
this.onInputConfirm, this.onInputConfirm,
this.mode = DialogMode.text, this.mode = DialogMode.text,
this.force = false, this.force = false,
this.onGetCode,
}) : super(key: key); }) : super(key: key);
// ------------------ ------------------ // ------------------ ------------------
static Future<bool> showConfirm( static Future<bool> showConfirm(
BuildContext context, { BuildContext context, {
required String title, required String title,
String content = '', String content = '',
String cancelText = '取消', String cancelText = '取消',
String confirmText = '确定', String confirmText = '确定',
bool barrierDismissible = true, bool barrierDismissible = true,
VoidCallback? onConfirm, VoidCallback? onConfirm,
bool force = false, bool force = false,
}) async { }) async {
final result = await showDialog<bool>( final result = await showDialog<bool>(
context: context, context: context,
barrierDismissible: force ? false : barrierDismissible, barrierDismissible: force ? false : barrierDismissible,
builder: (_) => PopScope( builder:
canPop: false, (_) => PopScope(
child: CustomAlertDialog( canPop: false,
title: title, child: CustomAlertDialog(
content: content, title: title,
cancelText: cancelText, content: content,
confirmText: confirmText, cancelText: cancelText,
onConfirm: onConfirm, confirmText: confirmText,
force: force, onConfirm: onConfirm,
),) force: force,
),
),
); );
return result == true; return result == true;
} }
static Future<void> showAlert( static Future<void> showAlert(
BuildContext context, { BuildContext context, {
required String title, required String title,
String content = '', String content = '',
String confirmText = '确定', String confirmText = '确定',
bool barrierDismissible = true, bool barrierDismissible = true,
VoidCallback? onConfirm, VoidCallback? onConfirm,
bool force = false, bool force = false,
}) async { }) async {
await showDialog<void>( await showDialog<void>(
context: context, context: context,
barrierDismissible: force ? false : barrierDismissible, barrierDismissible: force ? false : barrierDismissible,
builder: (_) => CustomAlertDialog( builder:
title: title, (_) => CustomAlertDialog(
content: content, title: title,
cancelText: '', content: content,
confirmText: confirmText, cancelText: '',
onConfirm: onConfirm, confirmText: confirmText,
force: force, onConfirm: onConfirm,
), force: force,
),
); );
} }
static Future<String?> showInput( static Future<String?> showInput(
BuildContext context, { BuildContext context, {
required String title, required String title,
String hintText = '', String hintText = '',
String cancelText = '取消', String cancelText = '取消',
String confirmText = '确定', String confirmText = '确定',
bool barrierDismissible = true, bool barrierDismissible = true,
bool force = false, bool force = false,
}) async { }) async {
final result = await showDialog<String?>( final result = await showDialog<String?>(
context: context, context: context,
barrierDismissible: force ? false : barrierDismissible, barrierDismissible: force ? false : barrierDismissible,
builder: (_) => CustomAlertDialog( builder:
title: title, (_) => CustomAlertDialog(
hintText: hintText, title: title,
cancelText: cancelText, hintText: hintText,
confirmText: confirmText, cancelText: cancelText,
mode: DialogMode.input, confirmText: confirmText,
force: force, mode: DialogMode.input,
), force: force,
),
); );
// / null String // / null String
return result; return result;
} }
/// +
static Future<String?> showInputWithCode(
BuildContext context, {
required String title,
String hintText = '',
String cancelText = '取消',
String confirmText = '确定',
bool barrierDismissible = true,
bool force = false,
Future<bool> Function()? onGetCode,
ValueChanged<String>? onConfirm, // <--
}) async {
final result = await showDialog<String?>(
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 @override
_CustomAlertDialogState createState() => _CustomAlertDialogState(); _CustomAlertDialogState createState() => _CustomAlertDialogState();
@ -117,6 +158,11 @@ class _CustomAlertDialogState extends State<CustomAlertDialog> {
late TextEditingController _controller; late TextEditingController _controller;
bool _isClosing = false; bool _isClosing = false;
//
Timer? _timer;
int _seconds = 0;
static const int _defaultCountdown = 60;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -125,6 +171,7 @@ class _CustomAlertDialogState extends State<CustomAlertDialog> {
@override @override
void dispose() { void dispose() {
_timer?.cancel();
_controller.dispose(); _controller.dispose();
super.dispose(); super.dispose();
} }
@ -144,6 +191,41 @@ class _CustomAlertDialogState extends State<CustomAlertDialog> {
} }
} }
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<void> _onGetCodePressed() async {
if (_seconds > 0) return; //
//
if (widget.onGetCode != null) {
await widget.onGetCode!();
_startCountdown();
} else {
// 便
_startCountdown();
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return PopScope( return PopScope(
@ -177,14 +259,11 @@ class _CustomAlertDialogState extends State<CustomAlertDialog> {
padding: const EdgeInsets.symmetric(horizontal: 24), padding: const EdgeInsets.symmetric(horizontal: 24),
child: Text( child: Text(
widget.content, widget.content,
style: const TextStyle( style: const TextStyle(fontSize: 16, color: Colors.black54),
fontSize: 16,
color: Colors.black54,
),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
) )
else else if (widget.mode == DialogMode.input)
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 20), padding: const EdgeInsets.symmetric(horizontal: 20),
child: TextField( child: TextField(
@ -204,6 +283,45 @@ class _CustomAlertDialogState extends State<CustomAlertDialog> {
), ),
), ),
), ),
)
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 SizedBox(height: 20),
const Divider(height: 1), const Divider(height: 1),

View File

@ -18,7 +18,7 @@ class ApiService {
static final String baseImgPath = static final String baseImgPath =
isProduct isProduct
? "https://jpfz.qhdsafety.com/gbsFileTest/" ? "https://jpfz.qhdsafety.com/gbsFileTest/"
: "http://192.168.20.100:9787/mnt/"; // : "http://192.168.20.240:9787/mnt/"; //
static const publicKey = static const publicKey =
'0402df2195296d4062ac85ad766994d73e871b887e18efb9a9a06b4cebc72372869b7da6c347c129dee2b46a0f279ff066b01c76208c2a052af75977c722a2ccee'; '0402df2195296d4062ac85ad766994d73e871b887e18efb9a9a06b4cebc72372869b7da6c347c129dee2b46a0f279ff066b01c76208c2a052af75977c722a2ccee';

View File

@ -76,6 +76,7 @@ class HttpManager {
CancelToken? cancelToken, CancelToken? cancelToken,
String? contentType, // Content-Type jsonContentType String? contentType, // Content-Type jsonContentType
bool isHeartbeat = false, bool isHeartbeat = false,
bool isHaveToken = true,
}) async { }) async {
printLongString('参数:${jsonEncode(data)}'); printLongString('参数:${jsonEncode(data)}');
Response resp; Response resp;
@ -87,7 +88,7 @@ class HttpManager {
}; };
final token = SessionService.instance.token ?? ''; final token = SessionService.instance.token ?? '';
// final token = 'jjb-saas-auth:oauth:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJjbGllbnRJZFwiOlwieGdmemRcIixcImFjY291bnRJZFwiOjE5OTE2NzQ0MzEzMzY4NDk0MDgsXCJ1c2VyVHlwZUVudW1cIjpcIlBMQVRGT1JNXCIsXCJ1c2VySWRcIjoxOTkxNjc0NDI4MjYxNTMxNjQ4LFwidGVuYW50SWRcIjoxOTkxNjc0NDI4MjYxNTMxNjQ4LFwidGVuYW50TmFtZVwiOlwi5Yas5rOz55u45YWz5pa5XCIsXCJ0ZW5hbnRUeXBlSWRcIjoxOTkwNjkzMzg4MDcyMTI0NDE2LFwidGVuYW50UGFyZW50SWRzXCI6XCIwLDE5ODM3NzMwMTMwODYwNDgyNTYsMTk5MTY3NDQyODI2MTUzMTY0OFwiLFwibmFtZVwiOlwi5Yas5rOz55u45YWz5pa5XCIsXCJhY2Nlc3NUaWNrZXRcIjpcIkg0YXBlMkFaRVcxZFR1OTIwOXNzSDREc3pPWjBoTkZ4eEVlZzRmYTJZaFRVUFA0QkZVZXZmSklhTVdoS1wiLFwicmVmcmVzaFRpY2tldFwiOlwiRlRlZUxIaXJVblhueTBMcXNMcUdyc2dFaGpqVlRRN0pncVptVTBLS0JHVkFCU1ExeENtT3RTWmxRbUdpXCIsXCJleHBpcmVJblwiOjYwNDgwMCxcInJlZnJlc2hFeHBpcmVzSW5cIjo2MDQ4MDAsXCJvcmdJZFwiOjE5OTE2NzQ0MjgyNjE1MzE2NDgsXCJvcmdOYW1lXCI6XCLlhqzms7Pnm7jlhbPmlrlcIixcIm9yZ0lkc1wiOlsxOTkxNjc0NDI4MjYxNTMxNjQ4XSxcInJvbGVzVHlwZXNcIjpbXCJHT1ZfQ0hJTERfQUNDT1VOVFwiXSxcInJvbGVJZHNcIjpbMTk5MDY5MjE3NTA2NjgyNDcwNV0sXCJzY29wZXNcIjpbXSxcInJwY1R5cGVFbnVtXCI6XCJIVFRQXCIsXCJiaW5kTW9iaWxlU2lnblwiOlwiRkFMU0VcIn0iLCJpc3MiOiJwcm8tc2VydmVyIiwiZXhwIjoxNzY1OTU4NDIzfQ.RphPGGnh18RdGZ2vB0-2gKHp6bQg3-rKR4xPvDgH1ek'; // 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; headers['token'] = token;
} }

View File

@ -38,6 +38,7 @@ class AuthApi {
ApiService.basePath, ApiService.basePath,
'/login/captcha', '/login/captcha',
method: Method.get, method: Method.get,
isHaveToken: false,
data: {}, data: {},
); );
} }
@ -60,7 +61,8 @@ class AuthApi {
static Future<Map<String, dynamic>> getUserData() { static Future<Map<String, dynamic>> getUserData() {
return HttpManager().request( return HttpManager().request(
ApiService.basePath, ApiService.basePath,
'/basicInfo/user/getInfo', // '/basicInfo/user/getInfo',
'/basicInfo/user/${SessionService.instance.accountId}',
method: Method.get, method: Method.get,
data: {}, data: {},
); );

View File

@ -1,6 +1,7 @@
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:qhd_prevention/http/ApiService.dart'; import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/http/HttpManager.dart'; import 'package:qhd_prevention/http/HttpManager.dart';
import 'package:qhd_prevention/services/SessionService.dart';
class BasicInfoApi { class BasicInfoApi {
/// ///
@ -12,6 +13,17 @@ class BasicInfoApi {
data: {...data}, data: {...data},
); );
} }
///
static Future<Map<String, dynamic>> logout(Map data) {
return HttpManager().request(
ApiService.basePath + (ApiService.isProduct ? '/basicInfo' : '/basicInfo') ,
'/appuser/logOut',
method: Method.post,
data: {
...data
},
);
}
/// ///
static Future<Map<String, dynamic>> sendRegisterSms(Map data) { static Future<Map<String, dynamic>> sendRegisterSms(Map data) {
@ -42,15 +54,6 @@ class BasicInfoApi {
data: {...data}, data: {...data},
); );
} }
//
static Future<Map<String, dynamic>> getEntryInfo(String id) {
return HttpManager().request(
ApiService.basePath + (ApiService.isProduct ? '/basicInfo' : '/basicInfo') ,
'/app/userCorpRecord/getInfoById/$id',
method: Method.get,
data: {},
);
}
/// ///
static Future<Map<String, dynamic>> getUserMessage(String value) { static Future<Map<String, dynamic>> getUserMessage(String value) {
return HttpManager().request( return HttpManager().request(
@ -79,6 +82,44 @@ class BasicInfoApi {
data: {...data}, data: {...data},
); );
} }
///
static Future<Map<String, dynamic>> getFirmListByUser(Map data) {
return HttpManager().request(
ApiService.basePath + (ApiService.isProduct ? '/basicInfo' : '/basicInfo') ,
'/app/userCorpRecord/list',
method: Method.post,
data: {...data},
);
}
///
static Future<Map<String, dynamic>> getFirmInfo(String id) {
return HttpManager().request(
ApiService.basePath + (ApiService.isProduct ? '/basicInfo' : '/basicInfo') ,
'/app/userCorpRecord/getInfoById/$id',
method: Method.get,
data: {},
);
}
///
static Future<Map<String, dynamic>> leaveApply(Map data) {
return HttpManager().request(
ApiService.basePath + (ApiService.isProduct ? '/basicInfo' : '/basicInfo') ,
'/appuser/appUserResignation',
method: Method.post,
data: {...data},
);
}
///
static Future<Map<String, dynamic>> getJoinFirmList() {
return HttpManager().request(
ApiService.basePath + (ApiService.isProduct ? '/basicInfo' : '/basicInfo') ,
'/appuser/getUserCorpList/${SessionService.instance.accountId}',
method: Method.post,
data: {},
);
}

View File

@ -17,7 +17,6 @@ class FileApi {
} }
final fileName = file.path.split(Platform.pathSeparator).last; final fileName = file.path.split(Platform.pathSeparator).last;
return HttpManager().uploadImages( return HttpManager().uploadImages(
baseUrl: ApiService.basePath, baseUrl: ApiService.basePath,
path: '/basicInfo/imgFiles/save', path: '/basicInfo/imgFiles/save',

View File

@ -9,6 +9,7 @@ import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/pages/home/scan_page.dart'; import 'package:qhd_prevention/pages/home/scan_page.dart';
import 'package:qhd_prevention/pages/home/unit/unit_tab_page.dart'; import 'package:qhd_prevention/pages/home/unit/unit_tab_page.dart';
import 'package:qhd_prevention/pages/main_tab.dart'; import 'package:qhd_prevention/pages/main_tab.dart';
import 'package:qhd_prevention/pages/user/choose_userFirm_page.dart';
import 'package:qhd_prevention/pages/user/firm_list_page.dart'; import 'package:qhd_prevention/pages/user/firm_list_page.dart';
import 'package:qhd_prevention/tools/h_colors.dart'; import 'package:qhd_prevention/tools/h_colors.dart';
import 'package:qhd_prevention/tools/tools.dart'; import 'package:qhd_prevention/tools/tools.dart';
@ -422,6 +423,10 @@ class HomePageState extends RouteAwareState<HomePage>
); );
} }
Future<void> _joinFirm() async {
pushPage(FirmListPage(isBack: true,), context);
}
// //
Widget _buildFixedTopIcons(BuildContext context) { Widget _buildFixedTopIcons(BuildContext context) {
final double statusBar = MediaQuery.of(context).padding.top; final double statusBar = MediaQuery.of(context).padding.top;
@ -446,6 +451,19 @@ class HomePageState extends RouteAwareState<HomePage>
), ),
), ),
), ),
GestureDetector(
onTap: _joinFirm,
child: Container(
width: 38,
height: 38,
alignment: Alignment.center,
child: Image.asset(
"assets/icon-apps/home_add.png",
width: 22,
height: 22,
),
),
),
], ],
), ),
); );
@ -594,7 +612,7 @@ class HomePageState extends RouteAwareState<HomePage>
CustomButton( CustomButton(
text: '点击入职企业', text: '点击入职企业',
onPressed: () { onPressed: () {
pushPage(FirmListPage(), context); pushPage(FirmListPage(isBack: true,), context);
}, },
) )
], ],

View File

@ -0,0 +1,475 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/constants/app_enums.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/customWidget/bottom_picker.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/item_list_widget.dart';
import 'package:qhd_prevention/customWidget/photo_picker_row.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/main_tab.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/services/SessionService.dart';
import 'package:qhd_prevention/tools/tools.dart';
class UnitJoinDetailPage extends StatefulWidget {
const UnitJoinDetailPage({super.key, required this.firmId});
final String firmId;
@override
State<UnitJoinDetailPage> createState() => _UnitJoinDetailPageState();
}
class _UnitJoinDetailPageState extends State<UnitJoinDetailPage> {
Map<String, dynamic> pd = {
};
late bool _isEdit;
String _genderText = '';
String _birthText = '';
List<String> _idCardImgList = [];
List<String> _idCartImgIds = [];
List<String> _idCardImgRemoveList = [];
List<dynamic> _wenhuachengduList = [];
List<dynamic> _zhengzhimianmaoList = [];
List<dynamic> _hunyinList = [
{"name": "已婚", "value": 1},
{"name": "未婚", "value": 0},
];
List<String> idPhotos = [];
@override
void initState() {
super.initState();
_isEdit = false;
_getUserDetail();
_getKeyValues();
}
Future<void> _getUserDetail() async {
final res = await BasicInfoApi.getFirmInfo(
widget.firmId,
);
if (res['success']) {
final data = res['data'];
_genderText = data['sex'] ?? '';
_birthText = data['birthday'] ?? '';
final eqForeignKey = data['userId'];
await FileApi.getImagePathWithType(
eqForeignKey,
'',
UploadFileType.idCardPhoto,
).then((result) {
if (result['success']) {
List files = result['data'] ?? [];
_idCardImgList =
files.map((item) => item['filePath'].toString()).toList();
_idCartImgIds = files.map((item) => item['id'].toString()).toList();
// final filePath = fileData.first['filePath'] ?? '';
}
});
setState(() {
pd = data;
try{
final idCardBase64 = utf8.decode(base64.decode(pd['userIdCard']));
if (idCardBase64.isNotEmpty) {
pd['userIdCard'] =idCardBase64;
}
}catch(e){
print(e);
}
});
}
}
Future<void> _getKeyValues() async {
await BasicInfoApi.getDictValues('wenhuachengdu').then((res) {
_wenhuachengduList = res['data'];
});
await BasicInfoApi.getDictValues('zhengzhimianmao').then((res) {
_zhengzhimianmaoList = res['data'];
});
}
Future<void> _saveSuccess() async {
pd['userIdCard'] = base64.encode(utf8.encode(pd['userIdCard']));
await BasicInfoApi.updateUserInfo(pd).then((res) {
LoadingDialogHelper.hide();
if (res['success']) {
ToastUtil.showNormal(context, '保存成功');
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (_) => const MainPage(isChooseFirm: false)),
);
} else {
ToastUtil.showNormal(context, '保存失败');
}
});
}
@override
Widget build(BuildContext context) {
bool isShow = _isEdit;
if (!_isEdit && FormUtils.hasValue(pd, 'id')) {
isShow = true;
}
return Scaffold(
appBar: MyAppbar(
title: '查看信息',
),
body: SafeArea(
child: ItemListWidget.itemContainer(
horizontal: 5,
isShow ? ListView(
children: [
RepairedPhotoSection(
title: '照片',
inlineSingle: true,
isRequired: _isEdit,
initialMediaPaths:
FormUtils.hasValue(pd, 'userAvatarUrl')
? [
'${ApiService.baseImgPath}${pd['userAvatarUrl'] ?? ''}',
]
: [],
horizontalPadding: _isEdit ? 12 : 0,
inlineImageWidth: 60,
isFaceImage: true,
isEdit: _isEdit,
onChanged: (files) {
if (files.isEmpty) {
return;
}
pd['faceFiles'] = files.first.path;
},
onAiIdentify: () {},
// onMediaRemovedForIndex: (index) async {
// final deleFile = pd['userAvatarUrl'] ?? '';
// if (deleFile.contains(UploadFileType.idCardPhoto.path)) {
// _idCardImgRemoveList.add(deleFile);
// }
// },
),
if (_isEdit)
ItemListWidget.itemContainer(
const Text(
'温馨提示:该照片为进入项目施工场所口门人脸识别使用',
style: TextStyle(color: Colors.red, fontSize: 10),
),
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '姓名:',
isRequired: true,
hintText: '请输入姓名',
text: pd['name'] ?? '',
isEditable: _isEdit,
onChanged: (value) {
pd['name'] = value;
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '手机号:',
isRequired: true,
text: pd['username'] ?? '',
isNumericInput: true,
hintText: '请输入手机号',
strongRequired: _isEdit,
isEditable: false,
),
const Divider(),
// 使 onChanged value
ItemListWidget.singleLineTitleText(
label: '身份证:',
isRequired: true,
hintText: '请输入身份证号',
text: pd['userIdCard'] ?? '',
isEditable: _isEdit,
onChanged: (value) {
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '民族:',
isEditable: _isEdit,
text: pd['nationName'] ?? '请选择',
isRequired: _isEdit,
onTap: () async {
final found = await BottomPicker.show(
context,
items: nationMapList,
itemBuilder:
(i) =>
Text(i['name']!, textAlign: TextAlign.center),
initialIndex: 0,
);
//FocusHelper.clearFocus(context);
if (found != null) {
setState(() {
pd['nationName'] = found['name'];
pd['nation'] = found['code'];
});
}
},
),
const Divider(),
//
ItemListWidget.selectableLineTitleTextRightButton(
label: '性别:',
isEditable: false,
text: _genderText,
strongRequired: _isEdit,
isRequired: true,
onTap: () {
//
showModalBottomSheet(
context: context,
builder: (_) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: const Text(''),
onTap: () {
setState(() {
pd['gender'] = '';
_genderText = '';
});
Navigator.pop(context);
},
),
ListTile(
title: const Text(''),
onTap: () {
setState(() {
pd['gender'] = '';
_genderText = '';
});
Navigator.pop(context);
},
),
],
);
},
);
},
),
const Divider(),
//
ItemListWidget.selectableLineTitleTextRightButton(
label: '出生年月:',
isEditable: false,
text: _birthText,
strongRequired: _isEdit,
isRequired: true,
onTap: () async {
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '户口所在地:',
isRequired: _isEdit,
hintText: '请输入户口所在地',
text: pd['locationAddress'] ?? '',
isEditable: _isEdit,
onChanged: (value) {
pd['locationAddress'] = value;
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '现住址:',
isRequired: true,
text: pd['currentAddress'] ?? '',
hintText: '请输入现住址',
isEditable: _isEdit,
onChanged: (value) {
pd['currentAddress'] = value;
},
),
const Divider(),
if (_isEdit || _idCardImgList.isNotEmpty)
RepairedPhotoSection(
title: '身份证照片',
isRequired: _isEdit,
maxCount: 2,
initialMediaPaths:
_idCardImgList
.map(
(item) =>
ApiService.baseImgPath + item,
)
.toList(),
isEdit: _isEdit,
horizontalPadding: _isEdit ? 12 : 0,
inlineImageWidth: 60,
onChanged: (files) {
idPhotos = files.map((file) => file.path).toList();
},
onMediaRemovedForIndex: (index) async {
final deleFile = _idCardImgList[index];
final deleId = _idCartImgIds[index];
if (deleFile.contains(UploadFileType.idCardPhoto.path)) {
_idCardImgList.removeAt(index);
_idCartImgIds.removeAt(index);
_idCardImgRemoveList.add(deleId);
}
},
onAiIdentify: () {
/* ... */
},
),
if (_isEdit)
ItemListWidget.itemContainer(
const Text(
'温馨提示用户要上传身份证正反面身份证照片数量是2张才能进行人员培训',
style: TextStyle(color: Colors.red, fontSize: 10),
),
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '文化程度:',
isEditable: _isEdit,
text: pd['culturalLevelName'] ?? '请选择',
isRequired: _isEdit,
onTap: () async {
final found = await BottomPicker.show(
context,
items: _wenhuachengduList,
itemBuilder:
(i) => Text(
i['dictLabel']!,
textAlign: TextAlign.center,
),
initialIndex: 0,
);
//FocusHelper.clearFocus(context);
if (found != null) {
setState(() {
pd['culturalLevelName'] = found['dictLabel'];
pd['culturalLevel'] = found['dictValue'];
});
}
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '政治面貌:',
isEditable: _isEdit,
text: pd['politicalAffiliationName'] ?? '请选择',
isRequired: _isEdit,
onTap: () async {
final found = await BottomPicker.show(
context,
items: _zhengzhimianmaoList,
itemBuilder:
(i) => Text(
i['dictLabel']!,
textAlign: TextAlign.center,
),
initialIndex: 0,
);
//FocusHelper.clearFocus(context);
if (found != null) {
setState(() {
pd['politicalAffiliationName'] = found['dictLabel'];
pd['politicalAffiliation'] = found['dictValue'];
});
}
},
),
const Divider(),
ItemListWidget.selectableLineTitleTextRightButton(
label: '婚姻状态:',
isEditable: _isEdit,
text: pd['maritalStatusName'] ?? '请选择',
isRequired: _isEdit,
onTap: () async {
final found = await BottomPicker.show(
context,
items: _hunyinList,
itemBuilder:
(i) =>
Text(i['name']!, textAlign: TextAlign.center),
initialIndex: 0,
);
//FocusHelper.clearFocus(context);
if (found != null) {
setState(() {
pd['maritalStatusName'] = found['name'];
pd['maritalStatus'] = found['value'];
});
}
},
),
const Divider(),
ListItemFactory.createYesNoSection(
title: "是否流动人员:",
horizontalPadding: 2,
verticalPadding: 0,
yesLabel: "",
noLabel: "",
text: pd['flowFlag'] == 1 ? '' : '',
isRequired: true,
isEdit: _isEdit,
groupValue: (pd['flowFlag'] ?? 0) == 1,
onChanged: (val) {
setState(() {
pd['flowFlag'] = val ? 1 : 0;
});
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '电子邮箱:',
isRequired: false,
isNumericInput: false,
hintText: '请输入电子邮箱',
text: pd['email'] ?? '',
isEditable: _isEdit,
onChanged: (value) {
pd['email'] = value;
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '部门:',
isRequired: false,
isNumericInput: false,
hintText: '',
text: pd['departmentName'] ?? '',
isEditable: _isEdit,
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '岗位(工种):',
isRequired: false,
isNumericInput: false,
hintText: '',
text: pd['postName'] ?? '',
isEditable: _isEdit,
),
const Divider(),
],
) : NoDataWidget.show(),
),
),
);
}
}

View File

@ -0,0 +1,249 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/pages/home/unit/unit_join_detail_page.dart';
import 'package:qhd_prevention/pages/home/unit/unit_quit_apply_page.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/services/SessionService.dart';
import 'package:qhd_prevention/services/StorageService.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/http/ApiService.dart';
class UnitJoinListPage extends StatefulWidget {
const UnitJoinListPage({Key? key}) : super(key: key);
@override
_UnitJoinListPageState createState() => _UnitJoinListPageState();
}
class _UnitJoinListPageState extends State<UnitJoinListPage> {
// Data and state variables
List<dynamic> list = [];
int currentPage = 1;
int rows = 10;
int totalPage = 1;
bool isLoading = false;
List<Map<String, dynamic>> flowList = [];
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final ScrollController _scrollController = ScrollController();
final employmentFlag = {'0': '离职', '1': '在职', '3': '未入职'};
final statusInfo = {
'1': '待审批',
'2': '通过',
'3': '驳回',
};
@override
void initState() {
super.initState();
_fetchData();
_scrollController.addListener(_onScroll);
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
void _onScroll() {
if (_scrollController.position.pixels >=
_scrollController.position.maxScrollExtent &&
!isLoading) {
if (currentPage < totalPage) {
currentPage++;
_fetchData();
}
}
}
String formatDate(String dateTimeStr) {
if (dateTimeStr == null || dateTimeStr.isEmpty) {
return '';
}
// DateTime
DateTime dateTime = DateTime.parse(dateTimeStr);
final time = dateTime == null ? '' : '${dateTime.year}${dateTime.month}${dateTime.day}';
//
return time;
}
Future<void> _fetchData() async {
if (isLoading) return;
setState(() => isLoading = true);
try {
final data = {
'pageIndex': currentPage,
'pageSize': rows,
'eqUserId': SessionService.instance.accountId
};
final response = await BasicInfoApi.getFirmListByUser(data);
setState(() {
if (currentPage == 1) {
list = response['data'];
} else {
list.addAll(response['data']);
}
Map<String, dynamic> page = response['page'];
totalPage = page['totalPage'] ?? 1;
isLoading = false;
});
} catch (e) {
print('Error fetching data: $e');
setState(() => isLoading = false);
}
}
//
void _goToDetail(Map<String, dynamic> item) async {
await pushPage(
UnitJoinDetailPage(firmId: item['id'],),
context,
);
_fetchData();
}
//
void _leaveFirm(Map<String, dynamic> item) async {
await pushPage(
UnitQuitApplyPage(firmInfo: item,),
context,
);
_fetchData();
}
Widget _buildListItem(Map<String, dynamic> item) {
final startTime = formatDate(item['startTime'] ?? '');
final endTime = item['employmentFlag'] == 1 ? '至今' : formatDate(item['endTime'] ?? '');
return Card(
color: Colors.white,
margin: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () => _goToDetail(item),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'单位名称:${item['corpinfoName'] ?? ''}',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
],
),
const SizedBox(height: 8),
if (startTime.isNotEmpty && endTime.isNotEmpty)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Text("就职时间:$startTime - $endTime")],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Text("就职状态: ${employmentFlag['${item['employmentFlag']}'] ?? ''}")],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"审核状态: ${statusInfo['${item['status']}'] ?? ''}",
maxLines: 5,
overflow: TextOverflow.ellipsis,
),
],
),
const SizedBox(height: 8),
_statusButtons(item),
],
),
),
),
);
}
Widget _statusButtons(Map<String, dynamic> item) {
final List<Widget> buttons = [];
final List<Widget> buttonRowChildren = [];
buttons.add(
CustomButton(
text: '查看',
backgroundColor: Colors.blue,
onPressed: () {
_goToDetail(item);
},
),
);
if (item['employmentFlag'] == 1) {
buttons.add(
CustomButton(
text: '离职',
backgroundColor: Colors.blue,
onPressed: () {
_leaveFirm(item);
},
),
);
}
for (int i = 0; i < buttons.length; i++) {
buttonRowChildren.add(
Expanded(child: SizedBox(height: 40, child: buttons[i])),
);
if (i != buttons.length - 1) {
buttonRowChildren.add(const SizedBox(width: 10));
}
}
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: buttonRowChildren,
);
}
Widget _buildListContent() {
if (isLoading && list.isEmpty) {
//
return Center(child: CircularProgressIndicator());
} else if (list.isEmpty) {
//
return NoDataWidget.show();
} else {
//
return ListView.builder(
padding: EdgeInsets.zero,
controller: _scrollController,
itemCount: list.length + (isLoading ? 1 : 0),
itemBuilder: (context, index) {
if (index >= list.length) {
//
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Center(child: CircularProgressIndicator()),
);
}
return _buildListItem(list[index]);
},
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: MyAppbar(title: '就职单位', actions: []),
body: SafeArea(child: _buildListContent()),
);
}
}

View File

@ -0,0 +1,96 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/item_list_widget.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/services/SessionService.dart';
import 'package:qhd_prevention/tools/tools.dart';
class UnitQuitApplyPage extends StatefulWidget {
const UnitQuitApplyPage({super.key, required this.firmInfo});
final Map firmInfo;
@override
State<UnitQuitApplyPage> createState() => _UnitQuitApplyPageState();
}
class _UnitQuitApplyPageState extends State<UnitQuitApplyPage> {
String _resignationReason = '';
@override
void initState() {
super.initState();
}
Future<void> _submit() async {
final Map data = {
'corpinfoId' : widget.firmInfo['corpinfoId'],
'id' : widget.firmInfo['userId'],
'resignationReason' : _resignationReason,
};
LoadingDialogHelper.show();
try {
final result = await BasicInfoApi.leaveApply(data);
LoadingDialogHelper.hide();
if (result['success'] == true) {
ToastUtil.showNormal(context, '申请已提交');
Navigator.pop(context);
}else{
ToastUtil.showNormal(context, result['errMessage']);
}
}catch(e){
LoadingDialogHelper.hide();
ToastUtil.showNormal(context, '申请失败');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '离职申请'),
body: SafeArea(
child: ItemListWidget.itemContainer(
Column(
children: [
ItemListWidget.singleLineTitleText(
label: '离职申请单位',
text: widget.firmInfo['corpinfoName'] ?? '',
isEditable: false,
),
const Divider(),
ItemListWidget.multiLineTitleTextField(
label: '离职原因',
isEditable: true,
isRequired: false,
hintText: '请输入原因',
onChanged: (value) {
_resignationReason = value;
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '申请时间',
text: DateFormat('yyyy年MM月dd日').format(DateTime.now()),
isEditable: false,
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '申请人',
text: SessionService.instance.name,
isEditable: false,
),
const Divider(),
const SizedBox(height: 30,),
CustomButton(text: '提交', onPressed: () {
_submit();
},)
],
),
),
),
);
}
}

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/work_tab_icon_grid.dart'; import 'package:qhd_prevention/customWidget/work_tab_icon_grid.dart';
import 'package:qhd_prevention/http/ApiService.dart'; import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/customWidget/IconBadgeButton.dart'; import 'package:qhd_prevention/customWidget/IconBadgeButton.dart';
import 'package:qhd_prevention/pages/home/unit/unit_join_list_page.dart';
import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/tools/tools.dart'; import 'package:qhd_prevention/tools/tools.dart';
import 'package:qhd_prevention/common/route_aware_state.dart'; import 'package:qhd_prevention/common/route_aware_state.dart';
@ -42,6 +43,11 @@ class _UnitTabPageState extends RouteAwareState<UnitTabPage> {
switch (index) { switch (index) {
case 0: case 0:
break; break;
case 1:
pushPage(UnitJoinListPage(), context);
break;
default:
break;
} }
_getData(); _getData();
} }

View File

@ -131,6 +131,7 @@ class _ForgotPwdPageState extends State<ForgotPwdPage> {
} }
if (!_canSend) return; if (!_canSend) return;
setState(() => _isSending = true); setState(() => _isSending = true);
LoadingDialogHelper.show(); LoadingDialogHelper.show();
try { try {
@ -140,7 +141,7 @@ class _ForgotPwdPageState extends State<ForgotPwdPage> {
ToastUtil.showNormal(context, '验证码已发送'); ToastUtil.showNormal(context, '验证码已发送');
_startCountdown(60); _startCountdown(60);
} else { } else {
ToastUtil.showNormal(context, res?['message'] ?? '发送验证码失败'); ToastUtil.showNormal(context, res?['errMessage'] ?? '发送验证码失败');
} }
} catch (e) { } catch (e) {
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
@ -244,7 +245,6 @@ class _ForgotPwdPageState extends State<ForgotPwdPage> {
return null; return null;
}, },
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
// //

View File

@ -0,0 +1,161 @@
import 'dart:io';
import 'dart:convert';
import 'package:qhd_prevention/services/StorageService.dart';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/main_tab.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/services/SessionService.dart';
import 'package:qhd_prevention/services/auth_service.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:shared_preferences/shared_preferences.dart';
class MineChangeFirmPage extends StatefulWidget {
const MineChangeFirmPage({super.key});
@override
State<MineChangeFirmPage> createState() => _MineChangeFirmPageState();
}
class _MineChangeFirmPageState extends State<MineChangeFirmPage> {
//
List<dynamic> list = [];
String joinedUnitId = '';
@override
void initState() {
super.initState();
Map jsonData = json.decode(
StorageService.instance.getString('key.saveJoinFirmInfo') ?? '{}',
);
joinedUnitId = jsonData['unitId'] ?? '';
_getList();
}
void _getList() async {
LoadingDialogHelper.show();
var res = await BasicInfoApi.getJoinFirmList();
LoadingDialogHelper.dismiss();
if (res['success'] == true) {
setState(() {
list = res['data'];
});
}
}
//
Future<void> _changeAccount(dynamic data) async {
await CustomAlertDialog.showConfirm(
context,
title: '温馨提示',
content: '确认切换到企业"${data['corpName']}"?',
onConfirm: () async {
LoadingDialogHelper.show();
final prefs = await SharedPreferences.getInstance();
final phone = prefs.getString('savePhone') ?? '';
final pwd = prefs.getString('savePass') ?? '';
var params = {'unitId': data['id']};
try {
var res = await AuthService.gbsLogin(phone, pwd, params);
LoadingDialogHelper.dismiss();
if (res['success'] == true) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => const MainPage(isChooseFirm: true),
),
);
} else {
ToastUtil.showNormal(context, res['errMessage'] ?? '切换账户失败,请重试');
}
} catch (e) {
LoadingDialogHelper.dismiss();
ToastUtil.showNormal(context, '切换账户失败,请重试');
}
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
// backgroundColor: Colors.white,
appBar: MyAppbar(title: '切换账号'),
body: Column(
children: [
Container(
width: MediaQuery.of(context).size.width,
color: Colors.blue.shade50,
padding: const EdgeInsets.symmetric(vertical: 8),
// height: 40,
child: Center(child: Text('点击企业名称以切换账号')),
),
const SizedBox(height: 10),
Container(
height: 40.0 * list.length,
width: MediaQuery.of(context).size.width - 24,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey.shade300),
),
child:
list.isEmpty
? NoDataWidget.show()
: ListView.builder(
padding: EdgeInsets.zero,
itemCount: list.length,
itemBuilder: (context, index) {
if (index >= list.length) {
//
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Center(child: CircularProgressIndicator()),
);
}
var data = list[index];
return SizedBox(
height: 40.0,
child: Column(
children: [
GestureDetector(
onTap: () async {
_changeAccount(data);
},
child: SizedBox(
height: 39.0,
child: Center(
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text('${data['corpName'] ?? 'aaaa'}'),
if (joinedUnitId ==
data['id']) ...[
const Icon(
Icons.check,
size: 20,
color: Colors.green,
),
] else ...[
const SizedBox(width: 20),
],
],
),
),
),
),
if (index < list.length - 1)
const Divider(height: 1),
],
),
);
},
),
),
],
),
);
}
}

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'dart:io'; import 'dart:io';
import '../../../../../customWidget/photo_picker_row.dart'; import '../../../../../customWidget/photo_picker_row.dart';
@ -274,20 +275,7 @@ class _FeedbackPageState extends State<FeedbackPage> {
// //
SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
child: ElevatedButton( child: CustomButton(text: '提交', onPressed: _submitFeedback,)
onPressed: _submitFeedback,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: const Text(
'提交',
style: TextStyle(fontSize: 18, color: Colors.white),
),
),
), ),
], ],
), ),

View File

@ -4,9 +4,11 @@ import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart'; import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/home/scan_page.dart'; import 'package:qhd_prevention/pages/home/scan_page.dart';
import 'package:qhd_prevention/pages/home/userinfo_page.dart'; import 'package:qhd_prevention/pages/home/userinfo_page.dart';
import 'package:qhd_prevention/pages/mine/face_ecognition_page.dart'; import 'package:qhd_prevention/pages/mine/face_ecognition_page.dart';
import 'package:qhd_prevention/pages/mine/mine_change_firm_page.dart';
import 'package:qhd_prevention/pages/mine/mine_feedback_page.dart'; import 'package:qhd_prevention/pages/mine/mine_feedback_page.dart';
import 'package:qhd_prevention/pages/mine/mine_set_pwd_page.dart'; import 'package:qhd_prevention/pages/mine/mine_set_pwd_page.dart';
import 'package:qhd_prevention/pages/mine/onboarding_full_page.dart'; import 'package:qhd_prevention/pages/mine/onboarding_full_page.dart';
@ -107,7 +109,7 @@ class MinePageState extends State<MinePage> {
MaterialPageRoute( MaterialPageRoute(
builder: (context) => const LoginPage(), builder: (context) => const LoginPage(),
), ),
(Route<dynamic> route) => false, (Route<dynamic> route) => false,
); );
}, },
); );
@ -154,6 +156,69 @@ class MinePageState extends State<MinePage> {
); );
} }
Future<void> _logout() async {
LoadingDialogHelper.show();
///
final firmData = await BasicInfoApi.getJoinFirmList();
if (firmData['success'] == true) {
final firmList = firmData['data'];
LoadingDialogHelper.dismiss();
if (firmList.isNotEmpty) {
CustomAlertDialog.showAlert(
context,
title: '温馨提示',
content: '您目前还有入职信息无法直接注销。\n请先在“就职单位”页面中离职。',
);
} else {
CustomAlertDialog.showConfirm(
context,
title: '温馨提示',
content: '注销后您的所有信息将会被删除\n请确认是否注销。 ',
onConfirm: () async {
CustomAlertDialog.showInputWithCode(
context,
title: '手机号:${SessionService.instance.phone}',
onGetCode: () async {
LoadingDialogHelper.show();
final res = await BasicInfoApi.sendRegisterSms({
'phone': phone,
});
LoadingDialogHelper.dismiss();
return true;
},
onConfirm: (code) async {
LoadingDialogHelper.show();
Map data = {
'id' : SessionService.instance.accountId,
'phoneCode' : code,
};
await BasicInfoApi.logout(data).then((res) async {
LoadingDialogHelper.dismiss();
if (res['success'] == true) {
ToastUtil.showNormal(context, '账号已注销');
await SessionService.instance.clear(clearPrefs: true);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => const LoginPage()),
);
} else {
ToastUtil.showNormal(context, res['errMessage'] ?? '');
}
});
}
);
},
);
}
} else {
LoadingDialogHelper.dismiss();
ToastUtil.showNormal(context, firmData['errMessage'] ?? '');
}
}
Widget _buildSloganSection() { Widget _buildSloganSection() {
return Container( return Container(
margin: EdgeInsets.fromLTRB(0, 100, 0, 0), margin: EdgeInsets.fromLTRB(0, 100, 0, 0),
@ -180,11 +245,11 @@ class MinePageState extends State<MinePage> {
], ],
), ),
const SizedBox(width: 16), const SizedBox(width: 16),
], ],
), ),
); );
} }
Widget _buildSettingsList() { Widget _buildSettingsList() {
return Container( return Container(
margin: const EdgeInsets.fromLTRB(20, 0, 20, 0), margin: const EdgeInsets.fromLTRB(20, 0, 20, 0),
@ -206,14 +271,18 @@ class MinePageState extends State<MinePage> {
title: "我的信息", title: "我的信息",
icon: "assets/images/ico9.png", icon: "assets/images/ico9.png",
value: notificationsEnabled, value: notificationsEnabled,
num: 0, onChanged: (value) {
onChanged: (value) => setState(() => notificationsEnabled = value!), pushPage(
FullUserinfoPage(isEidt: false, isChooseFirm: true),
context,
);
},
), ),
_buildSettingItem( _buildSettingItem(
title: "修改密码", title: "修改密码",
icon: "assets/images/ico16.png", icon: "assets/images/ico16.png",
value: notificationsEnabled, value: notificationsEnabled,
num: 1,
onChanged: (value) async { onChanged: (value) async {
await pushPage(MineSetPwdPage('0'), context); await pushPage(MineSetPwdPage('0'), context);
}, },
@ -222,23 +291,38 @@ class MinePageState extends State<MinePage> {
title: "扫码入职", title: "扫码入职",
icon: "assets/images/ico10.png", icon: "assets/images/ico10.png",
value: scanAuthentication, value: scanAuthentication,
num: 2, onChanged: (value) async {
onChanged: (value) async {}, final result = await pushPage(
ScanPage(type: ScanType.Onboarding),
context,
);
if (result == null) {
return;
}
pushPage(OnboardingFullPage(scanData: result), context);
},
), ),
_buildSettingItem( _buildSettingItem(
title: "人脸认证", title: "人脸认证",
icon: "assets/images/ico11.png", icon: "assets/images/ico11.png",
value: faceAuthentication, value: faceAuthentication,
num: 3, onChanged: (value) {
onChanged: (value) => setState(() => faceAuthentication = value!), pushPage(
const FaceRecognitionPage(
studentId: '',
data: {},
mode: FaceMode.setUpdata,
),
context,
);
},
), ),
_buildSettingItem( _buildSettingItem(
title: "证书信息", title: "证书信息",
icon: "assets/images/ico12.png", icon: "assets/images/ico12.png",
value: passwordChanged, value: passwordChanged,
num: 4,
onChanged: (value) => setState(() => passwordChanged = value!), onChanged: (value) => setState(() => passwordChanged = value!),
), ),
@ -246,7 +330,6 @@ class MinePageState extends State<MinePage> {
title: "问题反馈", title: "问题反馈",
icon: "assets/images/ico13.png", icon: "assets/images/ico13.png",
value: passwordChanged, value: passwordChanged,
num: 5,
onChanged: (value) => setState(() => passwordChanged = value!), onChanged: (value) => setState(() => passwordChanged = value!),
), ),
@ -255,7 +338,6 @@ class MinePageState extends State<MinePage> {
title: "版本更新", title: "版本更新",
icon: "assets/images/ico14.png", icon: "assets/images/ico14.png",
value: updateAvailable, value: updateAvailable,
num: 6,
onChanged: (value) => setState(() => updateAvailable = value!), onChanged: (value) => setState(() => updateAvailable = value!),
), ),
@ -263,21 +345,24 @@ class MinePageState extends State<MinePage> {
title: "关于我们", title: "关于我们",
icon: "assets/images/ico15.png", icon: "assets/images/ico15.png",
value: logoutSelected, value: logoutSelected,
num: 7,
onChanged: (value) { onChanged: (value) {
setState(() => logoutSelected = value!); setState(() => logoutSelected = value!);
// if (value == true) { },
// _showLogoutConfirmation(); ),
// } _buildSettingItem(
title: "切换账户",
icon: "assets/images/ico15.png",
value: logoutSelected,
onChanged: (value) {
pushPage(MineChangeFirmPage(), context);
}, },
), ),
_buildSettingItem( _buildSettingItem(
title: "账户注销", title: "账户注销",
icon: "assets/images/ico15.png", icon: "assets/images/ico15.png",
value: logoutSelected, value: logoutSelected,
num: 8,
onChanged: (value) { onChanged: (value) {
_logout();
}, },
), ),
], ],
@ -289,53 +374,11 @@ class MinePageState extends State<MinePage> {
required String title, required String title,
required String icon, required String icon,
required bool value, required bool value,
required int num,
required ValueChanged<bool?> onChanged, required ValueChanged<bool?> onChanged,
}) { }) {
return GestureDetector( return GestureDetector(
onTap: () async { onTap: () async {
switch (num) { onChanged(value);
case 0:
pushPage(FullUserinfoPage(isEidt: false, isChooseFirm: true,), context);
break;
case 1:
await pushPage(MineSetPwdPage('0'), context);
break;
case 2:
final result = await pushPage(
ScanPage(type: ScanType.Onboarding),
context,
);
if (result == null) {
return;
}
pushPage(OnboardingFullPage(scanData: result), context);
break;
case 3:
pushPage(
const FaceRecognitionPage(
studentId: '',
data: {},
mode: FaceMode.setUpdata,
),
context,
);
// pushPage(ChangePassPage(), context);
break;
case 4:
// _showLogoutConfirmation();
break;
case 5:
pushPage(FeedbackPage(), context);
break;
case 6:
break;
case 7:
break;
}
}, },
child: ListTile( child: ListTile(
leading: Container( leading: Container(
@ -366,84 +409,8 @@ class MinePageState extends State<MinePage> {
); );
} }
Widget _buildActionButton() {
return SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
//
_saveSettings();
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF1A237E),
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 3, // elevationstyleFrom
),
child: const Text(
"保存设置",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
),
),
);
}
void _saveSettings() {
//
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text("设置已保存成功"),
backgroundColor: Colors.green[700],
duration: const Duration(seconds: 2),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
),
);
}
Future<void> _clearUserSession() async { Future<void> _clearUserSession() async {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
await prefs.remove('isLoggedIn'); // await prefs.remove('isLoggedIn'); //
} }
} }
class _StatItem extends StatelessWidget {
final String number;
final String label;
const _StatItem({required this.number, required this.label});
@override
Widget build(BuildContext context) {
return Column(
children: [
//
Center(
child: Text(
number,
style: const TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: 8),
//
Text(
label,
style: TextStyle(
fontSize: 12,
color: Colors.grey[600],
fontWeight: FontWeight.w500,
),
),
],
);
}
}

View File

@ -1,11 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/bottom_picker.dart'; import 'package:qhd_prevention/customWidget/bottom_picker.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/item_list_widget.dart'; import 'package:qhd_prevention/customWidget/item_list_widget.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/modules/basic_info_api.dart'; import 'package:qhd_prevention/http/modules/basic_info_api.dart';
import 'package:qhd_prevention/pages/main_tab.dart'; import 'package:qhd_prevention/pages/main_tab.dart';
import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/pages/user/login_page.dart';
import 'package:qhd_prevention/services/SessionService.dart'; import 'package:qhd_prevention/services/SessionService.dart';
import 'package:qhd_prevention/services/auth_service.dart'; import 'package:qhd_prevention/services/auth_service.dart';
import 'package:qhd_prevention/tools/tools.dart'; import 'package:qhd_prevention/tools/tools.dart';
@ -13,20 +15,25 @@ import 'package:shared_preferences/shared_preferences.dart';
class OnboardingFullPage extends StatefulWidget { class OnboardingFullPage extends StatefulWidget {
const OnboardingFullPage({super.key, required this.scanData}); const OnboardingFullPage({super.key, required this.scanData});
final Map scanData; final Map scanData;
@override @override
State<OnboardingFullPage> createState() => _OnboardingFullPageState(); State<OnboardingFullPage> createState() => _OnboardingFullPageState();
} }
class _OnboardingFullPageState extends State<OnboardingFullPage> { class _OnboardingFullPageState extends State<OnboardingFullPage> {
Map<String, dynamic> pd = {}; Map<String, dynamic> pd = {};
//
//
List<dynamic> _deptList = []; List<dynamic> _deptList = [];
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_getDept(); _getDept();
} }
// //
Future<void> _getDept() async { Future<void> _getDept() async {
try { try {
@ -36,57 +43,57 @@ class _OnboardingFullPageState extends State<OnboardingFullPage> {
}; };
final result = await BasicInfoApi.getDeptTree(data); final result = await BasicInfoApi.getDeptTree(data);
if (result['success'] == true) { if (result['success'] == true) {
_deptList = result['data']; final list = result['data'] ?? [];
if (list.length > 0) {
setState(() {
_deptList = list[0]['childrenList'] ?? [];
});
}
} }
} catch (e) { } catch (e) {}
}
} }
// //
Future<void> _saveSuccess() async { Future<void> _saveSuccess() async {
if (!FormUtils.hasValue(pd, 'corpinfoId')) { if (!FormUtils.hasValue(pd, 'corpinfoId')) {
ToastUtil.showNormal(context, '请选择部门'); ToastUtil.showNormal(context, '请选择部门');
return; return;
}
if (!FormUtils.hasValue(pd, 'postName')) {
ToastUtil.showNormal(context, '请输入岗位');
return;
}
LoadingDialogHelper.show();
pd['id'] = widget.scanData['id'];
try {
final result = await BasicInfoApi.userFirmEntry(pd);
LoadingDialogHelper.hide();
if (result['success'] == true) {
ToastUtil.showNormal(context, '操作成功');
_relogin();
}
} catch (e) {
LoadingDialogHelper.hide();
ToastUtil.showNormal(context, '操作成功');
}
}
///
Future<void> _relogin() async {
final prefs = await SharedPreferences.getInstance();
final username = prefs.getString('savePhone') ?? '';
final password = prefs.getString('savePass') ?? '';
try {
Map data = {
'id': widget.scanData['id'] ?? '',
'corpinfoId':widget.scanData['corpinfoId'] ?? '',
};
final result = await AuthService.gbsLogin(username, password, data);
if (result['success'] == true) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => const MainPage(isChooseFirm: true,)),
);
}
} catch (e) {
ToastUtil.showNormal(context, '重新登录失败');
} }
if (!FormUtils.hasValue(pd, 'postName')) {
ToastUtil.showNormal(context, '请输入岗位');
return;
}
await CustomAlertDialog.showConfirm(
context,
title: '温馨提示',
content: '确定加入${widget.scanData['corpName'] ?? ''}?',
onConfirm: () async {
LoadingDialogHelper.show();
pd['id'] = SessionService.instance.accountId;
try {
final result = await BasicInfoApi.userFirmEntry(pd);
LoadingDialogHelper.hide();
if (result['success'] == true) {
ToastUtil.showNormal(context, '申请成功');
_relogin();
} else {
ToastUtil.showNormal(context, result['errMessage']);
}
} catch (e) {
LoadingDialogHelper.hide();
ToastUtil.showNormal(context, '操作失败,请重试');
}
},
);
}
///
Future<void> _relogin() async {
bool isChooseFirm = (SessionService.instance.token ?? '').isNotEmpty;
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (_) => MainPage(isChooseFirm: isChooseFirm)),
);
} }
@override @override
@ -98,6 +105,11 @@ class _OnboardingFullPageState extends State<OnboardingFullPage> {
horizontal: 5, horizontal: 5,
ListView( ListView(
children: [ children: [
ItemListWidget.singleLineTitleText(
label: '企业名称',
isEditable: false,
text: widget.scanData['corpName'] ?? '',
),
ItemListWidget.selectableLineTitleTextRightButton( ItemListWidget.selectableLineTitleTextRightButton(
verticalInset: 15, verticalInset: 15,
label: '选择入职部门:', label: '选择入职部门:',
@ -113,8 +125,7 @@ class _OnboardingFullPageState extends State<OnboardingFullPage> {
context, context,
items: _deptList, items: _deptList,
itemBuilder: itemBuilder:
(i) => (i) => Text(i['name']!, textAlign: TextAlign.center),
Text(i['name']!, textAlign: TextAlign.center),
initialIndex: 0, initialIndex: 0,
); );
//FocusHelper.clearFocus(context); //FocusHelper.clearFocus(context);
@ -125,7 +136,6 @@ class _OnboardingFullPageState extends State<OnboardingFullPage> {
pd['departmentName'] = found['name']; pd['departmentName'] = found['name'];
pd['corpinfoId'] = found['corpinfoId']; pd['corpinfoId'] = found['corpinfoId'];
pd['corpinfoName'] = found['corpinfoName']; pd['corpinfoName'] = found['corpinfoName'];
}); });
} }
}, },

View File

@ -53,8 +53,7 @@ class _ChooseUserfirmPageState extends State<ChooseUserfirmPage> {
return; return;
} }
final params = { final params = {
'corpId': widget.firms[_selectedIndex]['id'], 'unitId': widget.firms[_selectedIndex]['id'],
'corpName': widget.firms[_selectedIndex]['corpName'],
}; };
LoadingDialogHelper.show(); LoadingDialogHelper.show();
final result = await AuthService.gbsLogin(widget.userName, widget.password, params); final result = await AuthService.gbsLogin(widget.userName, widget.password, params);

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/search_bar_widget.dart'; import 'package:qhd_prevention/customWidget/search_bar_widget.dart';
import 'package:qhd_prevention/http/ApiService.dart'; import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/main_tab.dart';
import 'package:qhd_prevention/pages/mine/onboarding_full_page.dart'; import 'package:qhd_prevention/pages/mine/onboarding_full_page.dart';
import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/pages/my_appbar.dart';
@ -9,7 +10,9 @@ import 'package:lpinyin/lpinyin.dart';
import 'package:qhd_prevention/tools/tools.dart'; import 'package:qhd_prevention/tools/tools.dart';
class FirmListPage extends StatefulWidget { class FirmListPage extends StatefulWidget {
const FirmListPage({super.key}); const FirmListPage({super.key, required this.isBack});
final bool isBack;
@override @override
State<FirmListPage> createState() => _FirmListPageState(); State<FirmListPage> createState() => _FirmListPageState();
@ -274,11 +277,29 @@ class _FirmListPageState extends State<FirmListPage> {
// 使 // 使
final mq = MediaQuery.of(context); final mq = MediaQuery.of(context);
final fixedIndexHeight = final fixedIndexHeight =
mq.size.height - kToolbarHeight - mq.padding.top - 24-100; mq.size.height - kToolbarHeight - mq.padding.top - 24 - 100;
return Scaffold( return Scaffold(
backgroundColor: Colors.white, backgroundColor: Colors.white,
appBar: MyAppbar(title: '选择企业'), appBar: MyAppbar(
title: '选择企业',
isBack: widget.isBack,
actions: [
if (!widget.isBack)
TextButton(
onPressed: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (_) => MainPage(isChooseFirm: false)),
);
},
child: const Text(
'跳过',
style: TextStyle(color: Colors.white, fontSize: 17),
),
),
],
),
body: SafeArea( body: SafeArea(
child: Column( child: Column(
children: [ children: [

View File

@ -15,9 +15,11 @@ import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/pages/main_tab.dart'; import 'package:qhd_prevention/pages/main_tab.dart';
import 'package:qhd_prevention/pages/mine/face_ecognition_page.dart'; import 'package:qhd_prevention/pages/mine/face_ecognition_page.dart';
import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/pages/user/firm_list_page.dart';
import 'package:qhd_prevention/services/SessionService.dart'; import 'package:qhd_prevention/services/SessionService.dart';
import 'package:qhd_prevention/tools/id_cart_util.dart'; import 'package:qhd_prevention/tools/id_cart_util.dart';
import 'package:qhd_prevention/tools/tools.dart'; import 'package:qhd_prevention/tools/tools.dart';
import 'package:shared_preferences/shared_preferences.dart';
class FullUserinfoPage extends StatefulWidget { class FullUserinfoPage extends StatefulWidget {
const FullUserinfoPage({super.key, required this.isEidt, required this.isChooseFirm}); const FullUserinfoPage({super.key, required this.isEidt, required this.isChooseFirm});
@ -61,6 +63,7 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
String _genderText = ''; String _genderText = '';
String _birthText = ''; String _birthText = '';
String _idValue = ''; String _idValue = '';
String? _userId = SessionService.instance.userId;
List<String> _idCardImgList = []; List<String> _idCardImgList = [];
List<String> _idCartImgIds = []; List<String> _idCartImgIds = [];
/// ///
@ -83,7 +86,6 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
if (!_isEdit) { if (!_isEdit) {
_getUserDetail(); _getUserDetail();
} else { } else {
pd['username'] = SessionService.instance.userName;
pd['id'] = SessionService.instance.accountId; pd['id'] = SessionService.instance.accountId;
pd['flowFlag'] = 0; pd['flowFlag'] = 0;
} }
@ -129,12 +131,18 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
} }
Future<void> _getKeyValues() async { Future<void> _getKeyValues() async {
final prefs = await SharedPreferences.getInstance();
final phone = await prefs.getString("savePhone");
pd['username'] = phone;
await BasicInfoApi.getDictValues('wenhuachengdu').then((res) { await BasicInfoApi.getDictValues('wenhuachengdu').then((res) {
_wenhuachengduList = res['data']; _wenhuachengduList = res['data'];
}); });
await BasicInfoApi.getDictValues('zhengzhimianmao').then((res) { await BasicInfoApi.getDictValues('zhengzhimianmao').then((res) {
_zhengzhimianmaoList = res['data']; _zhengzhimianmaoList = res['data'];
}); });
setState(() {
});
} }
Future<void> _saveSuccess() async { Future<void> _saveSuccess() async {
@ -160,7 +168,7 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
return; return;
} }
LoadingDialogHelper.show(); LoadingDialogHelper.show();
// //
final signResult = await _checkFaceImage(); final signResult = await _checkFaceImage();
// //
final situationResult = await _checkIDCartImages(); final situationResult = await _checkIDCartImages();
@ -173,12 +181,13 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (res['success']) { if (res['success']) {
ToastUtil.showNormal(context, '保存成功'); ToastUtil.showNormal(context, '保存成功');
bool ischange = _isChange ? true: false;
Navigator.pushReplacement( Navigator.pushReplacement(
context, context,
MaterialPageRoute(builder: (_) => const MainPage(isChooseFirm: false)), MaterialPageRoute(builder: (_) => FirmListPage(isBack: false,)),
); );
} else { } else {
ToastUtil.showNormal(context, '保存失败'); ToastUtil.showNormal(context, res['errMessage']);
} }
}); });
}else{ }else{
@ -211,7 +220,7 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
late bool isSuccess = true; late bool isSuccess = true;
if (faceImgPath.isNotEmpty) { if (faceImgPath.isNotEmpty) {
try { try {
await FileApi.uploadFile(faceImgPath, fileType, '').then((result) { await FileApi.uploadFile(faceImgPath, fileType, _userId ?? '').then((result) {
if (result['success']) { if (result['success']) {
pd['userAvatarUrl'] = result['data']['filePath'] ?? ''; pd['userAvatarUrl'] = result['data']['filePath'] ?? '';
isSuccess = true; isSuccess = true;
@ -223,7 +232,7 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
}); });
} catch (e) { } catch (e) {
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
ToastUtil.showNormal(context, '签名上传失败'); ToastUtil.showNormal(context, '人脸照片上传失败');
isSuccess = false; isSuccess = false;
} }
} }
@ -241,10 +250,9 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
await FileApi.uploadFiles( await FileApi.uploadFiles(
idPhotos, idPhotos,
UploadFileType.idCardPhoto, UploadFileType.idCardPhoto,
pd['userId'] ?? '', _userId ?? '',
).then((result) { ).then((result) {
if (result['success']) { if (result['success']) {
pd['userId'] = result['data']['foreignKey'] ?? '';
} else { } else {
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
ToastUtil.showNormal(context, '图片上传失败'); ToastUtil.showNormal(context, '图片上传失败');
@ -282,8 +290,6 @@ class _FullUserinfoPageState extends State<FullUserinfoPage> {
}); });
} else { } else {
// //
ToastUtil.showNormal(context, '请输入正确格式身份证号');
setState(() { setState(() {
pd.remove('birthday'); pd.remove('birthday');
pd.remove('age'); pd.remove('age');

View File

@ -67,13 +67,18 @@ class _LoginPageState extends State<LoginPage> {
} }
Future<void> _getCaptcha() async { Future<void> _getCaptcha() async {
final response = await AuthApi.getUserCaptcha(); try{
if (response['success']) { final response = await AuthApi.getUserCaptcha();
setState(() { if (response['success']) {
_captchaImageBase64 = response['data']['img']; setState(() {
_captchaIdentifier = response['data']['captchaKey']; _captchaImageBase64 = response['data']['img'];
}); _captchaIdentifier = response['data']['captchaKey'];
});
}
}catch(e){
print(e);
} }
} }
Future<void> _getData() async { Future<void> _getData() async {
@ -122,7 +127,7 @@ class _LoginPageState extends State<LoginPage> {
children: [ children: [
const SizedBox(height: 70), // const SizedBox(height: 70), //
Image.asset( Image.asset(
"assets/images/logo.png", "assets/images/g_logo.png",
width: 40, width: 40,
height: 40, height: 40,
), ),
@ -282,17 +287,14 @@ class _LoginPageState extends State<LoginPage> {
Padding( Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 25, horizontal: 10,
), ),
child: _buildCaptchaImage(), child: _buildCaptchaImage(),
), ),
], ],
), ),
), ),
const Divider( const Divider(),
height: 0.5,
color: Colors.black26,
),
const SizedBox(height: 10), const SizedBox(height: 10),

View File

@ -167,7 +167,9 @@ class _RegisterPageState extends State<RegisterPage> {
'newPassword': pwd, 'newPassword': pwd,
'confirmPassword': pwd, 'confirmPassword': pwd,
}; };
LoadingDialogHelper.show();
final resp = await BasicInfoApi.register(data); final resp = await BasicInfoApi.register(data);
LoadingDialogHelper.hide();
if (resp != null && resp['success'] == true) { if (resp != null && resp['success'] == true) {
ToastUtil.showNormal(context, '注册成功,请登录'); ToastUtil.showNormal(context, '注册成功,请登录');
@ -181,6 +183,7 @@ class _RegisterPageState extends State<RegisterPage> {
ToastUtil.showNormal(context, resp?['message'] ?? '注册失败,请重试'); ToastUtil.showNormal(context, resp?['message'] ?? '注册失败,请重试');
} }
} catch (e) { } catch (e) {
LoadingDialogHelper.hide();
ToastUtil.showNormal(context, '注册失败,请稍后重试'); ToastUtil.showNormal(context, '注册失败,请稍后重试');
} }
} }

View File

@ -1,5 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
class BizAttr { class BizAttr {
@ -342,8 +343,8 @@ class SessionService {
/// API /// API
void updateFromApiResponse(Map<String, dynamic> responseJson) { void updateFromApiResponse(Map<String, dynamic> responseJson) {
if (responseJson['data'] != null) { if (responseJson != null) {
userData = UserData.fromJson(responseJson['data'] as Map<String, dynamic>); userData = UserData.fromJson(responseJson);
} }
// token // token
} }
@ -401,6 +402,7 @@ class SessionService {
print('姓名: ${userData!.name}'); print('姓名: ${userData!.name}');
print('部门: ${userData!.departmentName}'); print('部门: ${userData!.departmentName}');
print('租户ID: ${userData!.tenantId}'); print('租户ID: ${userData!.tenantId}');
// printLongString(text)
} }
} }
} }

View File

@ -29,14 +29,20 @@ class AuthService {
return {}; return {};
} }
final resData = res['data']; final resData = res['data'];
if (resData == null) {
Fluttertoast.showToast(msg: '登录失败');
return {};
}
bool isInfoComplete = resData['isInfoComplete'] ?? false; bool isInfoComplete = resData['isInfoComplete'] ?? false;
List firmList = resData['corpInfoCOList'] ?? []; List firmList = resData['corpInfoCOList'] ?? [];
///
SessionService.instance.updateFromApiResponse(resData['userCO']);
await SessionService.instance.saveToPrefs();
if (firmList.length == 1 && isInfoComplete) { if (firmList.length == 1 && isInfoComplete) {
// //
Map data = { Map data = {
'id': firmList.first['id'] ?? '', 'unitId': firmList.first['id'] ?? '',
'corpinfoId': firmList.first['corpinfoId'] ?? '',
}; };
return AuthService.gbsLogin(username, password, data); return AuthService.gbsLogin(username, password, data);
} else if (firmList.length > 1) { } else if (firmList.length > 1) {
@ -94,6 +100,7 @@ class AuthService {
_data['password'] = encrypted; _data['password'] = encrypted;
// printLongString(jsonEncode(_data)); // printLongString(jsonEncode(_data));
final result = await AuthApi.loginCheck(_data); final result = await AuthApi.loginCheck(_data);
final success = result['success'] as bool; final success = result['success'] as bool;
if (!success) { if (!success) {
Fluttertoast.showToast(msg: result['errMessage'] ?? ''); Fluttertoast.showToast(msg: result['errMessage'] ?? '');
@ -116,11 +123,25 @@ class AuthService {
json.encode(params), json.encode(params),
); );
await AuthApi.getUserData().then((result) async { try {
SessionService.instance.updateFromApiResponse(result); await AuthApi.getUserData().then((result) async {
await SessionService.instance.saveToPrefs(); if (!result['success']) {
SessionService.instance.setToken(token); LoadingDialogHelper.hide();
}); Fluttertoast.showToast(msg: result['errMessage'] ?? '');
return {};
}
SessionService.instance.updateFromApiResponse(result['data']);
await SessionService.instance.saveToPrefs();
SessionService.instance.setToken(token);
SessionService.instance.printUserInfo();
});
} catch (e) {
LoadingDialogHelper.hide();
Fluttertoast.showToast(msg: '用户信息获取失败,请重试');
return {};
}
return result; return result;
} }

View File

@ -316,6 +316,17 @@ class LoadingDialogHelper {
_timer?.cancel(); _timer?.cancel();
_timer = null; _timer = null;
try {
EasyLoading.dismiss();
} catch (e) {
debugPrint('EasyLoading.dismiss error: $e');
}
}
static void dismiss() {
//
_timer?.cancel();
_timer = null;
try { try {
EasyLoading.dismiss(); EasyLoading.dismiss();
} catch (e) { } catch (e) {

View File

@ -32,9 +32,13 @@ environment:
# ios: true # ios: true
# image_path: "assets/images/app-logo.png" # image_path: "assets/images/app-logo.png"
# min_sdk_android: 21 # (可选) Android 最低支持 # min_sdk_android: 21 # (可选) Android 最低支持
flutter_launcher_icons:
android: true
ios: true
image_path: "assets/images/logo.png"
flutter_native_splash: flutter_native_splash:
background_image: assets/images/bg-login.png background_image: assets/images/lun.jpg
android: true android: true
ios: true ios: true
web: false web: false