。。。

main
hs 2025-09-18 21:45:41 +08:00
parent 6d737adce3
commit 21387b3cbc
49 changed files with 379 additions and 310 deletions

View File

@ -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

View File

@ -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

View File

@ -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)
}
}

View File

@ -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

View File

@ -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";

View File

@ -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);
}
}, },
), ),
), ),

View File

@ -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'
}, },
); );
} }

View File

@ -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();

View File

@ -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;
} }
} }

View File

@ -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;

View File

@ -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) {

View File

@ -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 =

View File

@ -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,
), ),
], ],
), ),

View File

@ -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: () {},

View File

@ -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>(

View File

@ -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',

View File

@ -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,
); );

View File

@ -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>(

View File

@ -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'))

View File

@ -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,
); );

View File

@ -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>(

View File

@ -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'))

View File

@ -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,
); );

View File

@ -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>(

View File

@ -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: '',
), ),

View File

@ -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,
); );

View File

@ -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>(

View File

@ -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'))

View File

@ -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 {
// //

View File

@ -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) {

View File

@ -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,
); );

View File

@ -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

View File

@ -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>(

View File

@ -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: '',
), ),

View File

@ -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();
} }
/// ///

View File

@ -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,
); );

View File

@ -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>(

View File

@ -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'))

View File

@ -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,
); );

View File

@ -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>(

View File

@ -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'))

View File

@ -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();
} }
/// ///

View File

@ -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,
); );

View File

@ -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;
} }

View File

@ -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();

View File

@ -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");

View File

@ -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 {

View File

@ -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