From 6351d00c4b72dff122b30688aef591ac2ea91666 Mon Sep 17 00:00:00 2001 From: hs <873121290@qq.com> Date: Tue, 2 Sep 2025 16:22:17 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=82=E3=80=82=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/map/index.html | 17 +- assets/map/test_baidu_map.html | 380 ------------------ lib/customWidget/BaiDuMap/Map_page.dart | 150 +++---- lib/customWidget/custom_button.dart | 4 +- lib/customWidget/photo_picker_row.dart | 15 +- .../picker/CupertinoDatePicker.dart | 130 ++++-- lib/customWidget/toast_util.dart | 40 +- lib/http/ApiService.dart | 26 +- .../Danger/danger_manager_detail_page.dart | 7 +- .../punishment_manager_detail_page.dart | 3 - .../SafeCheck/custom/safe_drawer_page.dart | 30 -- .../check_information_one_item.dart | 39 +- .../hazard_registration_page.dart | 51 +-- .../app/Danger_paicha/quick_report_page.dart | 42 +- .../home/NFC/nfc_check_danger_detail.dart | 42 -- .../safeCheck_assignment_detail_page.dart | 8 +- .../Record/defend_record_detail_page.dart | 14 +- .../Start/safeCheck_drawer_page.dart | 13 - .../team_safety_commitment_apply.dart | 3 + lib/pages/home/home_page.dart | 6 + lib/pages/home/risk/risk_detail_page.dart | 38 +- lib/pages/home/study/study_my_task_page.dart | 13 +- lib/pages/home/study/study_score_page.dart | 6 +- lib/pages/home/study/take_exam_page.dart | 137 ++++--- .../home/study/video_study_detail_page.dart | 4 +- .../special_wrok/dangerous_options_page.dart | 3 - .../aqjd_work_detail/hotwork_aqjd_detail.dart | 3 - .../dh_work_detai/hotwork_apply_detail.dart | 10 +- .../ysgd_work_detail/hotwork_ysgd_detail.dart | 8 +- .../aqjd_work_detail/cutroad_aqjd_detail.dart | 3 - .../dl_work_detai/cutroad_apply_detail.dart | 8 +- .../ysgd_work_detail/cutroad_ysgd_detail.dart | 6 - .../zyr_work_detail/cutroad_zyr_detail.dart | 3 - .../breakground_aqjd_detail.dart | 3 - .../breakground_apply_detail.dart | 8 +- .../breakground_ysgd_detail.dart | 4 +- .../breakground_zyr_detail.dart | 3 - .../hoistwork_aqjd_detail.dart | 3 - .../dz_work_detai/hoistwork_apply_detail.dart | 8 +- .../hoistwork_ysgd_detail.dart | 8 +- .../highwork_aqjd_detail.dart | 3 - .../gc_work_detai/highwork_apply_detail.dart | 8 +- .../highwork_ysgd_detail.dart | 8 +- .../electricity_aqjd_detail.dart | 3 - .../electricity_apply_detail.dart | 5 +- .../electricity_ysgd_detail.dart | 8 +- .../blindboard_aqjd_detail.dart | 3 - .../blindboard_cjry_detail.dart | 3 - .../blindboard_apply_detail.dart | 33 +- .../blindboard_ysgd_detail.dart | 8 +- .../spacework_aqjd_detail.dart | 3 - .../spacework_apply_detail.dart | 8 +- .../spacework_ysgd_detail.dart | 8 +- lib/pages/home/work/danger_project_page.dart | 34 +- lib/pages/login_page.dart | 4 +- lib/tools/coord_convert.dart | 229 +++++++++++ lib/tools/tools.dart | 1 + pubspec.yaml | 3 +- 58 files changed, 680 insertions(+), 991 deletions(-) delete mode 100644 assets/map/test_baidu_map.html create mode 100644 lib/tools/coord_convert.dart diff --git a/assets/map/index.html b/assets/map/index.html index 971b9c3..0c33628 100644 --- a/assets/map/index.html +++ b/assets/map/index.html @@ -230,10 +230,19 @@ //alert("当前选择点位不在区域中!"); notifyHost({type:'point_selected', ok:false, reason:'out_of_polygon', lng:e.latlng.lng, lat:e.latlng.lat}); } else { - map.addOverlay(marker); - // 把 BD09 -> WGS84 转换后的点回传给宿主 - fnConvertorBd09ToWgs84Data2(e.latlng.lng, e.latlng.lat); - notifyHost({type:'point_selected', ok:true, lng:e.latlng.lng, lat:e.latlng.lat}); + map.addOverlay(marker); + // 把 BD09 -> WGS84 转换后的点回传给宿主 + fnConvertorBd09ToWgs84Data2(e.latlng.lng, e.latlng.lat); + notifyHost({type:'point_selected', ok:true, lng:e.latlng.lng, lat:e.latlng.lat}); + + // // 直接把BD09回传 + // notifyHost({type:'converted', longitue: e.latlng.lng, latitude: e.latlng.lat}); + // notifyHost({ + // type: 'point_selected', + // ok: true, + // lng: e.latlng.lng, + // lat: e.latlng.lat + // }); } } catch (err) { console.error('MapClick error', err); diff --git a/assets/map/test_baidu_map.html b/assets/map/test_baidu_map.html deleted file mode 100644 index 010ecac..0000000 --- a/assets/map/test_baidu_map.html +++ /dev/null @@ -1,380 +0,0 @@ - - - - - 特殊作业扎点 - - - - - - - - - - -
- - - - - diff --git a/lib/customWidget/BaiDuMap/Map_page.dart b/lib/customWidget/BaiDuMap/Map_page.dart index ef27cb6..4210252 100644 --- a/lib/customWidget/BaiDuMap/Map_page.dart +++ b/lib/customWidget/BaiDuMap/Map_page.dart @@ -4,7 +4,9 @@ import 'package:qhd_prevention/customWidget/BaiDuMap/BaiduMapWebView.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/services/location_service.dart'; +import 'package:qhd_prevention/tools/coord_convert.dart'; import 'package:qhd_prevention/tools/tools.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'package:geolocator/geolocator.dart'; @@ -37,86 +39,84 @@ class _MapPageState extends State { _isLoading = true; _errorMessage = null; }); - LoadingDialogHelper.show(message: '地图加载中'); try { - final LocationResult loc = await LocationService.getCurrentLocation( - timeout: const Duration(seconds: 10), - ); + await fetchAndSaveBd09(context); - // 解析 gson - try { - final parsed = jsonDecode(widget.gson); - if (parsed is List) { - _gsonList = parsed; - } else { - _gsonList = []; - } - } catch (e) { - debugPrint('解析 gson 失败: $e'); + final prefs = await SharedPreferences.getInstance(); + String latitude = prefs.getString('bd_lat') ?? ''; + String longitude = prefs.getString('bd_lon') ?? ''; + _loadWebView(LocationResult(latitude: latitude, longitude: longitude)); + + } catch (e, st) { + + final prefs = await SharedPreferences.getInstance(); + String latitude = prefs.getString('bd_lat') ?? ''; + String longitude = prefs.getString('bd_lon') ?? ''; + _loadWebView(LocationResult(latitude: latitude, longitude: longitude)); + } + } + Future _loadWebView(LocationResult loc) async { + // 解析 gson + try { + final parsed = jsonDecode(widget.gson); + if (parsed is List) { + _gsonList = parsed; + } else { _gsonList = []; } - - if (!mounted) return; - - setState(() { - _longitude = loc.longitudeAsDouble; - _latitude = loc.latitudeAsDouble; - }); - - - // 初始化 WebViewController 并加载本地页面 - _controller = WebViewController() - ..setJavaScriptMode(JavaScriptMode.unrestricted) - // 注册 JS 通道 'JS' —— 对应 HTML 中的 window.JS.postMessage(...) - ..addJavaScriptChannel('JS', onMessageReceived: (dynamic message) { - // message 是动态对象,不在签名中引用具体类型以避免 "Undefined class" 问题 - String payload; - try { - payload = message.message ?? message.toString(); - } catch (e) { - payload = message.toString(); - } - _onJsMessage(payload); - }) - // 也保留一个备用通道 'Flutter' - ..addJavaScriptChannel('Flutter', onMessageReceived: (dynamic message) { - String payload; - try { - payload = message.message ?? message.toString(); - } catch (e) { - payload = message.toString(); - } - _onJsMessage(payload); - }) - ..setNavigationDelegate( - NavigationDelegate( - onPageFinished: (String url) async { - LoadingDialogHelper.hide(); - - debugPrint('网页加载完成: $url'); - await _injectLocationParams(); - }, - onWebResourceError: (err) { - debugPrint('Web resource error: ${err.description}'); - }, - ), - ); - - // 加载本地 assets 中的 HTML - // await _controller.loadFlutterAsset('assets/map/test_baidu_map.html'); - await _controller.loadRequest(Uri.parse('http://47.92.102.56:7811/file/fluteightmap/index.html')); - - setState(() { - _isLoading = false; - }); - } catch (e, st) { - debugPrint('获取位置或初始化失败: $e\n$st'); - if (!mounted) return; - setState(() { - _errorMessage = '获取位置失败: ${e.toString()}'; - _isLoading = false; - }); + } catch (e) { + debugPrint('解析 gson 失败: $e'); + _gsonList = []; } + if (!mounted) return; + + setState(() { + _longitude = loc.longitudeAsDouble; + _latitude = loc.latitudeAsDouble; + }); + // 初始化 WebViewController 并加载本地页面 + _controller = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + // 注册 JS 通道 'JS' —— 对应 HTML 中的 window.JS.postMessage(...) + ..addJavaScriptChannel('JS', onMessageReceived: (dynamic message) { + // message 是动态对象,不在签名中引用具体类型以避免 "Undefined class" 问题 + String payload; + try { + payload = message.message ?? message.toString(); + } catch (e) { + payload = message.toString(); + } + _onJsMessage(payload); + }) + // 也保留一个备用通道 'Flutter' + ..addJavaScriptChannel('Flutter', onMessageReceived: (dynamic message) { + String payload; + try { + payload = message.message ?? message.toString(); + } catch (e) { + payload = message.toString(); + } + _onJsMessage(payload); + }) + ..setNavigationDelegate( + NavigationDelegate( + onPageFinished: (String url) async { + debugPrint('网页加载完成: $url'); + await _injectLocationParams(); + }, + onWebResourceError: (err) { + debugPrint('Web resource error: ${err.description}'); + }, + ), + ); + + // 加载本地 assets 中的 HTML + // await _controller.loadFlutterAsset('assets/map/index.html'); + await _controller.loadRequest(Uri.parse('http://47.92.102.56:7811/file/fluteightmap/index.html')); + + setState(() { + _isLoading = false; + }); } /// 注入参数并调用页面初始化函数 window.initWithData(...) diff --git a/lib/customWidget/custom_button.dart b/lib/customWidget/custom_button.dart index 39d5b41..1034012 100644 --- a/lib/customWidget/custom_button.dart +++ b/lib/customWidget/custom_button.dart @@ -55,7 +55,7 @@ class CustomButton extends StatelessWidget { } else { finalTextStyle = TextStyle( color: isEnabled ? Colors.white : (disabledTextColor ?? Colors.white70), - fontSize: 15, + fontSize: 14, fontWeight: FontWeight.bold, ); } @@ -69,7 +69,7 @@ class CustomButton extends StatelessWidget { onTap: isEnabled ? onPressed : null, child: Container( height: height ?? 45, // 默认高度45 - padding: padding ?? const EdgeInsets.all(8), // 默认内边距 + padding: padding ?? const EdgeInsets.all(6), // 默认内边距 margin: margin ?? const EdgeInsets.symmetric(horizontal: 5), // 默认外边距 decoration: BoxDecoration( borderRadius: BorderRadius.circular(borderRadius), diff --git a/lib/customWidget/photo_picker_row.dart b/lib/customWidget/photo_picker_row.dart index 0099314..e67b603 100644 --- a/lib/customWidget/photo_picker_row.dart +++ b/lib/customWidget/photo_picker_row.dart @@ -4,6 +4,9 @@ import 'package:flutter/services.dart'; import 'package:image_picker/image_picker.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; +import 'package:qhd_prevention/customWidget/single_image_viewer.dart'; +import 'package:qhd_prevention/tools/tools.dart'; import 'package:video_compress/video_compress.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.dart'; import 'package:photo_manager/photo_manager.dart'; @@ -563,7 +566,17 @@ class _RepairedPhotoSectionState extends State { }, onMediaAdded: widget.onMediaAdded, onMediaRemoved: widget.onMediaRemoved, - onMediaTapped: widget.onMediaTapped, + onMediaTapped: (filePath) { + if (widget.mediaType == MediaType.image) { + presentOpaque(SingleImageViewer(imageUrl: filePath), context); + }else{ + showDialog( + context: context, + barrierColor: Colors.black54, + builder: (_) => VideoPlayerPopup(videoUrl:filePath), + ); + } + }, // 传递点击回调 isEdit: widget.isEdit, // 传递编辑状态 ), diff --git a/lib/customWidget/picker/CupertinoDatePicker.dart b/lib/customWidget/picker/CupertinoDatePicker.dart index 811a504..a43fc6d 100644 --- a/lib/customWidget/picker/CupertinoDatePicker.dart +++ b/lib/customWidget/picker/CupertinoDatePicker.dart @@ -12,16 +12,20 @@ import 'package:flutter/material.dart'; /// if (picked != null) { /// print('用户选择的时间:$picked'); /// } -enum BottomPickerMode { dateTime, date, dateTimeWithSeconds } +enum BottomPickerMode { + dateTime, // 底部弹窗 年月日时分 + date, // 中间弹窗日历 + dateTimeWithSeconds, // 底部弹窗 年月日时分秒 +} class BottomDateTimePicker { static Future showDate( - BuildContext context, { - bool allowFuture = true, - bool allowPast = true, // 是否允许选择过去(默认允许) - String? minTimeStr, // 可选:'yyyy-MM-dd HH:mm:ss' - BottomPickerMode mode = BottomPickerMode.dateTime, - }) { + BuildContext context, { + bool allowFuture = true, + bool allowPast = true, // 是否允许选择过去(默认允许) + String? minTimeStr, // 可选:'yyyy-MM-dd HH:mm:ss' + BottomPickerMode mode = BottomPickerMode.dateTime, + }) { return showModalBottomSheet( context: context, backgroundColor: Colors.white, @@ -29,12 +33,13 @@ class BottomDateTimePicker { shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(12)), ), - builder: (_) => _InlineDateTimePickerContent( - allowFuture: allowFuture, - allowPast: allowPast, - minTimeStr: minTimeStr, - mode: mode, - ), + builder: + (_) => _InlineDateTimePickerContent( + allowFuture: allowFuture, + allowPast: allowPast, + minTimeStr: minTimeStr, + mode: mode, + ), ); } } @@ -118,8 +123,13 @@ class _InlineDateTimePickerContentState if (widget.mode == BottomPickerMode.date) { initial = DateTime(initial.year, initial.month, initial.day); } else if (widget.mode == BottomPickerMode.dateTime) { - initial = DateTime(initial.year, initial.month, initial.day, - initial.hour, initial.minute); + initial = DateTime( + initial.year, + initial.month, + initial.day, + initial.hour, + initial.minute, + ); } // dateTimeWithSeconds 模式保持完整的时间 @@ -135,17 +145,24 @@ class _InlineDateTimePickerContentState // controllers 初始项索引需在范围内 yearCtrl = FixedExtentScrollController( - initialItem: years.indexOf(selectedYear).clamp(0, years.length - 1)); + initialItem: years.indexOf(selectedYear).clamp(0, years.length - 1), + ); monthCtrl = FixedExtentScrollController( - initialItem: (selectedMonth - 1).clamp(0, months.length - 1)); + initialItem: (selectedMonth - 1).clamp(0, months.length - 1), + ); dayCtrl = FixedExtentScrollController( - initialItem: (selectedDay - 1).clamp(0, days.length - 1)); + initialItem: (selectedDay - 1).clamp(0, days.length - 1), + ); hourCtrl = FixedExtentScrollController( - initialItem: selectedHour.clamp(0, hours.length - 1)); + initialItem: selectedHour.clamp(0, hours.length - 1), + ); minuteCtrl = FixedExtentScrollController( - initialItem: selectedMinute.clamp(0, minutes.length - 1)); - secondCtrl = FixedExtentScrollController( // 初始化秒控制器 - initialItem: selectedSecond.clamp(0, seconds.length - 1)); + initialItem: selectedMinute.clamp(0, minutes.length - 1), + ); + secondCtrl = FixedExtentScrollController( + // 初始化秒控制器 + initialItem: selectedSecond.clamp(0, seconds.length - 1), + ); // 确保初始选择满足约束(例如 minTime 或禁止未来/禁止过去) WidgetsBinding.instance.addPostFrameCallback((_) { @@ -165,11 +182,11 @@ class _InlineDateTimePickerContentState try { final trimmed = s.trim(); final parts = trimmed.split(' '); - final dateParts = - parts[0].split('-').map((e) => int.parse(e)).toList(); - final timeParts = (parts.length > 1) - ? parts[1].split(':').map((e) => int.parse(e)).toList() - : [0, 0, 0]; + final dateParts = parts[0].split('-').map((e) => int.parse(e)).toList(); + final timeParts = + (parts.length > 1) + ? parts[1].split(':').map((e) => int.parse(e)).toList() + : [0, 0, 0]; final year = dateParts[0]; final month = dateParts[1]; final day = dateParts[2]; @@ -208,10 +225,21 @@ class _InlineDateTimePickerContentState picked = DateTime(selectedYear, selectedMonth, selectedDay); } else if (isDateTimeOnly) { picked = DateTime( - selectedYear, selectedMonth, selectedDay, selectedHour, selectedMinute); + selectedYear, + selectedMonth, + selectedDay, + selectedHour, + selectedMinute, + ); } else { - picked = DateTime(selectedYear, selectedMonth, selectedDay, - selectedHour, selectedMinute, selectedSecond); + picked = DateTime( + selectedYear, + selectedMonth, + selectedDay, + selectedHour, + selectedMinute, + selectedSecond, + ); } // 处理最小时间约束:结合 _minTime 与 allowPast @@ -232,8 +260,13 @@ class _InlineDateTimePickerContentState if (isDateOnly) { minRef = DateTime(minRef!.year, minRef.month, minRef.day); } else if (isDateTimeOnly) { - minRef = DateTime(minRef!.year, minRef.month, minRef.day, - minRef.hour, minRef.minute); + minRef = DateTime( + minRef!.year, + minRef.month, + minRef.day, + minRef.hour, + minRef.minute, + ); } } } else if (_minTime != null) { @@ -243,8 +276,13 @@ class _InlineDateTimePickerContentState if (isDateOnly) { minRef = DateTime(minRef!.year, minRef.month, minRef.day); } else if (isDateTimeOnly) { - minRef = DateTime(minRef!.year, minRef.month, minRef.day, - minRef.hour, minRef.minute); + minRef = DateTime( + minRef!.year, + minRef.month, + minRef.day, + minRef.hour, + minRef.minute, + ); } } @@ -363,7 +401,11 @@ class _InlineDateTimePickerContentState onPressed: () { DateTime result; if (isDateOnly) { - result = DateTime(selectedYear, selectedMonth, selectedDay); + result = DateTime( + selectedYear, + selectedMonth, + selectedDay, + ); } else if (isDateTimeOnly) { result = DateTime( selectedYear, @@ -411,7 +453,8 @@ class _InlineDateTimePickerContentState // 月 _buildPicker( controller: monthCtrl, - items: months.map((e) => e.toString().padLeft(2, '0')).toList(), + items: + months.map((e) => e.toString().padLeft(2, '0')).toList(), onSelected: (idx) { setState(() { selectedMonth = months[idx]; @@ -438,7 +481,8 @@ class _InlineDateTimePickerContentState if (!isDateOnly) _buildPicker( controller: hourCtrl, - items: hours.map((e) => e.toString().padLeft(2, '0')).toList(), + items: + hours.map((e) => e.toString().padLeft(2, '0')).toList(), onSelected: (idx) { setState(() { selectedHour = hours[idx]; @@ -450,7 +494,10 @@ class _InlineDateTimePickerContentState if (!isDateOnly) _buildPicker( controller: minuteCtrl, - items: minutes.map((e) => e.toString().padLeft(2, '0')).toList(), + items: + minutes + .map((e) => e.toString().padLeft(2, '0')) + .toList(), onSelected: (idx) { setState(() { selectedMinute = minutes[idx]; @@ -463,7 +510,10 @@ class _InlineDateTimePickerContentState if (widget.mode == BottomPickerMode.dateTimeWithSeconds) _buildPicker( controller: secondCtrl, - items: seconds.map((e) => e.toString().padLeft(2, '0')).toList(), + items: + seconds + .map((e) => e.toString().padLeft(2, '0')) + .toList(), onSelected: (idx) { setState(() { selectedSecond = seconds[idx]; @@ -496,4 +546,4 @@ class _InlineDateTimePickerContentState ), ); } -} \ No newline at end of file +} diff --git a/lib/customWidget/toast_util.dart b/lib/customWidget/toast_util.dart index 3488d00..d42e5f2 100644 --- a/lib/customWidget/toast_util.dart +++ b/lib/customWidget/toast_util.dart @@ -2,11 +2,13 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; class ToastUtil { - /// 普通灰色背景提示(仅文字) - static void showNormal(BuildContext context, String message, { - ToastGravity gravity = ToastGravity.BOTTOM, - int duration = 2, - }) { + /// 普通提示(仅文字,屏幕中间) + static void showNormal( + BuildContext context, + String message, { + ToastGravity gravity = ToastGravity.CENTER, // 修改为 CENTER + int duration = 2, + }) { _showToast( context: context, message: message, @@ -15,11 +17,13 @@ class ToastUtil { ); } - /// 成功提示(带图标) - static void showSuccess(BuildContext context, String message, { - ToastGravity gravity = ToastGravity.CENTER, - int duration = 3, - }) { + /// 成功提示(带图标,屏幕中间) + static void showSuccess( + BuildContext context, + String message, { + ToastGravity gravity = ToastGravity.CENTER, // 修改为 CENTER + int duration = 3, + }) { _showToast( context: context, message: message, @@ -29,11 +33,13 @@ class ToastUtil { ); } - /// 失败提示(带图标) - static void showError(BuildContext context, String message, { - ToastGravity gravity = ToastGravity.CENTER, - int duration = 4, - }) { + /// 失败提示(带图标,屏幕中间) + static void showError( + BuildContext context, + String message, { + ToastGravity gravity = ToastGravity.CENTER, // 修改为 CENTER + int duration = 4, + }) { _showToast( context: context, message: message, @@ -67,7 +73,7 @@ class ToastUtil { Fluttertoast.showToast( msg: message, toastLength: duration > 2 ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT, - gravity: gravity, + gravity: gravity, // 始终 CENTER backgroundColor: Colors.grey[500], textColor: Colors.white, fontSize: 16.0, @@ -104,4 +110,4 @@ class ToastUtil { ), ); } -} \ No newline at end of file +} diff --git a/lib/http/ApiService.dart b/lib/http/ApiService.dart index 90bc7c7..b32ab9a 100644 --- a/lib/http/ApiService.dart +++ b/lib/http/ApiService.dart @@ -19,11 +19,13 @@ class ApiService { // static const String projectManagerUrl = 'https://pm.qhdsafety.com/zy-projectManage/'; // 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"; - + "http://192.168.20.240:8500/whb_stu_face/"; /// 登录及其他管理后台接口 - 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.0.37:8099/api"; /// 图片文件服务 @@ -38,24 +40,6 @@ class ApiService { 'https://pm.qhdsafety.com/zy-projectManage'; - // /// 人脸识别服务 - // static const String baseFacePath = - // "https://qaaqwh.qhdsafety.com/whb_stu_face/"; - // - // /// 登录及其他管理后台接口 - // static const String basePath = "http://192.168.20.240:8500/integrated_whb/"; - // - // /// 图片文件服务 - // static const String baseImgPath = "https://file.zcloudchina.com/YTHFile"; - // - // /// 管理后台统一路径 - // static const String adminPath = - // "https://qaaqwh.qhdsafety.com/integrated_whb/"; - // - // /// 项目管理系统 - // static const String projectManagerUrl = - // 'https://pm.qhdsafety.com/zy-projectManage'; - /// RSA 公钥 static const publicKey = ''' -----BEGIN PUBLIC KEY----- diff --git a/lib/pages/KeyProjects/Danger/danger_manager_detail_page.dart b/lib/pages/KeyProjects/Danger/danger_manager_detail_page.dart index 0545a56..9486adb 100644 --- a/lib/pages/KeyProjects/Danger/danger_manager_detail_page.dart +++ b/lib/pages/KeyProjects/Danger/danger_manager_detail_page.dart @@ -368,12 +368,7 @@ class _DangerManagerDetailPageState extends State { '${ApiService.baseImgPath}$path', ) .toList(), - onMediaTapped: (p) { - presentOpaque( - SingleImageViewer(imageUrl: p), - context, - ); - }, + onChanged: (files) => setState(() { hiddenForm['ysImgs'] = diff --git a/lib/pages/KeyProjects/Punishment/punishment_manager_detail_page.dart b/lib/pages/KeyProjects/Punishment/punishment_manager_detail_page.dart index 448fc8e..77c0c89 100644 --- a/lib/pages/KeyProjects/Punishment/punishment_manager_detail_page.dart +++ b/lib/pages/KeyProjects/Punishment/punishment_manager_detail_page.dart @@ -354,9 +354,6 @@ class _PunishmentManagerDetailPageState extends State '${ApiService.baseImgPath}$path').toList(), - onMediaTapped: (p) { - presentOpaque(SingleImageViewer(imageUrl: p), context); - }, onChanged: (files) => setState(() { hiddenForm['ysImgs'] = diff --git a/lib/pages/KeyProjects/SafeCheck/custom/safe_drawer_page.dart b/lib/pages/KeyProjects/SafeCheck/custom/safe_drawer_page.dart index b0b4f8a..149f2f3 100644 --- a/lib/pages/KeyProjects/SafeCheck/custom/safe_drawer_page.dart +++ b/lib/pages/KeyProjects/SafeCheck/custom/safe_drawer_page.dart @@ -190,9 +190,6 @@ class _SafeDrawerPageState extends State { isEdit: _isEdit, isRequired: _isEdit, initialMediaPaths: _getSelectedImages(), - onMediaTapped: (p) { - presentOpaque(SingleImageViewer(imageUrl: p), context); - }, onChanged: (files) => setState(() { hiddenForm['hiddenImgs'] = @@ -222,13 +219,6 @@ class _SafeDrawerPageState extends State { RepairedPhotoSection( title: '隐患视频', maxCount: 1, - onMediaTapped: (p) { - showDialog( - context: context, - barrierColor: Colors.black54, - builder: (_) => VideoPlayerPopup(videoUrl:p), - ); - }, isEdit: _isEdit, mediaType: MediaType.video, initialMediaPaths: _getSelectedVideos(), @@ -680,24 +670,4 @@ class _SafeDrawerPageState extends State { } } - Future _uploadFile(String path, String type, String id) async { - try { - final r = await ApiService.addImgFiles(path, type, id); - return r['result'] == 'success' ? (r['imgPath'] ?? '') : ''; - } catch (_) { - return ''; - } - } - - Future _determinePosition() async { - if (!await Geolocator.isLocationServiceEnabled()) throw 'location disabled'; - var p = await Geolocator.checkPermission(); - if (p == LocationPermission.denied) - p = await Geolocator.requestPermission(); - if (p == LocationPermission.denied || p == LocationPermission.deniedForever) - throw 'permission denied'; - return await Geolocator.getCurrentPosition( - desiredAccuracy: LocationAccuracy.high, - ); - } } diff --git a/lib/pages/app/Danger_paicha/check_information_one_item.dart b/lib/pages/app/Danger_paicha/check_information_one_item.dart index 252b03f..0598c97 100644 --- a/lib/pages/app/Danger_paicha/check_information_one_item.dart +++ b/lib/pages/app/Danger_paicha/check_information_one_item.dart @@ -13,10 +13,13 @@ import 'package:qhd_prevention/customWidget/department_person_picker.dart'; import 'package:qhd_prevention/customWidget/department_picker.dart'; import 'package:qhd_prevention/customWidget/department_picker_hidden_type.dart'; import 'package:qhd_prevention/customWidget/department_picker_two.dart'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/tools/coord_convert.dart'; import 'package:qhd_prevention/tools/tools.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import '../../../customWidget/photo_picker_row.dart'; import '../../../http/ApiService.dart'; @@ -680,12 +683,11 @@ class _CheckInformationOneItemState extends State { } - //获取定位 - Position position = await _determinePosition(); - String longitude=position.longitude.toString(); - String latitude=position.latitude.toString(); - + await fetchAndSaveBd09(context); + final prefs = await SharedPreferences.getInstance(); + String latitude = prefs.getString('bd_lat') ?? ''; + String longitude = prefs.getString('bd_lon') ?? ''; try { // final result = await ApiService.temporaryStorageOfHidden( // unqualifiedInspectionItemID.isNotEmpty?"edit":"add",widget.item,unqualifiedInspectionItemID, @@ -828,33 +830,6 @@ class _CheckInformationOneItemState extends State { } } - Future _determinePosition() async { - bool serviceEnabled; - LocationPermission permission; - - // 检查定位服务是否启用 - serviceEnabled = await Geolocator.isLocationServiceEnabled(); - if (!serviceEnabled) { - return Future.error('Location services are disabled.'); - } - - // 获取权限 - permission = await Geolocator.checkPermission(); - if (permission == LocationPermission.denied) { - permission = await Geolocator.requestPermission(); - if (permission == LocationPermission.denied) { - return Future.error('Location permissions are denied'); - } - } - - if (permission == LocationPermission.deniedForever) { - return Future.error( - 'Location permissions are permanently denied, we cannot request permissions.'); - } - - // 获取当前位置 - return await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); - } String truncateText(String text, {int maxLength = 17}) { if (text.length <= maxLength) return text; diff --git a/lib/pages/app/Danger_paicha/hazard_registration_page.dart b/lib/pages/app/Danger_paicha/hazard_registration_page.dart index eea82b2..deb2fd9 100644 --- a/lib/pages/app/Danger_paicha/hazard_registration_page.dart +++ b/lib/pages/app/Danger_paicha/hazard_registration_page.dart @@ -18,7 +18,9 @@ import 'package:qhd_prevention/customWidget/single_image_viewer.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/tools/coord_convert.dart'; import 'package:qhd_prevention/tools/tools.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import '../../../customWidget/photo_picker_row.dart'; import '../../../http/ApiService.dart'; @@ -256,9 +258,6 @@ class _HazardRegistrationPageState extends State { } }, onChanged: (List files) {}, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onAiIdentify: () { // AI 识别逻辑 if(_yinHuanImages.isEmpty){ @@ -285,13 +284,6 @@ class _HazardRegistrationPageState extends State { onMediaRemoved: (value){ _yinHuanVido.remove(value); }, - onMediaTapped: (path) { - showDialog( - context: context, - barrierColor: Colors.black54, - builder: (_) => VideoPlayerPopup(videoUrl:path), - ); - }, onChanged: (List files) { }, onAiIdentify: () {}, @@ -665,12 +657,11 @@ class _HazardRegistrationPageState extends State { hiddenType1=_yinHuanTypeIds[2]; } - - //获取定位 - Position position = await _determinePosition(); - String longitude=position.longitude.toString(); - String latitude=position.latitude.toString(); + await fetchAndSaveBd09(context); + final prefs = await SharedPreferences.getInstance(); + String latitude = prefs.getString('bd_lat') ?? ''; + String longitude = prefs.getString('bd_lon') ?? ''; try { @@ -720,6 +711,9 @@ class _HazardRegistrationPageState extends State { widget.onClose(hiddenId, _standardController.text.trim()); }); } + }else{ + + ToastUtil.showNormal(context, "提交失败"); } } catch (e) { LoadingDialogHelper.hide(); @@ -804,33 +798,6 @@ class _HazardRegistrationPageState extends State { } } - Future _determinePosition() async { - bool serviceEnabled; - LocationPermission permission; - - // 检查定位服务是否启用 - serviceEnabled = await Geolocator.isLocationServiceEnabled(); - if (!serviceEnabled) { - return Future.error('Location services are disabled.'); - } - - // 获取权限 - permission = await Geolocator.checkPermission(); - if (permission == LocationPermission.denied) { - permission = await Geolocator.requestPermission(); - if (permission == LocationPermission.denied) { - return Future.error('Location permissions are denied'); - } - } - - if (permission == LocationPermission.deniedForever) { - return Future.error( - 'Location permissions are permanently denied, we cannot request permissions.'); - } - - // 获取当前位置 - return await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); - } String truncateText(String text, {int maxLength = 17}) { if (text.length <= maxLength) return text; diff --git a/lib/pages/app/Danger_paicha/quick_report_page.dart b/lib/pages/app/Danger_paicha/quick_report_page.dart index 4c57a8a..ed1e6af 100644 --- a/lib/pages/app/Danger_paicha/quick_report_page.dart +++ b/lib/pages/app/Danger_paicha/quick_report_page.dart @@ -12,9 +12,13 @@ import 'package:qhd_prevention/customWidget/department_person_picker.dart'; import 'package:qhd_prevention/customWidget/department_picker.dart'; import 'package:qhd_prevention/customWidget/department_picker_hidden_type.dart'; import 'package:qhd_prevention/customWidget/department_picker_two.dart'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; +import 'package:qhd_prevention/customWidget/single_image_viewer.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/tools/coord_convert.dart'; import 'package:qhd_prevention/tools/tools.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import '../../../customWidget/photo_picker_row.dart'; import '../../../http/ApiService.dart'; @@ -518,12 +522,11 @@ class _QuickReportPageState extends State { hiddenType1=_yinHuanTypeIds[2]; } - - //获取定位 - Position position = await _determinePosition(); - String longitude=position.longitude.toString(); - String latitude=position.latitude.toString(); + await fetchAndSaveBd09(context); + final prefs = await SharedPreferences.getInstance(); + String latitude = prefs.getString('bd_lat') ?? ''; + String longitude = prefs.getString('bd_lon') ?? ''; try { Map data = {}; @@ -536,7 +539,6 @@ class _QuickReportPageState extends State { String hiddenId = result['pd']['HIDDEN_ID'] ; - for (int i=0;i<_yinHuanImages.length;i++){ _addImgFiles(_yinHuanImages[i],"3",hiddenId); } @@ -630,33 +632,5 @@ class _QuickReportPageState extends State { } } - Future _determinePosition() async { - bool serviceEnabled; - LocationPermission permission; - - // 检查定位服务是否启用 - serviceEnabled = await Geolocator.isLocationServiceEnabled(); - if (!serviceEnabled) { - return Future.error('Location services are disabled.'); - } - - // 获取权限 - permission = await Geolocator.checkPermission(); - if (permission == LocationPermission.denied) { - permission = await Geolocator.requestPermission(); - if (permission == LocationPermission.denied) { - return Future.error('Location permissions are denied'); - } - } - - if (permission == LocationPermission.deniedForever) { - return Future.error( - 'Location permissions are permanently denied, we cannot request permissions.'); - } - - // 获取当前位置 - return await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); - } - } diff --git a/lib/pages/home/NFC/nfc_check_danger_detail.dart b/lib/pages/home/NFC/nfc_check_danger_detail.dart index 829946a..69c861a 100644 --- a/lib/pages/home/NFC/nfc_check_danger_detail.dart +++ b/lib/pages/home/NFC/nfc_check_danger_detail.dart @@ -285,9 +285,6 @@ class _NfcCheckDangerDetailState extends State { }); } }, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onChanged: (v) {}, onAiIdentify: () { // AI 识别逻辑 @@ -324,12 +321,6 @@ class _NfcCheckDangerDetailState extends State { }); } }, - onMediaTapped: (path) { - showDialog( - context: context, - barrierColor: Colors.black54, - builder: (_) => VideoPlayerPopup(videoUrl: path), - ); }, onMediaAdded: (localPath) { _videos.add(nfcImgData(path: localPath, id: '')); }, @@ -427,9 +418,6 @@ class _NfcCheckDangerDetailState extends State { initialMediaPaths: zgImgList.map((item) => item.path).toList(), mediaType: MediaType.image, isShowAI: false, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaAdded: (localPath) { zgImgList.add(nfcImgData(path: localPath, id: '')); }, @@ -646,34 +634,4 @@ class _NfcCheckDangerDetailState extends State { } } - Future _determinePosition() async { - bool serviceEnabled; - LocationPermission permission; - - // 检查定位服务是否启用 - serviceEnabled = await Geolocator.isLocationServiceEnabled(); - if (!serviceEnabled) { - return Future.error('Location services are disabled.'); - } - - // 获取权限 - permission = await Geolocator.checkPermission(); - if (permission == LocationPermission.denied) { - permission = await Geolocator.requestPermission(); - if (permission == LocationPermission.denied) { - return Future.error('Location permissions are denied'); - } - } - - if (permission == LocationPermission.deniedForever) { - return Future.error( - 'Location permissions are permanently denied, we cannot request permissions.', - ); - } - - // 获取当前位置 - return await Geolocator.getCurrentPosition( - desiredAccuracy: LocationAccuracy.high, - ); - } } diff --git a/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_detail_page.dart b/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_detail_page.dart index 5aa24a4..95ef6bc 100644 --- a/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_detail_page.dart +++ b/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_detail_page.dart @@ -241,18 +241,12 @@ class _SafecheckAssignmentDetailPageState RepairedPhotoSection( title: '隐患视频', maxCount: 1, - onMediaTapped: (p) { - showDialog( - context: context, - barrierColor: Colors.black54, - builder: (_) => VideoPlayerPopup(videoUrl: p), - ); - }, isEdit: false, mediaType: MediaType.video, initialMediaPaths: hiddenVideo, onChanged: (files) {}, onAiIdentify: () {}, + ), ), ], diff --git a/lib/pages/home/SafeCheck/Record/defend_record_detail_page.dart b/lib/pages/home/SafeCheck/Record/defend_record_detail_page.dart index 5975932..b669922 100644 --- a/lib/pages/home/SafeCheck/Record/defend_record_detail_page.dart +++ b/lib/pages/home/SafeCheck/Record/defend_record_detail_page.dart @@ -125,14 +125,12 @@ class _DefendRecordDetailPageState extends State { return Scaffold( appBar: MyAppbar(title: '申辩记录'), body: SafeArea( - child: Expanded( - child: ListView.builder( - itemCount: _list.length, - itemBuilder: (context, index) { - final item = _list[index]; - return _itemWidget(item); - }, - ), + child: ListView.builder( + itemCount: _list.length, + itemBuilder: (context, index) { + final item = _list[index]; + return _itemWidget(item); + }, ), ), ); diff --git a/lib/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart b/lib/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart index adbfecf..d2cd89d 100644 --- a/lib/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart +++ b/lib/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart @@ -220,12 +220,6 @@ class _SafeCheckDrawerPageState extends State { isEdit: _isEdit, isRequired: _isEdit, initialMediaPaths: _getSelectedImages(), - onMediaTapped: (p) { - presentOpaque( - SingleImageViewer(imageUrl: p), - context, - ); - }, onChanged: (files) => setState(() { hiddenForm['hiddenImgs'] = @@ -255,13 +249,6 @@ class _SafeCheckDrawerPageState extends State { RepairedPhotoSection( title: '隐患视频', maxCount: 1, - onMediaTapped: (p) { - showDialog( - context: context, - barrierColor: Colors.black54, - builder: (_) => VideoPlayerPopup(videoUrl: p), - ); - }, isEdit: _isEdit, mediaType: MediaType.video, initialMediaPaths: _getSelectedVideos(), diff --git a/lib/pages/home/SafetyCommitment/team_safety_commitment_apply.dart b/lib/pages/home/SafetyCommitment/team_safety_commitment_apply.dart index d46eb7b..3f95f0f 100644 --- a/lib/pages/home/SafetyCommitment/team_safety_commitment_apply.dart +++ b/lib/pages/home/SafetyCommitment/team_safety_commitment_apply.dart @@ -133,6 +133,9 @@ class _TeamSafetyCommitmentApplyState extends State { isEditable: true, controller: _controller5, text: '', + onChanged: (v) { + + } ), const Divider(), diff --git a/lib/pages/home/home_page.dart b/lib/pages/home/home_page.dart index b96d117..6ab5033 100644 --- a/lib/pages/home/home_page.dart +++ b/lib/pages/home/home_page.dart @@ -8,6 +8,8 @@ import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/home/scan_page.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/services/auth_service.dart'; +import 'package:qhd_prevention/services/location_service.dart'; +import 'package:qhd_prevention/tools/coord_convert.dart'; import 'package:qhd_prevention/tools/update/update_dialogs.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; @@ -185,10 +187,12 @@ class HomePageState extends State { // 使用初始化加载:先恢复缓存(若存在则直接显示),然后再发起网络请求(成功则覆盖缓存) _initialLoad(); BadgeManager().initAllModules(); + } /// 首次加载:先恢复缓存(如果有),然后在后台去刷新(只有当无缓存时才显示 loading) Future _initialLoad() async { + /// 清单列表 final data = await ApiService.getListData(); if (data['result'] == 'success') { @@ -239,6 +243,8 @@ class HomePageState extends State { // 拉取其他数据 + 隐患列表(当 hiddenList 为空时显示 loading,否则不显示) await _fetchData(); await _fetchHiddenList(showLoading: hiddenList.isEmpty); + await fetchAndSaveBd09(context); + } Future _onRefresh() async { diff --git a/lib/pages/home/risk/risk_detail_page.dart b/lib/pages/home/risk/risk_detail_page.dart index 3a43dd3..4a1160b 100644 --- a/lib/pages/home/risk/risk_detail_page.dart +++ b/lib/pages/home/risk/risk_detail_page.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/tools/coord_convert.dart'; import 'package:qhd_prevention/tools/tools.dart'; import 'package:geolocator/geolocator.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import '../../../http/ApiService.dart'; import '../../../tools/h_colors.dart'; @@ -64,9 +66,13 @@ class _RiskDetailPageState extends State { Future _addCoordinate() async { try { - Position position = await _determinePosition(); + //获取定位 + await fetchAndSaveBd09(context); + final prefs = await SharedPreferences.getInstance(); + String latitude = prefs.getString('bd_lat') ?? ''; + String longitude = prefs.getString('bd_lon') ?? ''; final result = await ApiService.addCoordinate( widget.itemData["IDENTIFICATIONPARTS_ID"], - position.longitude.toString(),position.latitude.toString()); + longitude,latitude); if (result['result'] == 'success') { setState(() { _showMessage('提交成功'); @@ -391,34 +397,6 @@ class _RiskDetailPageState extends State { ); } - Future _determinePosition() async { - bool serviceEnabled; - LocationPermission permission; - - // 检查定位服务是否启用 - serviceEnabled = await Geolocator.isLocationServiceEnabled(); - if (!serviceEnabled) { - return Future.error('Location services are disabled.'); - } - - // 获取权限 - permission = await Geolocator.checkPermission(); - if (permission == LocationPermission.denied) { - permission = await Geolocator.requestPermission(); - if (permission == LocationPermission.denied) { - return Future.error('Location permissions are denied'); - } - } - - if (permission == LocationPermission.deniedForever) { - return Future.error( - 'Location permissions are permanently denied, we cannot request permissions.'); - } - - // 获取当前位置 - return await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); - } - void _showMessage(String msg) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); } diff --git a/lib/pages/home/study/study_my_task_page.dart b/lib/pages/home/study/study_my_task_page.dart index 43d1666..8a0ff18 100644 --- a/lib/pages/home/study/study_my_task_page.dart +++ b/lib/pages/home/study/study_my_task_page.dart @@ -288,7 +288,7 @@ class _StudyMyTaskPageState extends State with RouteAware { ], ), Wrap( - spacing: 10, + spacing: 5, children: [ // 加强学习 if (studyState >= 2 && @@ -317,7 +317,8 @@ class _StudyMyTaskPageState extends State with RouteAware { CustomButton( height: 36, text: "立即学习", - padding: EdgeInsets.symmetric(horizontal: 18), + margin: const EdgeInsets.symmetric(horizontal: 2), + padding: EdgeInsets.symmetric(horizontal: 15), borderRadius: 18, backgroundColor: Colors.blue, onPressed: () { @@ -338,7 +339,9 @@ class _StudyMyTaskPageState extends State with RouteAware { CustomButton( height: 36, text: "立即考试", - padding: EdgeInsets.symmetric(horizontal: 18), + margin: const EdgeInsets.symmetric(horizontal: 2), + + padding: EdgeInsets.symmetric(horizontal: 15), borderRadius: 18, backgroundColor: Colors.green, onPressed: @@ -349,7 +352,9 @@ class _StudyMyTaskPageState extends State with RouteAware { CustomButton( height: 36, text: "考试详情", - padding: EdgeInsets.symmetric(horizontal: 18), + margin: const EdgeInsets.symmetric(horizontal: 2), + + padding: EdgeInsets.symmetric(horizontal: 15), borderRadius: 18, backgroundColor: Colors.green, onPressed: () { diff --git a/lib/pages/home/study/study_score_page.dart b/lib/pages/home/study/study_score_page.dart index 61264c5..adf37cc 100644 --- a/lib/pages/home/study/study_score_page.dart +++ b/lib/pages/home/study/study_score_page.dart @@ -62,7 +62,8 @@ class _StudyScorePageState extends State { int _toInt(dynamic value, {required int defaultValue}) { if (value is int) return value; if (value is String) { - return int.tryParse(value) ?? defaultValue; + int score = int.parse(value); + return score; } return defaultValue; } @@ -115,8 +116,7 @@ class _StudyScorePageState extends State { } // 解析成绩 - int score = _toInt(item['STAGEEXAMSCORE'], defaultValue: -1); - String scoreText = score >= 0 ? '$score' : '无'; + String scoreText = item['STAGEEXAMSCORE'] == '-1' ? '无' : item['STAGEEXAMSCORE']; return Card( color: Colors.white, diff --git a/lib/pages/home/study/take_exam_page.dart b/lib/pages/home/study/take_exam_page.dart index 14711d1..7abcb09 100644 --- a/lib/pages/home/study/take_exam_page.dart +++ b/lib/pages/home/study/take_exam_page.dart @@ -113,9 +113,10 @@ class _TakeExamPageState extends State { Future _showTip(String content) { return CustomAlertDialog.showAlert( - context, - title: '温馨提示', - confirmText: '确认' + context, + title: '温馨提示', + content: content, + confirmText: '确认' ); } @@ -206,13 +207,14 @@ class _TakeExamPageState extends State { context, title: '温馨提示', content: - passed - ? '您的成绩为 $score 分,恭喜您通过本次考试,请继续保持!' - : '您的成绩为 $score 分,很遗憾您没有通过本次考试,请再接再厉!', + passed + ? '您的成绩为 $score 分,恭喜您通过本次考试,请继续保持!' + : '您的成绩为 $score 分,很遗憾您没有通过本次考试,请再接再厉!', cancelText: '', confirmText: '确定', ); - if (ok) {} + Navigator.of(context).pop(); + } } @@ -236,47 +238,47 @@ class _TakeExamPageState extends State { final keys = q.questionType == '3' ? ['A', 'B'] : ['A', 'B', 'C', 'D']; return Column( children: - keys.map((key) { - final active = q.checked.split(',').contains(key); - return GestureDetector( - onTap: - () => _chooseTopic( - q.questionType == '3' - ? 'judge' - : (q.questionType == '2' ? 'multiple' : 'radio'), - key, + keys.map((key) { + final active = q.checked.split(',').contains(key); + return GestureDetector( + onTap: + () => _chooseTopic( + q.questionType == '3' + ? 'judge' + : (q.questionType == '2' ? 'multiple' : 'radio'), + key, + ), + child: Container( + margin: const EdgeInsets.symmetric(vertical: 8), + child: Row( + children: [ + Container( + width: 40, + height: 40, + alignment: Alignment.center, + decoration: BoxDecoration( + color: active ? Colors.blue : Colors.grey.shade200, + shape: BoxShape.circle, ), - child: Container( - margin: const EdgeInsets.symmetric(vertical: 8), - child: Row( - children: [ - Container( - width: 40, - height: 40, - alignment: Alignment.center, - decoration: BoxDecoration( - color: active ? Colors.blue : Colors.grey.shade200, - shape: BoxShape.circle, - ), - child: Text( - key, - style: TextStyle( - color: active ? Colors.white : Colors.black87, - ), - ), + child: Text( + key, + style: TextStyle( + color: active ? Colors.white : Colors.black87, ), - const SizedBox(width: 16), - Expanded( - child: Text( - q.options[key] ?? '', - style: const TextStyle(fontSize: 16), - ), - ), - ], + ), ), - ), - ); - }).toList(), + const SizedBox(width: 16), + Expanded( + child: Text( + q.options[key] ?? '', + style: const TextStyle(fontSize: 15), + ), + ), + ], + ), + ), + ); + }).toList(), ); } @@ -321,7 +323,7 @@ class _TakeExamPageState extends State { '考试科目:${info['EXAMNAME'] ?? ''}', style: const TextStyle( color: Colors.white, - fontSize: 18, + fontSize: 16, fontWeight: FontWeight.bold, ), ), @@ -330,7 +332,7 @@ class _TakeExamPageState extends State { '当前试题 ${current + 1}/${questions.length}', style: const TextStyle( color: Colors.white, - fontSize: 16, + fontSize: 15, ), ), const SizedBox(height: 8), @@ -338,7 +340,7 @@ class _TakeExamPageState extends State { '考试剩余时间:$_formattedTime', style: const TextStyle( color: Colors.white, - fontSize: 16, + fontSize: 15, ), ), ], @@ -348,18 +350,35 @@ class _TakeExamPageState extends State { ], ), const SizedBox(height: 16), - if (q != null) ...[ - Text( - '${current + 1}. ${q.questionDry} (${questionTypeMap[q.questionType] ?? ''})', - style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 18, + + // ============= 可滚动题目区域(防止题干或选项过长导致溢出) ============= + if (q != null) + // 将题干和选项放入可滚动区域,保证页头和按钮固定 + Expanded( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '${current + 1}. ${q.questionDry} (${questionTypeMap[q.questionType] ?? ''})', + style: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + const SizedBox(height: 16), + _buildOptions(q), + // 底部留白,避免最后一项被按钮遮挡 + const SizedBox(height: 24), + ], + ), ), - ), - const SizedBox(height: 16), - _buildOptions(q), - ], - const Spacer(), + ) + else + // 占位,保证布局一致 + const Expanded(child: SizedBox()), + + const SizedBox(height: 8), Row( children: [ if (current > 0) diff --git a/lib/pages/home/study/video_study_detail_page.dart b/lib/pages/home/study/video_study_detail_page.dart index 2d115cd..9f3e3be 100644 --- a/lib/pages/home/study/video_study_detail_page.dart +++ b/lib/pages/home/study/video_study_detail_page.dart @@ -192,7 +192,7 @@ class _VideoStudyDetailPageState extends State { children: [ Text( '考试科目: ${paperInfo['EXAMNAME']}', - style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold), + style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold), ), Padding(padding: EdgeInsets.symmetric(horizontal: 15), child: Divider(color: Colors.white30, height: 20,),), Text( @@ -210,7 +210,7 @@ class _VideoStudyDetailPageState extends State { if (q != null) ...[ Text( '${current + 1}. ${q.questionDry} (${questionTypeMap[q.questionType]})', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18), + style: TextStyle(fontSize: 16), ), SizedBox(height: 16), _buildOptions(q), diff --git a/lib/pages/home/tap/tabList/special_wrok/dangerous_options_page.dart b/lib/pages/home/tap/tabList/special_wrok/dangerous_options_page.dart index ce3ea47..5140ff4 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dangerous_options_page.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dangerous_options_page.dart @@ -329,9 +329,6 @@ class _DangerousOptionsPageState extends State { .toList(), onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere((e) => e.localPath == path); _onImageRemoved(item); diff --git a/lib/pages/home/tap/tabList/special_wrok/dh_work/aqjd_work_detail/hotwork_aqjd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dh_work/aqjd_work_detail/hotwork_aqjd_detail.dart index b2abbf6..07bcdf7 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dh_work/aqjd_work_detail/hotwork_aqjd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dh_work/aqjd_work_detail/hotwork_aqjd_detail.dart @@ -324,9 +324,6 @@ class _HotworkAqjdDetailState extends State { mediaType: MediaType.image, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart index d514460..ef87dda 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart @@ -265,7 +265,7 @@ class _HotworkApplyDetailState extends State { }); } } - + /// 选择经纬度 Future _showLocationHandle() async{ if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) { @@ -476,10 +476,10 @@ class _HotworkApplyDetailState extends State { {'value': _locationController.text.trim(), 'message': '请填写动火地点及部位'}, {'value': _methodController.text.trim(), 'message': '请填写动火方式'}, {'value': _hotworkPersonController.text.trim(), 'message': '请填写动火人及证书编号'}, - { - 'value': _relatedController.text.trim(), - 'message': '请输入关联的其他特殊作业及安全作业票编号', - }, + // { + // 'value': _relatedController.text.trim(), + // 'message': '请输入关联的其他特殊作业及安全作业票编号', + // }, {'value': _riskController.text.trim(), 'message': '请填写风险辨识结果'}, ]; final level = pd['WORK_LEVEL'] ?? ''; diff --git a/lib/pages/home/tap/tabList/special_wrok/dh_work/ysgd_work_detail/hotwork_ysgd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dh_work/ysgd_work_detail/hotwork_ysgd_detail.dart index 1254f10..47ee6e2 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dh_work/ysgd_work_detail/hotwork_ysgd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dh_work/ysgd_work_detail/hotwork_ysgd_detail.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; import 'package:qhd_prevention/tools/tools.dart'; @@ -199,7 +200,7 @@ class _HotworkYsgdDetailState extends State { title: '作废原因', hintText: '请输入作废原因', cancelText: '取消', - confirmText: '确定' + confirmText: '确定', ); if (reasonText.isEmpty) { ToastUtil.showNormal(context, '请填写作废原因'); @@ -243,7 +244,7 @@ class _HotworkYsgdDetailState extends State { if (result['result'] == 'success') { ToastUtil.showSuccess(context, '保存成功'); Navigator.of(context).pop(true); - }else{ + } else { ToastUtil.showNormal(context, '操作失败:${result['msg'] ?? '未知错误'}'); } } catch (e) { @@ -388,9 +389,6 @@ class _HotworkYsgdDetailState extends State { horizontalPadding: 0, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/dl_work/aqjd_work_detail/cutroad_aqjd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dl_work/aqjd_work_detail/cutroad_aqjd_detail.dart index ff0fbed..274e48e 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dl_work/aqjd_work_detail/cutroad_aqjd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dl_work/aqjd_work_detail/cutroad_aqjd_detail.dart @@ -317,9 +317,6 @@ class _CutroadAqjdDetailState extends State { mediaType: MediaType.image, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/dl_work/dl_work_detai/cutroad_apply_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dl_work/dl_work_detai/cutroad_apply_detail.dart index 637bc60..5a14c24 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dl_work/dl_work_detai/cutroad_apply_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dl_work/dl_work_detai/cutroad_apply_detail.dart @@ -281,10 +281,10 @@ class _CutroadApplyDetailState extends State { {'value': _unitController.text.trim(), 'message': '请输入涉及相关单位(部门)'}, {'value': _contentController.text.trim(), 'message': '请输入断路原因'}, - { - 'value': _relatedController.text.trim(), - 'message': '请输入关联的其他特殊作业及安全作业票编号', - }, + // { + // 'value': _relatedController.text.trim(), + // 'message': '请输入关联的其他特殊作业及安全作业票编号', + // }, {'value': _riskController.text.trim(), 'message': '请填写风险辨识结果'}, ]; /// 各项负责人校验 diff --git a/lib/pages/home/tap/tabList/special_wrok/dl_work/ysgd_work_detail/cutroad_ysgd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dl_work/ysgd_work_detail/cutroad_ysgd_detail.dart index 461d16c..b6b0f63 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dl_work/ysgd_work_detail/cutroad_ysgd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dl_work/ysgd_work_detail/cutroad_ysgd_detail.dart @@ -380,12 +380,6 @@ class _CutroadYsgdDetailState extends State { horizontalPadding: 0, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque( - SingleImageViewer(imageUrl: path), - context, - ); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/dl_work/zyr_work_detail/cutroad_zyr_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dl_work/zyr_work_detail/cutroad_zyr_detail.dart index 166eb6e..00eafda 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dl_work/zyr_work_detail/cutroad_zyr_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dl_work/zyr_work_detail/cutroad_zyr_detail.dart @@ -328,9 +328,6 @@ setState(() { horizontalPadding: 0, isRequired: true, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere((e) => e.localPath == path); _onImageRemoved(item); diff --git a/lib/pages/home/tap/tabList/special_wrok/dt_work/aqjd_work_detail/breakground_aqjd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dt_work/aqjd_work_detail/breakground_aqjd_detail.dart index 4ebd960..460c088 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dt_work/aqjd_work_detail/breakground_aqjd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dt_work/aqjd_work_detail/breakground_aqjd_detail.dart @@ -317,9 +317,6 @@ class _BreakgroundAqjdDetailState extends State { mediaType: MediaType.image, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/dt_work/dt_work_detai/breakground_apply_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dt_work/dt_work_detai/breakground_apply_detail.dart index 6731053..f57b19f 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dt_work/dt_work_detai/breakground_apply_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dt_work/dt_work_detai/breakground_apply_detail.dart @@ -420,10 +420,10 @@ class _BreakgroundApplyDetailState extends State { final textRules = >[ {'value': _locationController.text.trim(), 'message': '请输入作业地点'}, {'value': _contentController.text.trim(), 'message': '请输入作业内容'}, - { - 'value': _relatedController.text.trim(), - 'message': '请输入关联的其他特殊作业及安全作业票编号', - }, + // { + // 'value': _relatedController.text.trim(), + // 'message': '请输入关联的其他特殊作业及安全作业票编号', + // }, {'value': _riskController.text.trim(), 'message': '请输入风险辨识结果'}, ]; diff --git a/lib/pages/home/tap/tabList/special_wrok/dt_work/ysgd_work_detail/breakground_ysgd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dt_work/ysgd_work_detail/breakground_ysgd_detail.dart index 1b6d1c4..9aff356 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dt_work/ysgd_work_detail/breakground_ysgd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dt_work/ysgd_work_detail/breakground_ysgd_detail.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; import 'package:qhd_prevention/tools/tools.dart'; @@ -382,9 +383,6 @@ class _BreakgroundYsgdDetailState extends State { horizontalPadding: 0, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/dt_work/zyr_work_detail/breakground_zyr_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dt_work/zyr_work_detail/breakground_zyr_detail.dart index 41d42be..e4ee1f7 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dt_work/zyr_work_detail/breakground_zyr_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dt_work/zyr_work_detail/breakground_zyr_detail.dart @@ -353,9 +353,6 @@ class _BreakgroundZyrDetailState extends State { isShowNum: false, isRequired: true, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = workImages.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/dz_work/aqjd_work_detail/hoistwork_aqjd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dz_work/aqjd_work_detail/hoistwork_aqjd_detail.dart index 3e7f45f..4cbe1e9 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dz_work/aqjd_work_detail/hoistwork_aqjd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dz_work/aqjd_work_detail/hoistwork_aqjd_detail.dart @@ -317,9 +317,6 @@ class _HoistworkAqjdDetailState extends State { mediaType: MediaType.image, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/dz_work/dz_work_detai/hoistwork_apply_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dz_work/dz_work_detai/hoistwork_apply_detail.dart index 62cf9a2..b938683 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dz_work/dz_work_detai/hoistwork_apply_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dz_work/dz_work_detai/hoistwork_apply_detail.dart @@ -428,10 +428,10 @@ class _HoistworkApplyDetailState extends State { {'value': _nameController.text.trim(), 'message': '请输入吊具名称'}, {'value': _hightController.text.trim(), 'message': '请输入吊物质量(吨)'}, {'value': _contentController.text.trim(), 'message': '请输入吊物内容'}, - { - 'value': _relatedController.text.trim(), - 'message': '请输入关联的其他特殊作业及安全作业票编号', - }, + // { + // 'value': _relatedController.text.trim(), + // 'message': '请输入关联的其他特殊作业及安全作业票编号', + // }, {'value': _riskController.text.trim(), 'message': '请输入风险辨识结果'}, ]; final level = pd['WORK_LEVEL'] ?? ''; diff --git a/lib/pages/home/tap/tabList/special_wrok/dz_work/ysgd_work_detail/hoistwork_ysgd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dz_work/ysgd_work_detail/hoistwork_ysgd_detail.dart index d27b590..49a80ea 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dz_work/ysgd_work_detail/hoistwork_ysgd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dz_work/ysgd_work_detail/hoistwork_ysgd_detail.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; import 'package:qhd_prevention/tools/tools.dart'; @@ -199,7 +200,7 @@ class _HoistworkYsgdDetailState extends State { title: '作废原因', hintText: '请输入作废原因', cancelText: '取消', - confirmText: '确定' + confirmText: '确定', ); if (reasonText.isEmpty) { ToastUtil.showNormal(context, '请填写作废原因'); @@ -243,7 +244,7 @@ class _HoistworkYsgdDetailState extends State { if (result['result'] == 'success') { ToastUtil.showSuccess(context, '保存成功'); Navigator.of(context).pop(true); - }else{ + } else { ToastUtil.showNormal(context, '操作失败:${result['msg'] ?? '未知错误'}'); } } catch (e) { @@ -382,9 +383,6 @@ class _HoistworkYsgdDetailState extends State { horizontalPadding: 0, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/gc_work/aqjd_work_detail/highwork_aqjd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/gc_work/aqjd_work_detail/highwork_aqjd_detail.dart index 6a757ec..0824c34 100644 --- a/lib/pages/home/tap/tabList/special_wrok/gc_work/aqjd_work_detail/highwork_aqjd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/gc_work/aqjd_work_detail/highwork_aqjd_detail.dart @@ -317,9 +317,6 @@ class _HighworkAqjdDetailState extends State { mediaType: MediaType.image, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/gc_work/gc_work_detai/highwork_apply_detail.dart b/lib/pages/home/tap/tabList/special_wrok/gc_work/gc_work_detai/highwork_apply_detail.dart index 1c9b1c5..9e6cfa4 100644 --- a/lib/pages/home/tap/tabList/special_wrok/gc_work/gc_work_detai/highwork_apply_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/gc_work/gc_work_detai/highwork_apply_detail.dart @@ -428,10 +428,10 @@ class _HighworkApplyDetailState extends State { {'value': _hightController.text.trim(), 'message': '请填写高度'}, {'value': _contentController.text.trim(), 'message': '请填写作业内容'}, - { - 'value': _relatedController.text.trim(), - 'message': '请输入关联的其他特殊作业及安全作业票编号', - }, + // { + // 'value': _relatedController.text.trim(), + // 'message': '请输入关联的其他特殊作业及安全作业票编号', + // }, {'value': _riskController.text.trim(), 'message': '请填写风险辨识结果'}, ]; final level = pd['WORK_LEVEL'] ?? ''; diff --git a/lib/pages/home/tap/tabList/special_wrok/gc_work/ysgd_work_detail/highwork_ysgd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/gc_work/ysgd_work_detail/highwork_ysgd_detail.dart index baa1f97..a8362d1 100644 --- a/lib/pages/home/tap/tabList/special_wrok/gc_work/ysgd_work_detail/highwork_ysgd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/gc_work/ysgd_work_detail/highwork_ysgd_detail.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; import 'package:qhd_prevention/tools/tools.dart'; @@ -199,7 +200,7 @@ class _HighworkYsgdDetailState extends State { title: '作废原因', hintText: '请输入作废原因', cancelText: '取消', - confirmText: '确定' + confirmText: '确定', ); if (reasonText.isEmpty) { ToastUtil.showNormal(context, '请填写作废原因'); @@ -243,7 +244,7 @@ class _HighworkYsgdDetailState extends State { if (result['result'] == 'success') { ToastUtil.showSuccess(context, '保存成功'); Navigator.of(context).pop(true); - }else{ + } else { ToastUtil.showNormal(context, '操作失败:${result['msg'] ?? '未知错误'}'); } } catch (e) { @@ -382,9 +383,6 @@ class _HighworkYsgdDetailState extends State { horizontalPadding: 0, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/lsyd_work/aqjd_work_detail/electricity_aqjd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/lsyd_work/aqjd_work_detail/electricity_aqjd_detail.dart index cec1f35..d86c219 100644 --- a/lib/pages/home/tap/tabList/special_wrok/lsyd_work/aqjd_work_detail/electricity_aqjd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/lsyd_work/aqjd_work_detail/electricity_aqjd_detail.dart @@ -324,9 +324,6 @@ class _ElectricityAqjdDetailState extends State { mediaType: MediaType.image, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/lsyd_work/lsyd_work_detai/electricity_apply_detail.dart b/lib/pages/home/tap/tabList/special_wrok/lsyd_work/lsyd_work_detai/electricity_apply_detail.dart index 3f05bea..9961bde 100644 --- a/lib/pages/home/tap/tabList/special_wrok/lsyd_work/lsyd_work_detai/electricity_apply_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/lsyd_work/lsyd_work_detai/electricity_apply_detail.dart @@ -441,7 +441,10 @@ class _ElectricityApplyDetailState extends State { 'message': '请输入负责人电工号', }, {'value': _VController.text.trim(), 'message': '请输入工作电压'}, - {'value': _relatedController.text.trim(), 'message': '请输入关联的其他特殊作业及安全作业票编号'}, + // { + // 'value': _relatedController.text.trim(), + // 'message': '请输入关联的其他特殊作业及安全作业票编号', + // }, {'value': _riskController.text.trim(), 'message': '请填写风险辨识结果'}, diff --git a/lib/pages/home/tap/tabList/special_wrok/lsyd_work/ysgd_work_detail/electricity_ysgd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/lsyd_work/ysgd_work_detail/electricity_ysgd_detail.dart index 6855499..96375ed 100644 --- a/lib/pages/home/tap/tabList/special_wrok/lsyd_work/ysgd_work_detail/electricity_ysgd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/lsyd_work/ysgd_work_detail/electricity_ysgd_detail.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; import 'package:qhd_prevention/tools/tools.dart'; @@ -199,7 +200,7 @@ class _ElectricityYsgdDetailState extends State { title: '作废原因', hintText: '请输入作废原因', cancelText: '取消', - confirmText: '确定' + confirmText: '确定', ); if (reasonText.isEmpty) { ToastUtil.showNormal(context, '请填写作废原因'); @@ -243,7 +244,7 @@ class _ElectricityYsgdDetailState extends State { if (result['result'] == 'success') { ToastUtil.showSuccess(context, '保存成功'); Navigator.of(context).pop(true); - }else{ + } else { ToastUtil.showNormal(context, '操作失败:${result['msg'] ?? '未知错误'}'); } } catch (e) { @@ -388,9 +389,6 @@ class _ElectricityYsgdDetailState extends State { horizontalPadding: 0, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/mbcd_work/aqjd_work_detail/blindboard_aqjd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/mbcd_work/aqjd_work_detail/blindboard_aqjd_detail.dart index 8173383..7b01748 100644 --- a/lib/pages/home/tap/tabList/special_wrok/mbcd_work/aqjd_work_detail/blindboard_aqjd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/mbcd_work/aqjd_work_detail/blindboard_aqjd_detail.dart @@ -320,9 +320,6 @@ class _BlindboardAqjdDetailState extends State { mediaType: MediaType.image, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/mbcd_work/cjry_work_detail/blindboard_cjry_detail.dart b/lib/pages/home/tap/tabList/special_wrok/mbcd_work/cjry_work_detail/blindboard_cjry_detail.dart index 41e9b5b..3bc1841 100644 --- a/lib/pages/home/tap/tabList/special_wrok/mbcd_work/cjry_work_detail/blindboard_cjry_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/mbcd_work/cjry_work_detail/blindboard_cjry_detail.dart @@ -326,9 +326,6 @@ setState(() { horizontalPadding: 0, isRequired: true, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere((e) => e.localPath == path); _onImageRemoved(item); diff --git a/lib/pages/home/tap/tabList/special_wrok/mbcd_work/mbcd_work_detai/blindboard_apply_detail.dart b/lib/pages/home/tap/tabList/special_wrok/mbcd_work/mbcd_work_detai/blindboard_apply_detail.dart index b2a3d30..da91c5d 100644 --- a/lib/pages/home/tap/tabList/special_wrok/mbcd_work/mbcd_work_detai/blindboard_apply_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/mbcd_work/mbcd_work_detai/blindboard_apply_detail.dart @@ -28,6 +28,7 @@ enum EditUserType { CONFIRM('作业负责人单位', '作业负责人', true), LEADER('所在单位', '所在单位负责人', true), WORK_START('实际作业开始负责人单位', '实际作业开始负责人', true), + WORK_END('作业结束负责人单位', '作业结束负责人', true), ACCEPT('验收部门', '验收部门负责人', true); /// 对应的单位显示名 @@ -430,10 +431,13 @@ class _BlindboardApplyDetailState extends State { {'value': _temperatureController.text.trim(), 'message': '请输入温度'}, {'value': _pressureController.text.trim(), 'message': '请输入压力'}, - { - 'value': _relatedController.text.trim(), - 'message': '请输入关联的其他特殊作业及安全作业票编号', - }, + // { + // 'value': _relatedController.text.trim(), + // 'm// { + // 'value': _relatedController.text.trim(), + // 'message': '请输入关联的其他特殊作业及安全作业票编号', + // },', + // }, {'value': _riskController.text.trim(), 'message': '请填写风险辨识结果'}, ]; final level = pd['WORK_TYPE'] ?? ''; @@ -449,6 +453,7 @@ class _BlindboardApplyDetailState extends State { EditUserType.WORKSHOP, EditUserType.WORK_USER, EditUserType.WORK_START, + EditUserType.WORK_END, EditUserType.ACCEPT, ]; if (status == '1') { @@ -666,6 +671,26 @@ class _BlindboardApplyDetailState extends State { ], ), ), + SizedBox(height: 15), + _card( + Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + _chooseItem(EditUserType.WORK_END), + Divider(), + Row( + children: [ + SizedBox(width: 12), + Text( + '友情提示:负责填写作业实际结束时间', + style: TextStyle(color: Colors.red), + ), + ], + ), + SizedBox(height: 5), + ], + ), + ), SizedBox(height: 15), _card(_chooseItem(EditUserType.ACCEPT)), diff --git a/lib/pages/home/tap/tabList/special_wrok/mbcd_work/ysgd_work_detail/blindboard_ysgd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/mbcd_work/ysgd_work_detail/blindboard_ysgd_detail.dart index d177d59..2a4d751 100644 --- a/lib/pages/home/tap/tabList/special_wrok/mbcd_work/ysgd_work_detail/blindboard_ysgd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/mbcd_work/ysgd_work_detail/blindboard_ysgd_detail.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; import 'package:qhd_prevention/tools/tools.dart'; @@ -190,7 +191,7 @@ class _BlindboardYsgdDetailState extends State { title: '作废原因', hintText: '请输入作废原因', cancelText: '取消', - confirmText: '确定' + confirmText: '确定', ); if (reasonText.isEmpty) { ToastUtil.showNormal(context, '请填写作废原因'); @@ -234,7 +235,7 @@ class _BlindboardYsgdDetailState extends State { if (result['result'] == 'success') { ToastUtil.showSuccess(context, '保存成功'); Navigator.of(context).pop(true); - }else{ + } else { ToastUtil.showNormal(context, '操作失败:${result['msg'] ?? '未知错误'}'); } } catch (e) { @@ -375,9 +376,6 @@ class _BlindboardYsgdDetailState extends State { horizontalPadding: 0, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/sxkj_work/aqjd_work_detail/spacework_aqjd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/sxkj_work/aqjd_work_detail/spacework_aqjd_detail.dart index c22ea45..0ae9a14 100644 --- a/lib/pages/home/tap/tabList/special_wrok/sxkj_work/aqjd_work_detail/spacework_aqjd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/sxkj_work/aqjd_work_detail/spacework_aqjd_detail.dart @@ -328,9 +328,6 @@ class _SpaceworkAqjdDetailState extends State { mediaType: MediaType.image, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/tap/tabList/special_wrok/sxkj_work/space_work_detai/spacework_apply_detail.dart b/lib/pages/home/tap/tabList/special_wrok/sxkj_work/space_work_detai/spacework_apply_detail.dart index cd4806f..1abf650 100644 --- a/lib/pages/home/tap/tabList/special_wrok/sxkj_work/space_work_detai/spacework_apply_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/sxkj_work/space_work_detai/spacework_apply_detail.dart @@ -440,10 +440,10 @@ class _SpaceworkApplyDetailState extends State { {'value': _spaceNameController.text.trim(), 'message': '请确认受限空间名称不能为空'}, {'value': _jzController.text.trim(), 'message': '请输入受限空间内原有介质名称'}, {'value': pd['LIMITSPACE_NUMBER'], 'message': '请确认受限空间编号不能为空'}, - { - 'value': _relatedController.text.trim(), - 'message': '请输入关联的其他特殊作业及安全作业票编号', - }, + // { + // 'value': _relatedController.text.trim(), + // 'message': '请输入关联的其他特殊作业及安全作业票编号', + // }, {'value': _riskController.text.trim(), 'message': '请填写风险辨识结果'}, ]; diff --git a/lib/pages/home/tap/tabList/special_wrok/sxkj_work/ysgd_work_detail/spacework_ysgd_detail.dart b/lib/pages/home/tap/tabList/special_wrok/sxkj_work/ysgd_work_detail/spacework_ysgd_detail.dart index 86c3f00..ad08b1e 100644 --- a/lib/pages/home/tap/tabList/special_wrok/sxkj_work/ysgd_work_detail/spacework_ysgd_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/sxkj_work/ysgd_work_detail/spacework_ysgd_detail.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/sxkj_work/qtfx_work_detail/spacework_gas_list.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; @@ -200,7 +201,7 @@ class _SpaceworkYsgdDetailState extends State { title: '作废原因', hintText: '请输入作废原因', cancelText: '取消', - confirmText: '确定' + confirmText: '确定', ); if (reasonText.isEmpty) { ToastUtil.showNormal(context, '请填写作废原因'); @@ -244,7 +245,7 @@ class _SpaceworkYsgdDetailState extends State { if (result['result'] == 'success') { ToastUtil.showSuccess(context, '保存成功'); Navigator.of(context).pop(true); - }else{ + } else { ToastUtil.showNormal(context, '操作失败:${result['msg'] ?? '未知错误'}'); } } catch (e) { @@ -392,9 +393,6 @@ class _SpaceworkYsgdDetailState extends State { horizontalPadding: 0, onChanged: (paths) {}, onMediaAdded: _onImageAdded, - onMediaTapped: (path) { - presentOpaque(SingleImageViewer(imageUrl: path), context); - }, onMediaRemoved: (path) { final item = imgList.firstWhere( (e) => e.localPath == path, diff --git a/lib/pages/home/work/danger_project_page.dart b/lib/pages/home/work/danger_project_page.dart index 49fa52f..666897c 100644 --- a/lib/pages/home/work/danger_project_page.dart +++ b/lib/pages/home/work/danger_project_page.dart @@ -7,9 +7,11 @@ import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/http/ApiService.dart'; import 'package:qhd_prevention/pages/app/Danger_paicha/danger_image_updata_page.dart'; import 'package:qhd_prevention/pages/app/Danger_paicha/hazard_registration_page.dart'; +import 'package:qhd_prevention/tools/coord_convert.dart'; import 'package:qhd_prevention/tools/h_colors.dart'; import 'package:qhd_prevention/tools/tools.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class DangerProjectPage extends StatefulWidget { const DangerProjectPage(this.item, this.type, this.checkrecordId, {super.key}); @@ -533,9 +535,11 @@ class _DangerProjectPageState extends State { } Future _submitInvestigationItems() async { - Position position = await _determinePosition(); - String longitude = position.longitude.toString(); - String latitude = position.latitude.toString(); + //获取定位 + await fetchAndSaveBd09(context); + final prefs = await SharedPreferences.getInstance(); + String latitude = prefs.getString('bd_lat') ?? ''; + String longitude = prefs.getString('bd_lon') ?? ''; upDataItemList.clear(); bool hasNoSelectItem = false; @@ -610,30 +614,6 @@ class _DangerProjectPageState extends State { } } - Future _determinePosition() async { - bool serviceEnabled; - LocationPermission permission; - - serviceEnabled = await Geolocator.isLocationServiceEnabled(); - if (!serviceEnabled) { - return Future.error('Location services are disabled.'); - } - - permission = await Geolocator.checkPermission(); - if (permission == LocationPermission.denied) { - permission = await Geolocator.requestPermission(); - if (permission == LocationPermission.denied) { - return Future.error('Location permissions are denied'); - } - } - - if (permission == LocationPermission.deniedForever) { - return Future.error('Location permissions are permanently denied, we cannot request permissions.'); - } - - return await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); - } - String truncateText(String text, {int maxLength = 17}) { if (text.length <= maxLength) return text; return '${text.substring(0, maxLength)}...'; diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index 1853311..6a73380 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -39,10 +39,10 @@ class LoginPage extends StatefulWidget { class _LoginPageState extends State { final TextEditingController _phoneController = TextEditingController( - text: '13293211008', + // text: '13293211008', ); final TextEditingController _passwordController = TextEditingController( - text: 'Zsaq@123456', + // text: 'Zsaq@123456', ); final GlobalKey _formKey = GlobalKey(); String _errorMessage = ''; diff --git a/lib/tools/coord_convert.dart b/lib/tools/coord_convert.dart new file mode 100644 index 0000000..98cd0ef --- /dev/null +++ b/lib/tools/coord_convert.dart @@ -0,0 +1,229 @@ +// lib/utils/location_helper.dart + +import 'dart:async'; +import 'dart:math'; +import 'package:flutter/material.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart'; +import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +/// ============ 常量与坐标转换相关(WGS84/GCJ02/BD09) ============ + +const double _pi = 3.1415926535897932384626; +const double _xPi = _pi * 3000.0 / 180.0; +const double _a = 6378245.0; +const double _ee = 0.006693421622965943; + +/// 判断是否在中国境内(仅中国境内需要偏移处理) +bool _outOfChina(double lat, double lon) { + if (lon < 72.004 || lon > 137.8347) return true; + if (lat < 0.8293 || lat > 55.8271) return true; + return false; +} + +double _transformLat(double x, double y) { + double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(x.abs()); + ret += (20.0 * sin(6.0 * x * _pi) + 20.0 * sin(2.0 * x * _pi)) * 2.0 / 3.0; + ret += (20.0 * sin(y * _pi) + 40.0 * sin(y / 3.0 * _pi)) * 2.0 / 3.0; + ret += (160.0 * sin(y / 12.0 * _pi) + 320.0 * sin(y * _pi / 30.0)) * 2.0 / 3.0; + return ret; +} + +double _transformLon(double x, double y) { + double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(x.abs()); + ret += (20.0 * sin(6.0 * x * _pi) + 20.0 * sin(2.0 * x * _pi)) * 2.0 / 3.0; + ret += (20.0 * sin(x * _pi) + 40.0 * sin(x / 3.0 * _pi)) * 2.0 / 3.0; + ret += (150.0 * sin(x / 12.0 * _pi) + 300.0 * sin(x / 30.0 * _pi)) * 2.0 / 3.0; + return ret; +} + +/// WGS84 -> GCJ02 +List wgs84ToGcj02(double lat, double lon) { + if (_outOfChina(lat, lon)) return [lat, lon]; + double dLat = _transformLat(lon - 105.0, lat - 35.0); + double dLon = _transformLon(lon - 105.0, lat - 35.0); + double radLat = lat / 180.0 * _pi; + double magic = sin(radLat); + magic = 1 - _ee * magic * magic; + double sqrtMagic = sqrt(magic); + dLat = (dLat * 180.0) / ((_a * (1 - _ee)) / (magic * sqrtMagic) * _pi); + dLon = (dLon * 180.0) / ((_a / sqrtMagic) * cos(radLat) * _pi); + double mgLat = lat + dLat; + double mgLon = lon + dLon; + return [mgLat, mgLon]; +} + +/// GCJ02 -> BD09 +List gcj02ToBd09(double lat, double lon) { + double x = lon; + double y = lat; + double z = sqrt(x * x + y * y) + 0.00002 * sin(y * _xPi); + double theta = atan2(y, x) + 0.000003 * cos(x * _xPi); + double bdLon = z * cos(theta) + 0.0065; + double bdLat = z * sin(theta) + 0.006; + return [bdLat, bdLon]; +} + +/// 直接 WGS84 -> BD09(先 WGS84->GCJ02,再 GCJ02->BD09) +List wgs84ToBd09(double lat, double lon) { + final gcj = wgs84ToGcj02(lat, lon); + return gcj02ToBd09(gcj[0], gcj[1]); +} + +/// ============ 定位相关设置 ============ + +/// 定位请求超时时间(可根据需要调整) +const Duration _locationTimeout = Duration(seconds: 10); + +/// 获取 BD09 坐标(包含权限检查与多种后备方案) +/// 返回 [bdLat, bdLon] +Future> getBd09FromGeolocator({ + LocationAccuracy accuracy = LocationAccuracy.high, +}) async { + // 1. 权限检查与请求(先请求权限) + LocationPermission permission = await Geolocator.checkPermission(); + if (permission == LocationPermission.denied) { + permission = await Geolocator.requestPermission(); + if (permission == LocationPermission.denied) { + // 用户拒绝(不是永久拒绝) + throw Exception('定位权限被用户拒绝'); + } + } + if (permission == LocationPermission.deniedForever) { + // 永久拒绝(需要用户手动到设置开启) + throw Exception('定位权限被永久拒绝'); + } + + // 2. 检查定位服务是否开启(GPS/定位开关) + bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); + if (!serviceEnabled) { + throw Exception('定位服务未开启'); + } + + // 3. 尝试获取当前位置(主方案:getCurrentPosition,带超时) + Position? position; + try { + position = await Geolocator.getCurrentPosition(desiredAccuracy: accuracy) + .timeout(_locationTimeout); + } on TimeoutException catch (_) { + position = null; + } catch (_) { + position = null; + } + + // 4. 后备:尝试 getLastKnownPosition(可能是旧位置) + if (position == null) { + try { + position = await Geolocator.getLastKnownPosition(); + } catch (_) { + position = null; + } + } + + // 5. 后备:在 Android 上尝试 forceAndroidLocationManager(某些设备/厂商兼容性问题) + if (position == null) { + try { + position = await Geolocator.getCurrentPosition( + desiredAccuracy: accuracy, + forceAndroidLocationManager: true, + ).timeout(_locationTimeout); + } catch (_) { + position = null; + } + } + + // 6. 最终仍无位置 -> 抛异常 + if (position == null) { + throw Exception('无法获取位置信息,请检查设备定位设置或权限'); + } + + // 7. 转换 WGS84 -> BD09 并返回 [bdLat, bdLon] + final bd = wgs84ToBd09(position.latitude, position.longitude); + return bd; +} + +/// ============ 错误提示(中文映射) ============ +String _mapExceptionToChineseMessage(Object e) { + final msg = e?.toString() ?? ''; + + if (msg.contains('定位权限被用户拒绝') || msg.contains('Location permissions are denied') || msg.contains('denied')) { + return '定位权限被拒绝,请允许应用获取定位权限。'; + } + if (msg.contains('定位权限被永久拒绝') || msg.contains('deniedForever') || msg.contains('permanently denied')) { + return '定位权限被永久拒绝,请到系统设置手动开启定位权限。'; + } + if (msg.contains('定位服务未开启') || msg.contains('Location services are disabled')) { + return '设备定位功能未开启,请打开系统定位后重试。'; + } + if (msg.contains('无法获取位置信息') || msg.contains('无法获取位置信息')) { + return '无法获取有效定位,请检查网络/GPS并重试(可尝试切换到高精度模式)。'; + } + // 默认返回空字符串,调用方根据空串决定是否显示 + return '定位失败:${msg.replaceAll('Exception: ', '')}'; +} + +/// ============ 主业务方法:获取并保存 BD09(同时处理 UI 提示/引导) ============ +/// 调用示例: await fetchAndSaveBd09(context); +Future fetchAndSaveBd09(BuildContext context) async { + // 显示 loading(若你项目有 LoadingDialogHelper 也可替换为它) + // 注意:若外层已显示 loading,请不要重复显示 + try { + + // 获取 BD09 坐标(包含权限请求、可能弹系统权限对话) + final List bd = await getBd09FromGeolocator(); + final bdLat = bd[0]; + final bdLon = bd[1]; + + // 保存到 SharedPreferences(以字符串保存,便于后续读取) + final prefs = await SharedPreferences.getInstance(); + await prefs.setString('bd_lat', bdLat.toString()); + await prefs.setString('bd_lon', bdLon.toString()); + + // 成功提示 + // ToastUtil.showNormal(context, '定位成功:$bdLat, $bdLon'); + } on Exception catch (e) { + final msg = e.toString(); + + // 定位权限被永久拒绝 -> 引导用户打开应用设置 + if (msg.contains('定位权限被永久拒绝') || msg.contains('deniedForever') || msg.contains('permanently denied')) { + final open = await CustomAlertDialog.showConfirm( + context, + title: '定位权限', + content: '定位权限被永久拒绝,需要手动到应用设置开启定位权限,是否现在打开设置?', + cancelText: '取消', + confirmText: '去设置', + ); + if (open == true) { + await Geolocator.openAppSettings(); + } + } + // 定位服务未开启 -> 引导用户打开系统定位设置 + else if (msg.contains('定位服务未开启') || msg.contains('Location services are disabled')) { + final open = await CustomAlertDialog.showConfirm( + context, + title: '打开定位', + content: '检测到设备定位服务未开启,是否打开系统定位设置?', + cancelText: '取消', + confirmText: '去打开', + ); + if (open == true) { + await Geolocator.openLocationSettings(); + } + } + // 其它错误 -> 以 toast 显示中文提示(如果映射为空则显示原错误) + else { + final userMsg = _mapExceptionToChineseMessage(e); + if (userMsg.isNotEmpty) { + // ToastUtil.showError(context, userMsg); + } else { + // ToastUtil.showError(context, '定位失败:${e.toString()}'); + } + } + } catch (e) { + // 捕获任何未预期异常 + // ToastUtil.showError(context, '发生未知错误:${e.toString()}'); + } finally { + + } +} diff --git a/lib/tools/tools.dart b/lib/tools/tools.dart index e589243..1d315ed 100644 --- a/lib/tools/tools.dart +++ b/lib/tools/tools.dart @@ -495,3 +495,4 @@ class NativeOrientation { } } } + diff --git a/pubspec.yaml b/pubspec.yaml index 9056651..23941a9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +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 # 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. -version: 2.1.2+2 +version: 2.1.2+3 environment: sdk: ^3.7.0 @@ -86,7 +86,6 @@ dependencies: webview_flutter: ^4.4.0 path_provider: ^2.0.1 - camera: ^0.11.2 #富文本查看 flutter_html: ^3.0.0