。。。
parent
6d737adce3
commit
21387b3cbc
|
@ -15,7 +15,7 @@ if (keystorePropertiesFile.exists()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.zhuoyun.qhdprevention.qhd_prevention"
|
namespace = "uni.UNI85F7A17"
|
||||||
compileSdk = flutter.compileSdkVersion
|
compileSdk = flutter.compileSdkVersion
|
||||||
ndkVersion = "28.1.13356709"
|
ndkVersion = "28.1.13356709"
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.zhuoyun.qhdprevention.qhd_prevention"
|
applicationId = "uni.UNI85F7A17"
|
||||||
minSdk = 24
|
minSdk = 24
|
||||||
targetSdk = flutter.targetSdkVersion
|
targetSdk = flutter.targetSdkVersion
|
||||||
versionCode = flutter.versionCode
|
versionCode = flutter.versionCode
|
||||||
|
|
|
@ -104,7 +104,7 @@
|
||||||
<!-- FileProvider 配置 -->
|
<!-- FileProvider 配置 -->
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="com.zhuoyun.qhdprevention.qhd_prevention.fileprovider"
|
android:authorities="uni.UNI85F7A17.fileprovider"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:grantUriPermissions="true">
|
android:grantUriPermissions="true">
|
||||||
<meta-data
|
<meta-data
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
package com.zhuoyun.qhdprevention.qhd_prevention
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.provider.Settings
|
|
||||||
import androidx.core.content.FileProvider
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
|
||||||
import io.flutter.embedding.engine.FlutterEngine
|
|
||||||
import io.flutter.plugin.common.MethodChannel
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class MainActivity: FlutterActivity() {
|
|
||||||
private val CHANNEL = "app.install"
|
|
||||||
private val REQ_INSTALL_UNKNOWN = 9999
|
|
||||||
|
|
||||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
|
||||||
super.configureFlutterEngine(flutterEngine)
|
|
||||||
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
|
|
||||||
when (call.method) {
|
|
||||||
"installApk" -> {
|
|
||||||
val path = call.argument<String>("path")
|
|
||||||
if (path == null) {
|
|
||||||
result.error("NO_PATH", "no path provided", null)
|
|
||||||
return@setMethodCallHandler
|
|
||||||
}
|
|
||||||
installApk(path, result)
|
|
||||||
}
|
|
||||||
else -> result.notImplemented()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun installApk(path: String, result: MethodChannel.Result) {
|
|
||||||
val file = File(path)
|
|
||||||
if (!file.exists()) {
|
|
||||||
result.error("NO_FILE", "file not exist", null)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Android 8.0+ 需要允许安装未知来源
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
if (!packageManager.canRequestPackageInstalls()) {
|
|
||||||
// 引导用户去设置允许安装未知来源(你可以在 Flutter 侧提示用户)
|
|
||||||
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:$packageName"))
|
|
||||||
startActivity(intent)
|
|
||||||
result.error("NEED_INSTALL_PERMISSION", "need install permission", null)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val apkUri: Uri = FileProvider.getUriForFile(this, "$packageName.fileprovider", file)
|
|
||||||
val intent = Intent(Intent.ACTION_VIEW)
|
|
||||||
intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
|
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
|
||||||
startActivity(intent)
|
|
||||||
result.success(true)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.zhuoyun.qhdprevention.qhd_prevention
|
package uni.UNI85F7A17
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|
|
@ -503,10 +503,10 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.zhuoyun.qhdprevention.qhdPrevention;
|
PRODUCT_BUNDLE_IDENTIFIER = uni.UNI85F7A17;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "flutter-weihua";
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "qa-zsaq";
|
||||||
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";
|
||||||
|
@ -523,7 +523,7 @@
|
||||||
DEVELOPMENT_TEAM = 8AKCJ9LW7D;
|
DEVELOPMENT_TEAM = 8AKCJ9LW7D;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.zhuoyun.qhdprevention.qhdPrevention.RunnerTests;
|
PRODUCT_BUNDLE_IDENTIFIER = uni.UNI85F7A17.RunnerTests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
@ -542,7 +542,7 @@
|
||||||
DEVELOPMENT_TEAM = 8AKCJ9LW7D;
|
DEVELOPMENT_TEAM = 8AKCJ9LW7D;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.zhuoyun.qhdprevention.qhdPrevention.RunnerTests;
|
PRODUCT_BUNDLE_IDENTIFIER = uni.UNI85F7A17.RunnerTests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
|
||||||
|
@ -559,7 +559,7 @@
|
||||||
DEVELOPMENT_TEAM = 8AKCJ9LW7D;
|
DEVELOPMENT_TEAM = 8AKCJ9LW7D;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.zhuoyun.qhdprevention.qhdPrevention.RunnerTests;
|
PRODUCT_BUNDLE_IDENTIFIER = uni.UNI85F7A17.RunnerTests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
|
||||||
|
@ -697,10 +697,10 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.zhuoyun.qhdprevention.qhdPrevention;
|
PRODUCT_BUNDLE_IDENTIFIER = uni.UNI85F7A17;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "flutter-weihua";
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "qa-zsaq";
|
||||||
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;
|
||||||
|
@ -728,10 +728,10 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.zhuoyun.qhdprevention.qhdPrevention;
|
PRODUCT_BUNDLE_IDENTIFIER = uni.UNI85F7A17;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "flutter-weihua";
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "qa-zsaq";
|
||||||
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";
|
||||||
|
|
|
@ -33,6 +33,9 @@ class _RemoteFilePageState extends State<RemoteFilePage> {
|
||||||
late PdfControllerPinch _pdfController;
|
late PdfControllerPinch _pdfController;
|
||||||
int _totalPages = 0;
|
int _totalPages = 0;
|
||||||
|
|
||||||
|
// 用于短文档(<=3页)的停留计时器兜底
|
||||||
|
Timer? _pageViewTimer;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
@ -93,12 +96,36 @@ class _RemoteFilePageState extends State<RemoteFilePage> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_countdownTimer?.cancel();
|
_countdownTimer?.cancel();
|
||||||
|
_pageViewTimer?.cancel();
|
||||||
if (!_isLoading) {
|
if (!_isLoading) {
|
||||||
_pdfController.dispose();
|
_pdfController.dispose();
|
||||||
}
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 当页面改变时调用(pdfx 的 page 是 1-based)
|
||||||
|
void _onPageChanged(int page) {
|
||||||
|
// 取消可能存在的短页面计时器(重新开始)
|
||||||
|
_pageViewTimer?.cancel();
|
||||||
|
|
||||||
|
// 如果到达最后一页(注意页码从 1 开始)
|
||||||
|
if (_totalPages > 0 && page >= _totalPages) {
|
||||||
|
// 直接标记为已翻到底
|
||||||
|
setState(() => _hasScrolledToBottom = true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对于特别短的文档(例如 <=3 页),我们做一个停留计时器:如果用户停留在最后一页一小段时间,也视为已浏览完毕
|
||||||
|
if (_totalPages > 0 && _totalPages <= 3) {
|
||||||
|
// 如果当前页已经是最后一页(page == _totalPages),启动短计时器
|
||||||
|
if (page == _totalPages) {
|
||||||
|
_pageViewTimer = Timer(const Duration(seconds: 1), () {
|
||||||
|
if (mounted) setState(() => _hasScrolledToBottom = true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final isButtonEnabled = _timerFinished && _hasScrolledToBottom;
|
final isButtonEnabled = _timerFinished && _hasScrolledToBottom;
|
||||||
|
@ -117,12 +144,14 @@ class _RemoteFilePageState extends State<RemoteFilePage> {
|
||||||
onDocumentLoaded: (document) {
|
onDocumentLoaded: (document) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_totalPages = document.pagesCount;
|
_totalPages = document.pagesCount;
|
||||||
|
// 如果文档只有 1 页,直接视为已看完
|
||||||
|
if (_totalPages <= 1) {
|
||||||
|
_hasScrolledToBottom = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onPageChanged: (page) {
|
onPageChanged: (page) {
|
||||||
if (page == _totalPages - 1) {
|
_onPageChanged(page);
|
||||||
setState(() => _hasScrolledToBottom = true);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -19,13 +19,13 @@ class ApiService {
|
||||||
// static const String projectManagerUrl = 'https://pm.qhdsafety.com/zy-projectManage/';
|
// static const String projectManagerUrl = 'https://pm.qhdsafety.com/zy-projectManage/';
|
||||||
// static const String publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUoHAavCikaZxjlDM6Km8cX+ye78F4oF39AcEfnE1p2Yn9pJ9WFxYZ4Vkh6F8SKMi7k4nYsKceqB1RwG996SvHQ5C3pM3nbXCP4K15ad6QhN4a7lzlbLhiJcyIKszvvK8ncUDw8mVQ0j/2mwxv05yH6LN9OKU6Hzm1ninpWeE+awIDAQAB'
|
// static const String publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUoHAavCikaZxjlDM6Km8cX+ye78F4oF39AcEfnE1p2Yn9pJ9WFxYZ4Vkh6F8SKMi7k4nYsKceqB1RwG996SvHQ5C3pM3nbXCP4K15ad6QhN4a7lzlbLhiJcyIKszvvK8ncUDw8mVQ0j/2mwxv05yH6LN9OKU6Hzm1ninpWeE+awIDAQAB'
|
||||||
/// 人脸识别服务
|
/// 人脸识别服务
|
||||||
// static const String baseFacePath = "https://qaaqwh.qhdsafety.com/whb_stu_face";
|
static const String baseFacePath = "https://qaaqwh.qhdsafety.com/whb_stu_face";
|
||||||
static const String baseFacePath = "http://192.168.20.240:8500/whb_stu_face/";
|
// static const String baseFacePath = "http://192.168.20.240:8500/whb_stu_face/";
|
||||||
// static const String baseFacePath = "http://192.168.0.25:38199"; //王轩服务器
|
// static const String baseFacePath = "http://192.168.0.25:38199"; //王轩服务器
|
||||||
|
|
||||||
/// 登录及其他管理后台接口
|
/// 登录及其他管理后台接口
|
||||||
// static const String basePath = "https://qaaqwh.qhdsafety.com/integrated_whb";
|
static const String basePath = "https://qaaqwh.qhdsafety.com/integrated_whb";
|
||||||
static const String basePath = "http://192.168.20.240:8500/integrated_whb";//测试服务器
|
// static const String basePath = "http://192.168.20.240:8500/integrated_whb";//测试服务器
|
||||||
// static const String basePath = "http://192.168.0.25:28199";//王轩服务器
|
// static const String basePath = "http://192.168.0.25:28199";//王轩服务器
|
||||||
// static const String basePath = "http://192.168.0.45:28199";//长久服务器
|
// static const String basePath = "http://192.168.0.45:28199";//长久服务器
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ U6Hzm1ninpWeE+awIDAQAB
|
||||||
'/app/versionmanager/getVersion',
|
'/app/versionmanager/getVersion',
|
||||||
method: Method.post,
|
method: Method.post,
|
||||||
data: {
|
data: {
|
||||||
'FILETYPE':Platform.pathSeparator
|
'FILETYPE':Platform.isIOS ? 'iOS' : 'Android'
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ import 'pages/mine/mine_set_pwd_page.dart';
|
||||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||||
// 全局路由
|
// 全局路由
|
||||||
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
|
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
|
||||||
|
bool _isLoggingOut = false;
|
||||||
// 全局消息控制器
|
// 全局消息控制器
|
||||||
class GlobalMessage {
|
class GlobalMessage {
|
||||||
static void showError(String message) {
|
static void showError(String message) {
|
||||||
|
@ -109,17 +109,32 @@ void main( ) async {
|
||||||
|
|
||||||
// 初始化HTTP管理器未授权回调
|
// 初始化HTTP管理器未授权回调
|
||||||
HttpManager.onUnauthorized = () async {
|
HttpManager.onUnauthorized = () async {
|
||||||
|
final navigatorState = navigatorKey.currentState;
|
||||||
|
if (navigatorState == null) return;
|
||||||
|
|
||||||
|
// 尝试获取当前路由名(注意:ModalRoute 可能为 null)
|
||||||
|
final currentRouteName = ModalRoute.of(navigatorState.context)?.settings.name;
|
||||||
|
if (currentRouteName == '/login') {
|
||||||
|
// 已在登录页,直接返回,避免重复登出流程与提示
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_isLoggingOut) return; // 防止并发多次触发
|
||||||
|
_isLoggingOut = true;
|
||||||
|
|
||||||
|
try {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
await prefs.setBool('isLoggedIn', false);
|
await prefs.setBool('isLoggedIn', false);
|
||||||
await prefs.remove('token');
|
await prefs.remove('token');
|
||||||
navigatorKey.currentState?.pushNamedAndRemoveUntil(
|
|
||||||
'/login',
|
navigatorState.pushNamedAndRemoveUntil('/login', (route) => false);
|
||||||
(route) => false,
|
|
||||||
);
|
|
||||||
|
|
||||||
Future.delayed(const Duration(milliseconds: 100), () {
|
Future.delayed(const Duration(milliseconds: 100), () {
|
||||||
GlobalMessage.showError('您的账号已在其他设备登录,已自动下线,请使用单一设备进行学习。');
|
GlobalMessage.showError('您的账号已在其他设备登录,已自动下线,请使用单一设备进行学习。');
|
||||||
});
|
});
|
||||||
|
} finally {
|
||||||
|
_isLoggingOut = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// 自动登录逻辑
|
// 自动登录逻辑
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
|
|
@ -353,9 +353,9 @@ setState(() {
|
||||||
|
|
||||||
Widget _mainWidget() {
|
Widget _mainWidget() {
|
||||||
bool isShowCheck = false;
|
bool isShowCheck = false;
|
||||||
if (FormUtils.hasValue(inspectedForm, 'hiddenList')) {
|
if (FormUtils.hasValue(form, 'hiddenList')) {
|
||||||
List list = inspectedForm['hiddenList'];
|
List list = form['hiddenList'];
|
||||||
if (list.isEmpty) {
|
if (list.isNotEmpty) {
|
||||||
isShowCheck = true;
|
isShowCheck = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,33 +190,33 @@ class HomePageState extends State<HomePage> {
|
||||||
|
|
||||||
/// 首次加载:先恢复缓存(如果有),然后在后台去刷新(只有当无缓存时才显示 loading)
|
/// 首次加载:先恢复缓存(如果有),然后在后台去刷新(只有当无缓存时才显示 loading)
|
||||||
Future<void> _initialLoad() async {
|
Future<void> _initialLoad() async {
|
||||||
/// 清单列表
|
|
||||||
final data = await ApiService.getListData();
|
|
||||||
if (data['result'] == 'success') {
|
|
||||||
final content = data['varList'] ?? [];
|
|
||||||
for (Map item in content) {
|
|
||||||
if (item['checkCount'] == 0) {
|
|
||||||
totalList.add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final result = await AuthService.checkUpdate();
|
final result = await AuthService.checkUpdate();
|
||||||
|
try{
|
||||||
if (FormUtils.hasValue(result, 'pd')) {
|
if (FormUtils.hasValue(result, 'pd')) {
|
||||||
// 有更新 提示更新
|
|
||||||
Map pd = result['pd'];
|
Map pd = result['pd'];
|
||||||
CustomAlertDialog.showAlert(
|
final versionInfo = await getAppVersion();
|
||||||
|
bool isWifi = true;
|
||||||
|
if (versionInfo.versionName != pd['VERSION']) {
|
||||||
|
//有更新 提示更新
|
||||||
|
final ok = await CustomAlertDialog.showConfirm(
|
||||||
context,
|
context,
|
||||||
|
barrierDismissible:false,
|
||||||
title: '更新通知',
|
title: '更新通知',
|
||||||
content: pd['UPLOAD_CONTENT'] ?? '',
|
content: isWifi ? '发现新版本,是否更新?为了更好的体验,请更新到最新版本。' : '发现新版本,检查到您当前使用的是移动网络,是否更新?更新时请注意流量消耗。为了更好的体验,请更新到最新版本。',
|
||||||
onConfirm: () async{
|
cancelText: pd['ISUPDATE'] == '1' ? '' : '稍后更新',
|
||||||
final apkUrl = 'http://192.168.1.191:8888/app-release.apk';
|
confirmText: '立即更新'
|
||||||
await showUpdateConfirmDialog(context, apkUrl: apkUrl);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
if (ok) {
|
||||||
|
final apkUrl = pd['FILEURL'] ?? '';
|
||||||
|
await showUpdateConfirm(context, apkUrl: apkUrl);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}catch(_){}
|
||||||
|
|
||||||
|
|
||||||
final corppromiseData = await ApiService.checkSafeCorppromise();
|
final corppromiseData = await ApiService.checkSafeCorppromise();
|
||||||
if (corppromiseData['ISSIGN'] == 1) {
|
if (corppromiseData['ISSIGN'] == 1) {
|
||||||
// 承诺
|
// 承诺
|
||||||
|
@ -241,7 +241,16 @@ class HomePageState extends State<HomePage> {
|
||||||
_fetchData();
|
_fetchData();
|
||||||
_fetchHiddenList(showLoading: hiddenList.isEmpty);
|
_fetchHiddenList(showLoading: hiddenList.isEmpty);
|
||||||
fetchAndSaveBd09(context);
|
fetchAndSaveBd09(context);
|
||||||
|
/// 清单列表
|
||||||
|
final data = await ApiService.getListData();
|
||||||
|
if (data['result'] == 'success') {
|
||||||
|
final content = data['varList'] ?? [];
|
||||||
|
for (Map item in content) {
|
||||||
|
if (item['checkCount'] == 0) {
|
||||||
|
totalList.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onRefresh() async {
|
Future<void> _onRefresh() async {
|
||||||
|
@ -333,7 +342,16 @@ class HomePageState extends State<HomePage> {
|
||||||
// “我的工作”数据
|
// “我的工作”数据
|
||||||
final data = await ApiService.getWork();
|
final data = await ApiService.getWork();
|
||||||
final hidCount = data['hidCount'] as Map<String, dynamic>? ?? {};
|
final hidCount = data['hidCount'] as Map<String, dynamic>? ?? {};
|
||||||
|
setState(() {
|
||||||
|
// ———— 更新 workInfos ————
|
||||||
|
workInfos =
|
||||||
|
workInfos.map((info) {
|
||||||
|
final idx = info['index'] as int;
|
||||||
|
final key = _workKey(idx);
|
||||||
|
final num = (hidCount[key] ?? 0).toString();
|
||||||
|
return {...info, 'num': num};
|
||||||
|
}).toList();
|
||||||
|
});
|
||||||
// // 告知BadgeManager去更新“安全巡检”和“八项作业”角标
|
// // 告知BadgeManager去更新“安全巡检”和“八项作业”角标
|
||||||
// BadgeManager().updateEnvInspectCount();
|
// BadgeManager().updateEnvInspectCount();
|
||||||
// BadgeManager().updateEightWorkCount();
|
// BadgeManager().updateEightWorkCount();
|
||||||
|
@ -350,15 +368,6 @@ class HomePageState extends State<HomePage> {
|
||||||
|
|
||||||
//更新页面状态
|
//更新页面状态
|
||||||
setState(() {
|
setState(() {
|
||||||
// ———— 更新 workInfos ————
|
|
||||||
workInfos =
|
|
||||||
workInfos.map((info) {
|
|
||||||
final idx = info['index'] as int;
|
|
||||||
final key = _workKey(idx);
|
|
||||||
final num = (hidCount[key] ?? 0).toString();
|
|
||||||
return {...info, 'num': num};
|
|
||||||
}).toList();
|
|
||||||
|
|
||||||
// ———— 从 BadgeManager 拿最新的本页角标 ————
|
// ———— 从 BadgeManager 拿最新的本页角标 ————
|
||||||
_safetyEnvironmentalInspection = BadgeManager().envInspectCount;
|
_safetyEnvironmentalInspection = BadgeManager().envInspectCount;
|
||||||
_eight_work_count = BadgeManager().eightWorkCount;
|
_eight_work_count = BadgeManager().eightWorkCount;
|
||||||
|
|
|
@ -80,6 +80,7 @@ class _FaceRecognitionPageState extends State<FaceRecognitionPage>
|
||||||
// 可选:释放相机,节省资源
|
// 可选:释放相机,节省资源
|
||||||
try {
|
try {
|
||||||
_cameraController?.dispose();
|
_cameraController?.dispose();
|
||||||
|
Navigator.pop(context);
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
_cameraController = null;
|
_cameraController = null;
|
||||||
} else if (state == AppLifecycleState.resumed) {
|
} else if (state == AppLifecycleState.resumed) {
|
||||||
|
|
|
@ -225,7 +225,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
||||||
await _submitPlayTime(
|
await _submitPlayTime(
|
||||||
snapshot: prevSnapshot,
|
snapshot: prevSnapshot,
|
||||||
end: false,
|
end: false,
|
||||||
seconds: _lastReported.inSeconds,
|
seconds: _lastReported.inSeconds.toString(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
||||||
'VIDEOCOURSEWARE_ID': data['VIDEOCOURSEWARE_ID'] ?? '',
|
'VIDEOCOURSEWARE_ID': data['VIDEOCOURSEWARE_ID'] ?? '',
|
||||||
'CURRICULUM_ID': data['CURRICULUM_ID'] ?? '',
|
'CURRICULUM_ID': data['CURRICULUM_ID'] ?? '',
|
||||||
'CHAPTER_ID': data['CHAPTER_ID'] ?? '',
|
'CHAPTER_ID': data['CHAPTER_ID'] ?? '',
|
||||||
'VIDEOTIME': data['VIDEOTIME'] ?? 0,
|
'VIDEOTIME': data['VIDEOTIME'] ?? '0.0',
|
||||||
'IS_NODE': hasNodes,
|
'IS_NODE': hasNodes,
|
||||||
'FIRST_INDEX': fi,
|
'FIRST_INDEX': fi,
|
||||||
'NODE_INDEX': ni,
|
'NODE_INDEX': ni,
|
||||||
|
@ -265,7 +265,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
||||||
await _submitPlayTime(
|
await _submitPlayTime(
|
||||||
snapshot: docSnapshot,
|
snapshot: docSnapshot,
|
||||||
end: true,
|
end: true,
|
||||||
seconds: int.parse('${data['VIDEOTIME'] ?? '0'}'),
|
seconds: data['VIDEOTIME'] ?? '0.0',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -324,6 +324,17 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
||||||
await onPass();
|
await onPass();
|
||||||
} else {
|
} else {
|
||||||
ToastUtil.showError(context, '人脸验证未通过,无法继续');
|
ToastUtil.showError(context, '人脸验证未通过,无法继续');
|
||||||
|
if (_videoController != null) {
|
||||||
|
try {
|
||||||
|
_videoController?.removeListener(_onTimeUpdate);
|
||||||
|
} catch (_) {}
|
||||||
|
try {
|
||||||
|
_videoController?.dispose();
|
||||||
|
} catch (_) {}
|
||||||
|
_videoController = null;
|
||||||
|
}
|
||||||
|
_faceTimer?.cancel();
|
||||||
|
setState(() {});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final ok = await CustomAlertDialog.showConfirm(
|
final ok = await CustomAlertDialog.showConfirm(
|
||||||
|
@ -458,7 +469,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
||||||
return _submitPlayTime(
|
return _submitPlayTime(
|
||||||
snapshot: snapshot,
|
snapshot: snapshot,
|
||||||
end: false,
|
end: false,
|
||||||
seconds: pos.inSeconds,
|
seconds: pos.inSeconds.toString(),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.whenComplete(() {
|
.whenComplete(() {
|
||||||
|
@ -490,7 +501,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
||||||
await _submitPlayTime(
|
await _submitPlayTime(
|
||||||
snapshot: snapshot,
|
snapshot: snapshot,
|
||||||
end: true,
|
end: true,
|
||||||
seconds: finalSeconds,
|
seconds: finalSeconds.toString(),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.whenComplete(() {
|
.whenComplete(() {
|
||||||
|
@ -516,7 +527,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
||||||
Future<void> _submitPlayTime({
|
Future<void> _submitPlayTime({
|
||||||
required Map<String, dynamic> snapshot,
|
required Map<String, dynamic> snapshot,
|
||||||
required bool end,
|
required bool end,
|
||||||
required int seconds,
|
required String seconds,
|
||||||
}) async {
|
}) async {
|
||||||
// snapshot 必须包含 VIDEOCOURSEWARE_ID
|
// snapshot 必须包含 VIDEOCOURSEWARE_ID
|
||||||
if (snapshot['VIDEOCOURSEWARE_ID'] == null ||
|
if (snapshot['VIDEOCOURSEWARE_ID'] == null ||
|
||||||
|
@ -602,7 +613,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
|
||||||
final resT =
|
final resT =
|
||||||
(resTraw is num)
|
(resTraw is num)
|
||||||
? resTraw.toDouble()
|
? resTraw.toDouble()
|
||||||
: double.tryParse('$resTraw') ?? seconds.toDouble();
|
: double.tryParse('$resTraw') ?? double.parse(seconds);
|
||||||
|
|
||||||
final videoTimeRaw = snapshot['VIDEOTIME'];
|
final videoTimeRaw = snapshot['VIDEOTIME'];
|
||||||
final videoTime =
|
final videoTime =
|
||||||
|
|
|
@ -1322,6 +1322,7 @@ class SignItemWidget extends StatelessWidget {
|
||||||
this.smallThumbSize = 50.0,
|
this.smallThumbSize = 50.0,
|
||||||
this.signImageWidth = 200.0,
|
this.signImageWidth = 200.0,
|
||||||
this.signImageHeight = 100.0,
|
this.signImageHeight = 100.0,
|
||||||
|
required this.isShowTime,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
/// signs map 中用于查找签名列表的 key
|
/// signs map 中用于查找签名列表的 key
|
||||||
|
@ -1348,6 +1349,7 @@ class SignItemWidget extends StatelessWidget {
|
||||||
/// 签名图片展示尺寸(每张一行)
|
/// 签名图片展示尺寸(每张一行)
|
||||||
final double signImageWidth;
|
final double signImageWidth;
|
||||||
final double signImageHeight;
|
final double signImageHeight;
|
||||||
|
final bool isShowTime;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -1579,6 +1581,7 @@ class SignItemWidget extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
if (isShowTime) {
|
||||||
// 时间文本(始终固定在最右侧并底部对齐)
|
// 时间文本(始终固定在最右侧并底部对齐)
|
||||||
list.add(const SizedBox(height: 10));
|
list.add(const SizedBox(height: 10));
|
||||||
list.add(
|
list.add(
|
||||||
|
@ -1595,6 +1598,8 @@ class SignItemWidget extends StatelessWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -1615,6 +1620,7 @@ class ConfirmWithSignWidget extends StatelessWidget {
|
||||||
required this.nameKey, // 'CONFIRM_USER_NAME',
|
required this.nameKey, // 'CONFIRM_USER_NAME',
|
||||||
required this.headerTitle, // '作业负责人意见',
|
required this.headerTitle, // '作业负责人意见',
|
||||||
required this.roleTitle, // '作业负责人',
|
required this.roleTitle, // '作业负责人',
|
||||||
|
this.isShowTime = true,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
// 允许外部传入 null(但构建内部会降级为 {},避免空异常)
|
// 允许外部传入 null(但构建内部会降级为 {},避免空异常)
|
||||||
|
@ -1643,6 +1649,8 @@ class ConfirmWithSignWidget extends StatelessWidget {
|
||||||
/// 传给 SignItemWidget 的 title(例如 '作业负责人')
|
/// 传给 SignItemWidget 的 title(例如 '作业负责人')
|
||||||
final String roleTitle;
|
final String roleTitle;
|
||||||
|
|
||||||
|
final bool isShowTime;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// 容错:如果传入为 null,降级成空 Map,后续访问安全
|
// 容错:如果传入为 null,降级成空 Map,后续访问安全
|
||||||
|
@ -1767,6 +1775,7 @@ class ConfirmWithSignWidget extends StatelessWidget {
|
||||||
pd: safePd,
|
pd: safePd,
|
||||||
signs: safeSigns,
|
signs: safeSigns,
|
||||||
baseImgPath: baseImgPath,
|
baseImgPath: baseImgPath,
|
||||||
|
isShowTime:isShowTime,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -26,11 +26,7 @@ class SignImageData {
|
||||||
String? filePath;
|
String? filePath;
|
||||||
int? key;
|
int? key;
|
||||||
|
|
||||||
SignImageData({
|
SignImageData({required this.SIGNER_TIME, this.filePath, this.key});
|
||||||
required this.SIGNER_TIME,
|
|
||||||
this.filePath,
|
|
||||||
this.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'SIGNER_TIME': SIGNER_TIME,
|
'SIGNER_TIME': SIGNER_TIME,
|
||||||
|
@ -47,8 +43,10 @@ class SignImageData {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'SignImageData(key:$key, filePath:$filePath, SIGNER_TIME:$SIGNER_TIME)';
|
String toString() =>
|
||||||
|
'SignImageData(key:$key, filePath:$filePath, SIGNER_TIME:$SIGNER_TIME)';
|
||||||
}
|
}
|
||||||
|
|
||||||
class DangerousOptionsPage extends StatefulWidget {
|
class DangerousOptionsPage extends StatefulWidget {
|
||||||
final int index;
|
final int index;
|
||||||
final int status;
|
final int status;
|
||||||
|
@ -134,32 +132,23 @@ class _DangerousOptionsPageState extends State<DangerousOptionsPage> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LoadingDialogHelper.show();
|
LoadingDialogHelper.show();
|
||||||
List<String> filePaths =
|
List<SignImageData> filePaths = [];
|
||||||
signImgList.map((img) => img.filePath ?? '').toList();
|
List severImageList = [];
|
||||||
final result = await ApiService.saveDangerousOptionsFile(filePaths);
|
|
||||||
final List<dynamic> signList = result['FILE_PATH_LIST'];
|
|
||||||
List<Map<String, dynamic>> sineImageList = [];
|
|
||||||
for (SignImageData data in signImgList) {
|
for (SignImageData data in signImgList) {
|
||||||
for (Map<String, dynamic> img in signList) {
|
String path = data.filePath ?? '';
|
||||||
String imgName = 'file${data.key}';
|
if (!path.contains('uploadFiles')) {
|
||||||
if (data.filePath!.contains('uploadFiles')) {
|
filePaths.add(data);
|
||||||
final idata = {
|
} else {
|
||||||
|
severImageList.add({
|
||||||
'filePath': data.filePath,
|
'filePath': data.filePath,
|
||||||
'SIGNER_TIME': data.SIGNER_TIME,
|
'SIGNER_TIME': data.SIGNER_TIME,
|
||||||
'key': data.key,
|
'key': data.key,
|
||||||
};
|
});
|
||||||
sineImageList.add(idata);
|
|
||||||
}
|
|
||||||
if (imgName == img['key']) {
|
|
||||||
final idata = {
|
|
||||||
'filePath': img['filePath'] ?? '',
|
|
||||||
'SIGNER_TIME': data.SIGNER_TIME,
|
|
||||||
'key': data.key,
|
|
||||||
};
|
|
||||||
sineImageList.add(idata);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (filePaths.length == 0) {
|
||||||
|
// 如果没有本地未提交,直接返回
|
||||||
setState(() => buttonLoading = true);
|
setState(() => buttonLoading = true);
|
||||||
LoadingDialogHelper.hide();
|
LoadingDialogHelper.hide();
|
||||||
Navigator.pop(context, {
|
Navigator.pop(context, {
|
||||||
|
@ -167,7 +156,37 @@ class _DangerousOptionsPageState extends State<DangerousOptionsPage> {
|
||||||
imgList
|
imgList
|
||||||
.map((e) => {'local': e.localPath, 'remote': e.serverPath})
|
.map((e) => {'local': e.localPath, 'remote': e.serverPath})
|
||||||
.toList(),
|
.toList(),
|
||||||
'signImgList': sineImageList,
|
'signImgList': signImgList,
|
||||||
|
'index': index,
|
||||||
|
'status': status,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final result = await ApiService.saveDangerousOptionsFile(filePaths.map((item) => item.filePath).toList());
|
||||||
|
final List<dynamic> signList = result['FILE_PATH_LIST'];
|
||||||
|
for (SignImageData data in filePaths) {
|
||||||
|
for (Map<String, dynamic> img in signList) {
|
||||||
|
String imgName = 'file${data.key}';
|
||||||
|
|
||||||
|
if (imgName == img['key']) {
|
||||||
|
final idata = {
|
||||||
|
'filePath': img['filePath'] ?? '',
|
||||||
|
'SIGNER_TIME': data.SIGNER_TIME,
|
||||||
|
'key': data.key,
|
||||||
|
};
|
||||||
|
severImageList.add(idata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() => buttonLoading = true);
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
|
Navigator.pop(context, {
|
||||||
|
'imgList':
|
||||||
|
imgList
|
||||||
|
.map((e) => {'local': e.localPath, 'remote': e.serverPath})
|
||||||
|
.toList(),
|
||||||
|
'signImgList': severImageList,
|
||||||
'index': index,
|
'index': index,
|
||||||
'status': status,
|
'status': status,
|
||||||
});
|
});
|
||||||
|
@ -350,7 +369,9 @@ class _DangerousOptionsPageState extends State<DangerousOptionsPage> {
|
||||||
onMediaAdded: _onImageAdded,
|
onMediaAdded: _onImageAdded,
|
||||||
onMediaRemoved: (path) {
|
onMediaRemoved: (path) {
|
||||||
print(path);
|
print(path);
|
||||||
final item = imgList.firstWhere((e) => path.contains(e.localPath) );
|
final item = imgList.firstWhere(
|
||||||
|
(e) => path.contains(e.localPath),
|
||||||
|
);
|
||||||
_onImageRemoved(item);
|
_onImageRemoved(item);
|
||||||
},
|
},
|
||||||
onAiIdentify: () {},
|
onAiIdentify: () {},
|
||||||
|
|
|
@ -223,6 +223,7 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.twoRowButtonTitleText(
|
ItemListWidget.twoRowButtonTitleText(
|
||||||
label: '风险辨识结果',
|
label: '风险辨识结果',
|
||||||
|
isInput: false,
|
||||||
isEditable: widget.isEditable,
|
isEditable: widget.isEditable,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await showDialog<String>(
|
await showDialog<String>(
|
||||||
|
|
|
@ -110,7 +110,8 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
||||||
baseImgPath: baseImgPath,
|
baseImgPath: baseImgPath,
|
||||||
sectionKey: 'CONFESS',
|
sectionKey: 'CONFESS',
|
||||||
nameKey: 'CONFESS_USER_NAME',
|
nameKey: 'CONFESS_USER_NAME',
|
||||||
headerTitle: '安全交底人意见',
|
headerTitle: '安全交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '安全交底人',
|
roleTitle: '安全交底人',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
||||||
|
@ -121,12 +122,14 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'ACCEPT_CONFESS',
|
sectionKey: 'ACCEPT_CONFESS',
|
||||||
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
||||||
headerTitle: '接受交底人',
|
headerTitle: '接受交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '',
|
roleTitle: '',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'GUARDIAN'))
|
if (FormUtils.hasValue(signs, 'GUARDIAN'))
|
||||||
ConfirmWithSignWidget(
|
ConfirmWithSignWidget(
|
||||||
signs: signs,
|
signs: signs,
|
||||||
pd: pd,
|
pd: pd,
|
||||||
|
isShowTime: false,
|
||||||
baseImgPath: baseImgPath,
|
baseImgPath: baseImgPath,
|
||||||
sectionKey: 'GUARDIAN',
|
sectionKey: 'GUARDIAN',
|
||||||
nameKey: 'GUARDIAN_USER_NAME',
|
nameKey: 'GUARDIAN_USER_NAME',
|
||||||
|
|
|
@ -387,7 +387,7 @@ if (reasonText.isEmpty) {
|
||||||
),
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||||
allowPast:false,
|
minTimeStr: pd['WORK_END_DATE'],
|
||||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
|
|
|
@ -212,6 +212,7 @@ class _CutroadDetailFormWidgetState extends State<CutroadDetailFormWidget> {
|
||||||
|
|
||||||
ItemListWidget.twoRowButtonTitleText(
|
ItemListWidget.twoRowButtonTitleText(
|
||||||
label: '风险辨识结果',
|
label: '风险辨识结果',
|
||||||
|
isInput: false,
|
||||||
isEditable: widget.isEditable,
|
isEditable: widget.isEditable,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await showDialog<String>(
|
await showDialog<String>(
|
||||||
|
|
|
@ -106,6 +106,7 @@ class CutroadFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'CONFESS',
|
sectionKey: 'CONFESS',
|
||||||
nameKey: 'CONFESS_USER_NAME',
|
nameKey: 'CONFESS_USER_NAME',
|
||||||
headerTitle: '安全交底人',
|
headerTitle: '安全交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '安全交底人',
|
roleTitle: '安全交底人',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
||||||
|
@ -116,6 +117,7 @@ class CutroadFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'ACCEPT_CONFESS',
|
sectionKey: 'ACCEPT_CONFESS',
|
||||||
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
||||||
headerTitle: '接受交底人',
|
headerTitle: '接受交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '',
|
roleTitle: '',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
||||||
|
|
|
@ -378,7 +378,7 @@ if (reasonText.isEmpty) {
|
||||||
),
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||||
allowPast:false,
|
minTimeStr: pd['WORK_END_DATE'],
|
||||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
|
|
|
@ -210,6 +210,7 @@ class _BreakgroundDetailFormWidgetState
|
||||||
|
|
||||||
ItemListWidget.twoRowButtonTitleText(
|
ItemListWidget.twoRowButtonTitleText(
|
||||||
label: '风险辨识结果',
|
label: '风险辨识结果',
|
||||||
|
isInput: false,
|
||||||
isEditable: widget.isEditable,
|
isEditable: widget.isEditable,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await showDialog<String>(
|
await showDialog<String>(
|
||||||
|
|
|
@ -116,6 +116,7 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'CONFESS',
|
sectionKey: 'CONFESS',
|
||||||
nameKey: 'CONFESS_USER_NAME',
|
nameKey: 'CONFESS_USER_NAME',
|
||||||
headerTitle: '安全交底人',
|
headerTitle: '安全交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '安全交底人',
|
roleTitle: '安全交底人',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
||||||
|
@ -126,6 +127,7 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'ACCEPT_CONFESS',
|
sectionKey: 'ACCEPT_CONFESS',
|
||||||
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
||||||
headerTitle: '接受交底人',
|
headerTitle: '接受交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '',
|
roleTitle: '',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
||||||
|
|
|
@ -381,7 +381,7 @@ if (reasonText.isEmpty) {
|
||||||
),
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||||
allowPast:false,
|
minTimeStr: pd['WORK_END_DATE'],
|
||||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
|
|
|
@ -261,6 +261,7 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.twoRowButtonTitleText(
|
ItemListWidget.twoRowButtonTitleText(
|
||||||
label: '风险辨识结果',
|
label: '风险辨识结果',
|
||||||
|
isInput: false,
|
||||||
isEditable: widget.isEditable,
|
isEditable: widget.isEditable,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await showDialog<String>(
|
await showDialog<String>(
|
||||||
|
|
|
@ -278,6 +278,7 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'CONFESS',
|
sectionKey: 'CONFESS',
|
||||||
nameKey: 'CONFESS_USER_NAME',
|
nameKey: 'CONFESS_USER_NAME',
|
||||||
headerTitle: '安全交底人',
|
headerTitle: '安全交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '安全交底人',
|
roleTitle: '安全交底人',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
||||||
|
@ -288,6 +289,7 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'ACCEPT_CONFESS',
|
sectionKey: 'ACCEPT_CONFESS',
|
||||||
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
||||||
headerTitle: '接受交底人',
|
headerTitle: '接受交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '',
|
roleTitle: '',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
|
@ -381,7 +381,7 @@ if (reasonText.isEmpty) {
|
||||||
),
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||||
allowPast:false,
|
minTimeStr: pd['WORK_END_DATE'],
|
||||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
|
|
|
@ -241,6 +241,7 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.twoRowButtonTitleText(
|
ItemListWidget.twoRowButtonTitleText(
|
||||||
label: '风险辨识结果',
|
label: '风险辨识结果',
|
||||||
|
isInput: false,
|
||||||
isEditable: widget.isEditable,
|
isEditable: widget.isEditable,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await showDialog<String>(
|
await showDialog<String>(
|
||||||
|
|
|
@ -115,6 +115,7 @@ class HighWorkFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'CONFESS',
|
sectionKey: 'CONFESS',
|
||||||
nameKey: 'CONFESS_USER_NAME',
|
nameKey: 'CONFESS_USER_NAME',
|
||||||
headerTitle: '安全交底人',
|
headerTitle: '安全交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '安全交底人',
|
roleTitle: '安全交底人',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
||||||
|
@ -125,6 +126,7 @@ class HighWorkFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'ACCEPT_CONFESS',
|
sectionKey: 'ACCEPT_CONFESS',
|
||||||
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
||||||
headerTitle: '接受交底人',
|
headerTitle: '接受交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '',
|
roleTitle: '',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
||||||
|
|
|
@ -436,7 +436,25 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
||||||
//FocusHelper.clearFocus(context);
|
//FocusHelper.clearFocus(context);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
bool checkWorkTime(Map<String, dynamic> pd, BuildContext context) {
|
||||||
|
// 解析开始和结束时间
|
||||||
|
final start = DateTime.parse(pd['WORK_EXPECTED_START_TIME'] as String);
|
||||||
|
final end = DateTime.parse(pd['WORK_EXPECTED_END_TIME'] as String);
|
||||||
|
|
||||||
|
// 校验:结束时间必须晚于开始时间
|
||||||
|
if (end.isAtSameMomentAs(start) || end.isBefore(start)) {
|
||||||
|
ToastUtil.showNormal(context, '作业开始时间不能晚于或等于结束时间,请重新选择');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final diffMs = end.difference(start).inMilliseconds;
|
||||||
|
const max8h = 7 * 24 * 60 * 60 * 1000;
|
||||||
|
if (diffMs >= max8h) {
|
||||||
|
ToastUtil.showNormal(context, '作业开始时间与结束时间应不超过7天,请重新选择');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
/// 提交 1 提交 0暂存
|
/// 提交 1 提交 0暂存
|
||||||
Future<void> _submit(String status) async {
|
Future<void> _submit(String status) async {
|
||||||
// 通用文本字段校验规则
|
// 通用文本字段校验规则
|
||||||
|
|
|
@ -59,6 +59,12 @@ class _HighworkJszyDetailState extends State<HighworkJszyDetail> {
|
||||||
// 校验:结束时间必须晚于开始时间
|
// 校验:结束时间必须晚于开始时间
|
||||||
if (end.isAtSameMomentAs(start) || end.isBefore(start)) {
|
if (end.isAtSameMomentAs(start) || end.isBefore(start)) {
|
||||||
ToastUtil.showNormal(context, '作业开始时间不能晚于或等于结束时间,请重新选择');
|
ToastUtil.showNormal(context, '作业开始时间不能晚于或等于结束时间,请重新选择');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final diffMs = end.difference(start).inMilliseconds;
|
||||||
|
const max8h = 7 *24 * 60 * 60 * 1000;
|
||||||
|
if (diffMs >= max8h) {
|
||||||
|
ToastUtil.showNormal(context, '作业开始时间与结束时间应不超过7天,请重新选择');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +74,6 @@ class _HighworkJszyDetailState extends State<HighworkJszyDetail> {
|
||||||
|
|
||||||
/// 作废 -1 通过 1
|
/// 作废 -1 通过 1
|
||||||
Future<void> _submit(String status) async {
|
Future<void> _submit(String status) async {
|
||||||
|
|
||||||
String? reasonText = '';
|
String? reasonText = '';
|
||||||
if (status == '1') {
|
if (status == '1') {
|
||||||
if (endTime.isEmpty) {
|
if (endTime.isEmpty) {
|
||||||
|
@ -84,7 +89,7 @@ class _HighworkJszyDetailState extends State<HighworkJszyDetail> {
|
||||||
title: '作废原因',
|
title: '作废原因',
|
||||||
hintText: '请输入作废原因',
|
hintText: '请输入作废原因',
|
||||||
cancelText: '取消',
|
cancelText: '取消',
|
||||||
confirmText: '确定'
|
confirmText: '确定',
|
||||||
);
|
);
|
||||||
// 用户取消(或点遮罩、返回键)
|
// 用户取消(或点遮罩、返回键)
|
||||||
if (reasonText == null) {
|
if (reasonText == null) {
|
||||||
|
|
|
@ -381,7 +381,7 @@ if (reasonText.isEmpty) {
|
||||||
),
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||||
allowPast:false,
|
minTimeStr: pd['WORK_END_DATE'],
|
||||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
|
|
|
@ -184,7 +184,6 @@ class _HomeGasTestPageState extends State<HomeGasTestPage> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (status == 1) {
|
if (status == 1) {
|
||||||
|
|
||||||
Map itemForm = {
|
Map itemForm = {
|
||||||
'ANALYZE_GAS': _gasController.text,
|
'ANALYZE_GAS': _gasController.text,
|
||||||
'ANALYZE_RESULT': _resultController.text,
|
'ANALYZE_RESULT': _resultController.text,
|
||||||
|
@ -256,7 +255,7 @@ if (reasonText.isEmpty) {
|
||||||
'CORPINFO_ID': SessionService.instance.corpinfoId,
|
'CORPINFO_ID': SessionService.instance.corpinfoId,
|
||||||
'USER_ID': SessionService.instance.loginUserId,
|
'USER_ID': SessionService.instance.loginUserId,
|
||||||
};
|
};
|
||||||
|
LoadingDialogHelper.show();
|
||||||
try {
|
try {
|
||||||
await ApiService.saveGasTest('hotwork', formData, imagePaths);
|
await ApiService.saveGasTest('hotwork', formData, imagePaths);
|
||||||
ToastUtil.showNormal(context, status == 1 ? '保存成功' : '作废成功');
|
ToastUtil.showNormal(context, status == 1 ? '保存成功' : '作废成功');
|
||||||
|
@ -266,6 +265,7 @@ if (reasonText.isEmpty) {
|
||||||
} finally {
|
} finally {
|
||||||
setState(() => _loading = false);
|
setState(() => _loading = false);
|
||||||
}
|
}
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -244,6 +244,7 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.twoRowButtonTitleText(
|
ItemListWidget.twoRowButtonTitleText(
|
||||||
label: '风险辨识结果',
|
label: '风险辨识结果',
|
||||||
|
isInput: false,
|
||||||
isEditable: widget.isEditable,
|
isEditable: widget.isEditable,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await showDialog<String>(
|
await showDialog<String>(
|
||||||
|
|
|
@ -292,7 +292,8 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
||||||
baseImgPath: baseImgPath,
|
baseImgPath: baseImgPath,
|
||||||
sectionKey: 'CONFESS',
|
sectionKey: 'CONFESS',
|
||||||
nameKey: 'CONFESS_USER_NAME',
|
nameKey: 'CONFESS_USER_NAME',
|
||||||
headerTitle: '安全交底人意见',
|
headerTitle: '安全交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '安全交底人',
|
roleTitle: '安全交底人',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
||||||
|
@ -303,6 +304,7 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'ACCEPT_CONFESS',
|
sectionKey: 'ACCEPT_CONFESS',
|
||||||
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
||||||
headerTitle: '接受交底人',
|
headerTitle: '接受交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '',
|
roleTitle: '',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
|
@ -217,6 +217,7 @@ if (reasonText.isEmpty) {
|
||||||
'CORPINFO_ID': SessionService.instance.corpinfoId,
|
'CORPINFO_ID': SessionService.instance.corpinfoId,
|
||||||
'USER_ID': SessionService.instance.loginUserId,
|
'USER_ID': SessionService.instance.loginUserId,
|
||||||
};
|
};
|
||||||
|
LoadingDialogHelper.show();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await ApiService.saveGasTest('electricity', formData, imagePaths);
|
await ApiService.saveGasTest('electricity', formData, imagePaths);
|
||||||
|
@ -227,6 +228,7 @@ if (reasonText.isEmpty) {
|
||||||
} finally {
|
} finally {
|
||||||
setState(() => _loading = false);
|
setState(() => _loading = false);
|
||||||
}
|
}
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 选择气体类型
|
/// 选择气体类型
|
||||||
|
|
|
@ -387,7 +387,7 @@ if (reasonText.isEmpty) {
|
||||||
),
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||||
allowPast:false,
|
minTimeStr: pd['WORK_END_DATE'],
|
||||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
|
|
|
@ -642,6 +642,7 @@ class _BlindboardDetailFormWidgetState
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.twoRowButtonTitleText(
|
ItemListWidget.twoRowButtonTitleText(
|
||||||
label: '风险辨识结果',
|
label: '风险辨识结果',
|
||||||
|
isInput: false,
|
||||||
isEditable: widget.isEditable,
|
isEditable: widget.isEditable,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await showDialog<String>(
|
await showDialog<String>(
|
||||||
|
|
|
@ -299,6 +299,7 @@ class BlindboardFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'CONFESS',
|
sectionKey: 'CONFESS',
|
||||||
nameKey: 'CONFESS_USER_NAME',
|
nameKey: 'CONFESS_USER_NAME',
|
||||||
headerTitle: '安全交底人',
|
headerTitle: '安全交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '安全交底人',
|
roleTitle: '安全交底人',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
||||||
|
@ -309,6 +310,7 @@ class BlindboardFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'ACCEPT_CONFESS',
|
sectionKey: 'ACCEPT_CONFESS',
|
||||||
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
||||||
headerTitle: '接受交底人',
|
headerTitle: '接受交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '',
|
roleTitle: '',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
||||||
|
|
|
@ -374,7 +374,7 @@ if (reasonText.isEmpty) {
|
||||||
),
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||||
allowPast:false,
|
minTimeStr: pd['WORK_END_DATE'],
|
||||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
|
|
|
@ -254,6 +254,7 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ItemListWidget.twoRowButtonTitleText(
|
ItemListWidget.twoRowButtonTitleText(
|
||||||
label: '风险辨识结果',
|
label: '风险辨识结果',
|
||||||
|
isInput: false,
|
||||||
isEditable: widget.isEditable,
|
isEditable: widget.isEditable,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await showDialog<String>(
|
await showDialog<String>(
|
||||||
|
|
|
@ -120,6 +120,7 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'CONFESS',
|
sectionKey: 'CONFESS',
|
||||||
nameKey: 'CONFESS_USER_NAME',
|
nameKey: 'CONFESS_USER_NAME',
|
||||||
headerTitle: '安全交底人',
|
headerTitle: '安全交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '安全交底人',
|
roleTitle: '安全交底人',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
if (FormUtils.hasValue(signs, 'ACCEPT_CONFESS'))
|
||||||
|
@ -130,6 +131,7 @@ class SpecialWorkFormBaseWork extends StatelessWidget {
|
||||||
sectionKey: 'ACCEPT_CONFESS',
|
sectionKey: 'ACCEPT_CONFESS',
|
||||||
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
nameKey: 'ACCEPT_CONFESS_USER_NAME',
|
||||||
headerTitle: '接受交底人',
|
headerTitle: '接受交底人',
|
||||||
|
isShowTime: false,
|
||||||
roleTitle: '',
|
roleTitle: '',
|
||||||
),
|
),
|
||||||
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
if (FormUtils.hasValue(signs, 'CONFIRM'))
|
||||||
|
|
|
@ -252,6 +252,7 @@ if (reasonText.isEmpty) {
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
);
|
);
|
||||||
if (!confirmed) return;
|
if (!confirmed) return;
|
||||||
|
LoadingDialogHelper.show();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await ApiService.saveGasTest('confinedspace', formData, imagePaths);
|
await ApiService.saveGasTest('confinedspace', formData, imagePaths);
|
||||||
|
@ -262,6 +263,7 @@ if (reasonText.isEmpty) {
|
||||||
} finally {
|
} finally {
|
||||||
setState(() => _loading = false);
|
setState(() => _loading = false);
|
||||||
}
|
}
|
||||||
|
LoadingDialogHelper.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 选择计量单位
|
/// 选择计量单位
|
||||||
|
|
|
@ -391,7 +391,7 @@ if (reasonText.isEmpty) {
|
||||||
),
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||||
allowPast:false,
|
minTimeStr: pd['WORK_END_DATE'],
|
||||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
|
|
|
@ -101,19 +101,20 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
if (FormUtils.hasValue(result, 'pd')) {
|
if (FormUtils.hasValue(result, 'pd')) {
|
||||||
Map pd = result['pd'];
|
Map pd = result['pd'];
|
||||||
final versionInfo = await getAppVersion();
|
final versionInfo = await getAppVersion();
|
||||||
bool isWifi = await checkNetworkWifi();
|
bool isWifi = true;
|
||||||
if (versionInfo.versionName != pd['VERSION']) {
|
if (versionInfo.versionName != pd['VERSION']) {
|
||||||
//有更新 提示更新
|
//有更新 提示更新
|
||||||
final ok = await CustomAlertDialog.showConfirm(
|
final ok = await CustomAlertDialog.showConfirm(
|
||||||
context,
|
context,
|
||||||
|
barrierDismissible:false,
|
||||||
title: '更新通知',
|
title: '更新通知',
|
||||||
content: isWifi ? '发现新版本,是否更新?为了更好的体验,请更新到最新版本。' : '发现新版本,检查到您当前使用的是移动网络,是否更新?更新时请注意流量消耗。为了更好的体验,请更新到最新版本。',
|
content: isWifi ? '发现新版本,是否更新?为了更好的体验,请更新到最新版本。' : '发现新版本,检查到您当前使用的是移动网络,是否更新?更新时请注意流量消耗。为了更好的体验,请更新到最新版本。',
|
||||||
cancelText: pd['ISUPDATE'] == '1' ? '' : '稍后更新',
|
cancelText: pd['ISUPDATE'] == '1' ? '' : '稍后更新',
|
||||||
confirmText: '立即更新'
|
confirmText: '立即更新'
|
||||||
);
|
);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
// await showUpdateConfirmDialog(context, apkUrl: apkUrl);
|
final apkUrl = pd['FILEURL'] ?? '';
|
||||||
|
await showUpdateConfirm(context, apkUrl: apkUrl);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import 'package:qhd_prevention/pages/mine/mine_set_pwd_page.dart';
|
||||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||||
import 'package:qhd_prevention/services/auth_service.dart';
|
import 'package:qhd_prevention/services/auth_service.dart';
|
||||||
import 'package:qhd_prevention/tools/h_colors.dart';
|
import 'package:qhd_prevention/tools/h_colors.dart';
|
||||||
|
import 'package:qhd_prevention/tools/update/update_dialogs.dart';
|
||||||
|
|
||||||
import '../../tools/tools.dart';
|
import '../../tools/tools.dart';
|
||||||
|
|
||||||
|
@ -26,19 +27,26 @@ class _MineSetPageState extends State<MineSetPage> {
|
||||||
final result = await AuthService.checkUpdate();
|
final result = await AuthService.checkUpdate();
|
||||||
LoadingDialogHelper.hide();
|
LoadingDialogHelper.hide();
|
||||||
if (FormUtils.hasValue(result, 'pd')) {
|
if (FormUtils.hasValue(result, 'pd')) {
|
||||||
|
|
||||||
// 有更新 提示更新
|
|
||||||
Map pd = result['pd'];
|
Map pd = result['pd'];
|
||||||
CustomAlertDialog.showConfirm(
|
final versionInfo = await getAppVersion();
|
||||||
|
bool isWifi = true;
|
||||||
|
if (versionInfo.versionName != pd['VERSION']) {
|
||||||
|
//有更新 提示更新
|
||||||
|
final ok = await CustomAlertDialog.showConfirm(
|
||||||
context,
|
context,
|
||||||
|
barrierDismissible:false,
|
||||||
title: '更新通知',
|
title: '更新通知',
|
||||||
cancelText: '',
|
content: isWifi ? '发现新版本,是否更新?为了更好的体验,请更新到最新版本。' : '发现新版本,检查到您当前使用的是移动网络,是否更新?更新时请注意流量消耗。为了更好的体验,请更新到最新版本。',
|
||||||
confirmText: '我知道了',
|
cancelText: pd['ISUPDATE'] == '1' ? '' : '稍后更新',
|
||||||
content: pd['UPLOAD_CONTENT'] ?? '',
|
confirmText: '立即更新'
|
||||||
onConfirm: () {
|
|
||||||
ToastUtil.showNormal(context, '更新去吧!');
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
if (ok) {
|
||||||
|
final apkUrl = pd['FILEURL'] ?? '';
|
||||||
|
await showUpdateConfirm(context, apkUrl: apkUrl);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
_loadAppVersion();
|
_loadAppVersion();
|
||||||
|
|
||||||
|
|
|
@ -600,6 +600,7 @@ Future<bool> checkNetworkWifi() async {
|
||||||
final connectivityResult = await Connectivity().checkConnectivity();
|
final connectivityResult = await Connectivity().checkConnectivity();
|
||||||
if (connectivityResult == ConnectivityResult.mobile) {
|
if (connectivityResult == ConnectivityResult.mobile) {
|
||||||
print("当前是移动网络(可能是 2G/3G/4G/5G)");
|
print("当前是移动网络(可能是 2G/3G/4G/5G)");
|
||||||
|
return false;
|
||||||
} else if (connectivityResult == ConnectivityResult.wifi) {
|
} else if (connectivityResult == ConnectivityResult.wifi) {
|
||||||
return true;
|
return true;
|
||||||
print("当前是 WiFi");
|
print("当前是 WiFi");
|
||||||
|
|
|
@ -3,43 +3,16 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:qhd_prevention/services/update_service.dart';
|
import 'package:qhd_prevention/services/update_service.dart';
|
||||||
|
|
||||||
/// 显示“发现新版本”确认对话框,点击更新后会弹出下载进度弹窗
|
/// 显示“发现新版本”确认对话框,点击更新后会弹出下载进度弹窗
|
||||||
Future<void> showUpdateConfirmDialog(BuildContext context, {
|
Future<void> showUpdateConfirm(BuildContext context, {
|
||||||
required String apkUrl,
|
required String apkUrl,
|
||||||
String title = '发现新版本',
|
|
||||||
String content = '检测到新版本,是否立即更新?',
|
|
||||||
String updateButtonText = '更新',
|
|
||||||
String cancelButtonText = '稍后',
|
|
||||||
}) async {
|
|
||||||
final confirmed = await showDialog<bool>(
|
|
||||||
context: context,
|
|
||||||
barrierDismissible: false,
|
|
||||||
builder: (ctx) {
|
|
||||||
return AlertDialog(
|
|
||||||
title: Text(title),
|
|
||||||
content: Text(content),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.of(ctx).pop(false),
|
|
||||||
child: Text(cancelButtonText),
|
|
||||||
),
|
|
||||||
ElevatedButton(
|
|
||||||
onPressed: () => Navigator.of(ctx).pop(true),
|
|
||||||
child: Text(updateButtonText),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (confirmed == true) {
|
}) async {
|
||||||
// 跳出下载进度弹窗(阻塞式,直到弹窗被关闭)
|
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
builder: (ctx) => DownloadProgressDialog(apkUrl: apkUrl),
|
builder: (ctx) => DownloadProgressDialog(apkUrl: apkUrl),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// 下载进度弹窗(会在 initState 里自动开始下载)
|
/// 下载进度弹窗(会在 initState 里自动开始下载)
|
||||||
class DownloadProgressDialog extends StatefulWidget {
|
class DownloadProgressDialog extends StatefulWidget {
|
||||||
|
|
|
@ -16,8 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
#version: 2.1.2+10
|
version: 2.1.2+59
|
||||||
version: 2.2.0
|
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.7.0
|
sdk: ^3.7.0
|
||||||
|
|
Loading…
Reference in New Issue