diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index bb7c53b..d583b3f 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_webrtc","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\flutter_webrtc-0.9.48+hotfix.1\\\\","native_build":true,"dependencies":[]},{"name":"open_settings","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\open_settings-2.0.2\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"permission_handler_apple","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\permission_handler_apple-9.4.5\\\\","native_build":true,"dependencies":[]},{"name":"quick_blue","path":"D:\\\\ly\\\\dart\\\\A\\\\new\\\\pile_nav_new\\\\plugins\\\\quick_blue\\\\","native_build":true,"dependencies":[]},{"name":"wifi_iot","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\wifi_iot-0.3.19+1\\\\","native_build":true,"dependencies":[]},{"name":"wifi_scan","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\wifi_scan-0.4.1+1\\\\","native_build":true,"dependencies":[]}],"android":[{"name":"flutter_webrtc","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\flutter_webrtc-0.9.48+hotfix.1\\\\","native_build":true,"dependencies":[]},{"name":"libserialport","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\git\\\\libserialport-d6d27ef7aaf89e4dfa026db0c50dd3053c546710\\\\","native_build":true,"dependencies":[]},{"name":"open_settings","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\open_settings-2.0.2\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_android-2.2.12\\\\","native_build":true,"dependencies":[]},{"name":"permission_handler_android","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\permission_handler_android-12.0.13\\\\","native_build":true,"dependencies":[]},{"name":"quick_blue","path":"D:\\\\ly\\\\dart\\\\A\\\\new\\\\pile_nav_new\\\\plugins\\\\quick_blue\\\\","native_build":true,"dependencies":[]},{"name":"wifi_iot","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\wifi_iot-0.3.19+1\\\\","native_build":true,"dependencies":[]},{"name":"wifi_scan","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\wifi_scan-0.4.1+1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"flutter_webrtc","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\flutter_webrtc-0.9.48+hotfix.1\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"quick_blue","path":"D:\\\\ly\\\\dart\\\\A\\\\new\\\\pile_nav_new\\\\plugins\\\\quick_blue\\\\","native_build":true,"dependencies":[]}],"linux":[{"name":"flutter_webrtc","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\flutter_webrtc-0.9.48+hotfix.1\\\\","native_build":true,"dependencies":[]},{"name":"libserialport","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\git\\\\libserialport-d6d27ef7aaf89e4dfa026db0c50dd3053c546710\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_linux","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"quick_blue","path":"D:\\\\ly\\\\dart\\\\A\\\\new\\\\pile_nav_new\\\\plugins\\\\quick_blue\\\\","native_build":false,"dependencies":[]}],"windows":[{"name":"flutter_webrtc","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\flutter_webrtc-0.9.48+hotfix.1\\\\","native_build":true,"dependencies":[]},{"name":"libserialport","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\git\\\\libserialport-d6d27ef7aaf89e4dfa026db0c50dd3053c546710\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_windows","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_windows-2.3.0\\\\","native_build":false,"dependencies":[]},{"name":"permission_handler_windows","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\permission_handler_windows-0.2.1\\\\","native_build":true,"dependencies":[]},{"name":"quick_blue","path":"D:\\\\ly\\\\dart\\\\A\\\\new\\\\pile_nav_new\\\\plugins\\\\quick_blue\\\\","native_build":true,"dependencies":[]}],"web":[{"name":"permission_handler_html","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\permission_handler_html-0.1.3+2\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_webrtc","dependencies":["path_provider"]},{"name":"libserialport","dependencies":[]},{"name":"open_settings","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":["permission_handler_android","permission_handler_apple","permission_handler_html","permission_handler_windows"]},{"name":"permission_handler_android","dependencies":[]},{"name":"permission_handler_apple","dependencies":[]},{"name":"permission_handler_html","dependencies":[]},{"name":"permission_handler_windows","dependencies":[]},{"name":"quick_blue","dependencies":[]},{"name":"wifi_iot","dependencies":[]},{"name":"wifi_scan","dependencies":[]}],"date_created":"2024-11-06 16:19:14.820151","version":"3.24.4","swift_package_manager_enabled":false} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_webrtc","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\flutter_webrtc-0.9.48+hotfix.1\\\\","native_build":true,"dependencies":[]},{"name":"open_settings","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\open_settings-2.0.2\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"permission_handler_apple","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\permission_handler_apple-9.4.5\\\\","native_build":true,"dependencies":[]},{"name":"quick_blue","path":"D:\\\\ly\\\\dart\\\\A\\\\new\\\\pile_nav_new\\\\plugins\\\\quick_blue\\\\","native_build":true,"dependencies":[]},{"name":"wifi_iot","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\wifi_iot-0.3.19+1\\\\","native_build":true,"dependencies":[]},{"name":"wifi_scan","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\wifi_scan-0.4.1+1\\\\","native_build":true,"dependencies":[]}],"android":[{"name":"flutter_webrtc","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\flutter_webrtc-0.9.48+hotfix.1\\\\","native_build":true,"dependencies":[]},{"name":"libserialport","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\git\\\\libserialport-d6d27ef7aaf89e4dfa026db0c50dd3053c546710\\\\","native_build":true,"dependencies":[]},{"name":"open_settings","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\open_settings-2.0.2\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_android-2.2.12\\\\","native_build":true,"dependencies":[]},{"name":"permission_handler_android","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\permission_handler_android-12.0.13\\\\","native_build":true,"dependencies":[]},{"name":"quick_blue","path":"D:\\\\ly\\\\dart\\\\A\\\\new\\\\pile_nav_new\\\\plugins\\\\quick_blue\\\\","native_build":true,"dependencies":[]},{"name":"wifi_iot","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\wifi_iot-0.3.19+1\\\\","native_build":true,"dependencies":[]},{"name":"wifi_scan","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\wifi_scan-0.4.1+1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"flutter_webrtc","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\flutter_webrtc-0.9.48+hotfix.1\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"quick_blue","path":"D:\\\\ly\\\\dart\\\\A\\\\new\\\\pile_nav_new\\\\plugins\\\\quick_blue\\\\","native_build":true,"dependencies":[]}],"linux":[{"name":"flutter_webrtc","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\flutter_webrtc-0.9.48+hotfix.1\\\\","native_build":true,"dependencies":[]},{"name":"libserialport","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\git\\\\libserialport-d6d27ef7aaf89e4dfa026db0c50dd3053c546710\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_linux","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"quick_blue","path":"D:\\\\ly\\\\dart\\\\A\\\\new\\\\pile_nav_new\\\\plugins\\\\quick_blue\\\\","native_build":false,"dependencies":[]}],"windows":[{"name":"flutter_webrtc","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\flutter_webrtc-0.9.48+hotfix.1\\\\","native_build":true,"dependencies":[]},{"name":"libserialport","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\git\\\\libserialport-d6d27ef7aaf89e4dfa026db0c50dd3053c546710\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_windows","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_windows-2.3.0\\\\","native_build":false,"dependencies":[]},{"name":"permission_handler_windows","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\permission_handler_windows-0.2.1\\\\","native_build":true,"dependencies":[]},{"name":"quick_blue","path":"D:\\\\ly\\\\dart\\\\A\\\\new\\\\pile_nav_new\\\\plugins\\\\quick_blue\\\\","native_build":true,"dependencies":[]}],"web":[{"name":"permission_handler_html","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.flutter-io.cn\\\\permission_handler_html-0.1.3+2\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_webrtc","dependencies":["path_provider"]},{"name":"libserialport","dependencies":[]},{"name":"open_settings","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":["permission_handler_android","permission_handler_apple","permission_handler_html","permission_handler_windows"]},{"name":"permission_handler_android","dependencies":[]},{"name":"permission_handler_apple","dependencies":[]},{"name":"permission_handler_html","dependencies":[]},{"name":"permission_handler_windows","dependencies":[]},{"name":"quick_blue","dependencies":[]},{"name":"wifi_iot","dependencies":[]},{"name":"wifi_scan","dependencies":[]}],"date_created":"2024-11-15 17:09:47.525275","version":"3.24.4","swift_package_manager_enabled":false} \ No newline at end of file diff --git a/README.md b/README.md index 7ee81c4..aae9c50 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,6 @@ -# cpnav +## 登录之后存的数据有 -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) - -For help getting started with Flutter development, view the -[online documentation](https://docs.flutter.dev/), which offers tutorials, -samples, guidance on mobile development, and a full API reference. + 1. 项目 project + 2. 设备 device + 3. 任务 task + 4. 用户 user diff --git a/analysis_options.yaml b/analysis_options.yaml index 0d29021..0ccc657 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -7,6 +7,9 @@ # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. +analyzer: + errors: + non_constant_identifier_names: ignore include: package:flutter_lints/flutter.yaml linter: diff --git a/lib/appbar.dart b/lib/appbar.dart index ccd7bf5..b7d1292 100644 --- a/lib/appbar.dart +++ b/lib/appbar.dart @@ -1,11 +1,15 @@ +import 'package:cpnav/pages/setting/setting_controller.dart'; +import 'package:cpnav/pages/task/taskcontroller.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'main.dart'; import 'pages/aim_point/aimpoint_controller.dart'; import 'pages/real/real_controller.dart'; -final AimPointerController aimcontroller = Get.find(); -final RealController realcontroller = Get.find(); +final AimPointerController aimcontroller = Get.find(); +final RealController realcontroller = Get.find(); +final TaskController taskcontroller = Get.find(); +final SettingController settingcontroller = Get.find(); class CustomAppBar extends StatelessWidget implements PreferredSizeWidget { final double appBarHeight; @@ -26,14 +30,30 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget { toolbarHeight: 40, centerTitle: true, // 标题居中 title: Obx(() { + // pile_cm + // if (_currentIndex.value == 0) { + // return const Text("桩点:", style: textStyle); + // } else if (_currentIndex.value == 1) { + // return Text( + // "设备:${settingcontroller.currentDevice.value?.name ?? ""} | 任务:${taskcontroller.currentask.value.name}", + // style: textStyle); + // } else if (_currentIndex.value == 2) { + // return const Text("任务管理", style: textStyle); + // } else if (_currentIndex.value == 3) { + // return const Text("历史数据", style: textStyle); + // }else { + // return const Text("系统:", style: textStyle); + // } if (_currentIndex.value == 0) { - return const Text("桩点:", style: textStyle); + return Text( + "设备:${settingcontroller.currentDevice.value?.name ?? ""} | 任务:${taskcontroller.currentask.value.name}", + style: textStyle); } else if (_currentIndex.value == 1) { - return const Text("设备:", style: textStyle); - } else if (_currentIndex.value == 2) { return const Text("任务管理", style: textStyle); + } else if (_currentIndex.value == 2) { + return const Text("历史数据", style: textStyle); } else { - return const Text("系统:", style: textStyle); + return const Text("系统", style: textStyle); } }), leading: null, @@ -89,7 +109,7 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget { const SizedBox( width: 10, ), - _currentIndex.value == 1 + _currentIndex.value == 0 ? Row( children: [ Obx( diff --git a/lib/controllers/appcontroller.dart b/lib/controllers/appcontroller.dart index 7e65b25..027253d 100644 --- a/lib/controllers/appcontroller.dart +++ b/lib/controllers/appcontroller.dart @@ -14,10 +14,11 @@ class AppController extends GetxController { // 绑定 currentIndex ever(currentIndex, (value) { mapcontroller.currentIndex.value = value; - }); - - ever(mapcontroller.currentIndex, (value) { currentIndex.value = value; }); + + // ever(mapcontroller.currentIndex, (value) { + + // }); } } diff --git a/lib/controllers/gnss_Controller.dart b/lib/controllers/gnss_Controller.dart index 9901d31..580e874 100644 --- a/lib/controllers/gnss_Controller.dart +++ b/lib/controllers/gnss_Controller.dart @@ -1,15 +1,19 @@ import 'dart:async'; import 'dart:math'; import 'dart:developer' as dev; -import 'dart:ui'; +import 'package:cpnav/pages/setting/setting_controller.dart'; +import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:gnss/gnss.dart'; import 'package:scence_map/controllers/controller.dart'; import 'package:scence_map/record_entity.dart'; +import '../main.dart'; import '../models/pilePoint/coord_trans.dart'; import '../pages/aim_point/aimpoint_controller.dart'; +SettingController settingController = Get.find(); + class GnssController extends GetxController { late final Gnss gnss; late ScenceMapController mapController; @@ -38,7 +42,7 @@ class GnssController extends GetxController { return; } - Offset pilerCenterPoint = Offset(device.x, device.y); + Offset pilerCenterPoint = Offset(device.x.value, device.y.value); if (aimcontroller.selectedPilePoint == null) { return; } @@ -64,19 +68,36 @@ class GnssController extends GetxController { @override void onInit() async { super.onInit(); + mapController = Get.find(); aimcontroller = Get.find(); - device = DeviceItem( - name: 'GNSS', - tid: 1001, - type: 2, - height: 3.0, - width: 3.0, - lat: 3790621.123, - lon: 577052.547, - image: ['assets/images/pilerCar.png']); - mapController.addDevice(device); + if (settingController.currentDevice.value != null) { + device = settingController.currentDevice.value!; + } else { + device = DeviceItem( + name: "", + tid: 0, + type: "", + height: 0.0, + width: 0.0, + image: "", + ); + } + if (device.x.value == 0 && device.y.value == 0) { + device.x.value = 3790621.123; + device.y.value = 577052.547; + } + // device = DeviceItem( + // name: 'GNSS', + // tid: 1001, + // // type: 2, + // height: 3.0, + // width: 3.0, + // lat: 3790621.123, + // lon: 577052.547, + // image: 'assets/images/pilerCar.png'); + // mapController.addDevice(device); // pilerCenterPoint = PilerPointCalculate( // maindrilldistance.value, // auxdrilldistance.value, @@ -91,26 +112,25 @@ class GnssController extends GetxController { if (lastPilePoint != aimcontroller.selectedPilePoint) { lastPilePoint = aimcontroller.selectedPilePoint; if (aimcontroller.selectedPilePoint != null) { - var dx = device.x - aimcontroller.selectedPilePoint!.x; - var dy = device.y - aimcontroller.selectedPilePoint!.y; + var dx = device.x.value - aimcontroller.selectedPilePoint!.x; + var dy = device.y.value - aimcontroller.selectedPilePoint!.y; var distance = sqrt(dx * dx + dy * dy); if (distance > 2) { - dx = (aimcontroller.selectedPilePoint!.x - device.x) / + dx = (aimcontroller.selectedPilePoint!.x - device.x.value) / (distance / 2); - dy = (aimcontroller.selectedPilePoint!.y - device.y) / + dy = (aimcontroller.selectedPilePoint!.y - device.y.value) / (distance / 2); - device.x = aimcontroller.selectedPilePoint!.x + dx; - device.y = aimcontroller.selectedPilePoint!.y + dy; + device.x.value = aimcontroller.selectedPilePoint!.x + dx; + device.y.value = aimcontroller.selectedPilePoint!.y + dy; } _dx = -dx / 10; _dy = -dy / 10; - } } // if ((aimcontroller.selectedPilePoint!.x - device.x).abs() > _dx.abs()) { - device.x += _dx; - device.y += _dy; + device.x.value += _dx; + device.y.value += _dy; // } else { // device.x = aimcontroller.selectedPilePoint!.x; // device.y = aimcontroller.selectedPilePoint!.y; @@ -118,14 +138,27 @@ class GnssController extends GetxController { // device.x += 0.05; // device.y += 0.05; - device.rotation = device.rotation + pi / 180; // 确保旋转角度在0-360度之间 + device.rotation.value += pi / 180; // 确保旋转角度在0-360度之间 device.update.value++; checkDistance(); }); gnss = Gnss(port: "/dev/ttysWK2", baudrate: 115200); // gnss = Gnss(port: "COM1", baudrate: 115200); - gnss.start(); + try { + gnss.start(); + } catch (e) { + scaffoldMessengerKey.currentState?.showSnackBar( + SnackBar( + content: Text('发生错误: ${e.toString()}'), + duration: const Duration(seconds: 25), + backgroundColor: Colors.red, + ), + ); + + return; + } + gnss.locationStream.listen((location) { locationData = location; // log(locationData); diff --git a/lib/main.dart b/lib/main.dart index bafc86d..7370aaa 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,43 +1,52 @@ import 'package:cpnav/controllers/appcontroller.dart'; -import 'package:cpnav/controllers/gnss_controller.dart'; -import 'package:cpnav/pages/setting/child_pages/antenna/antenna_setting.dart'; import 'package:cpnav/pages/task/task_page.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:scence_map/controllers/controller.dart'; -import 'package:scence_map/controllers/plum_controller.dart'; + import 'appbar.dart'; + import 'pages/aim_point/aimpoint_controller.dart'; import 'pages/history/history_record.dart'; import 'pages/login/login_page.dart'; import 'pages/login/my_routes.dart'; import 'pages/pass_track/view.dart'; -// import 'pages/pile/rightDra/pileGenerate.dart'; import 'pages/real/index.dart'; -import 'pages/setting/child_pages/XyChange/connect.dart'; + +import 'pages/real/real_controller.dart'; +import 'pages/setting/child_pages/antenna/antenna_setting.dart'; +import 'pages/setting/setting_controller.dart'; import 'pages/setting/setting_page.dart'; +import 'pages/setting/child_pages/XyChange/connect.dart'; +import 'pages/task/taskcontroller.dart'; import 'service/user/loginprefs.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; + +import 'package:scence_map/controllers/plum_controller.dart'; + +import '../../controllers/gnss_controller.dart'; final AppController appcontroller = Get.put(AppController()); +final GlobalKey scaffoldMessengerKey = + GlobalKey(); Connect connect = Connect(); + void main() async { WidgetsFlutterBinding.ensureInitialized(); SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); //设置全屏 - Get.put(ScenceMapController()); - Get.put(PlumDataController()); - Get.put(AimPointerController()); - Get.put(GnssController()); - Get.put(AntennaController()); - Get.put(AppController()); + Get.put(SettingController()); Get.put(LoginPageController()); Get.put(AccountLoginController()); Get.put(PhoneLoginController()); + Get.put(ScenceMapController()); + Get.put(AimPointerController()); LoginPrefs loginPrefs = LoginPrefs(); String value = await loginPrefs.init(); // await 关键字必须用在异步方法中 await等待异步方法执行完毕 异步方法必须用变量接收 if ('ok' == value) { - connect.init(); + // connect.init(); // loginPrefs.removeToken(); //注释掉即能实现短时间二次登录不需要再重新登录 runApp(const MyApp()); } @@ -49,22 +58,34 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return Obx(() { return MaterialApp( - title: 'Flutter Demo', + scaffoldMessengerKey: scaffoldMessengerKey, + // title: 'Flutter Demo', theme: appcontroller.isDarkMode.value ? ThemeData.dark() : ThemeData.light(), debugShowCheckedModeBanner: false, - home: const MyHomePage(title: 'Flutter Demo Home Page'), + onGenerateRoute: (settings) { + String str = routeBeforeHook(settings); + Widget page = routes[str]!; + return MaterialPageRoute(builder: (BuildContext context) => page); + }, + home: const MyHomePage(), initialRoute: "home", - onGenerateRoute: onGenerateRoute, + localizationsDelegates: GlobalMaterialLocalizations.delegates, + supportedLocales: const [ + Locale('zh', ''), + Locale('en', ''), + ], ); }); } } class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); - final String title; + const MyHomePage({ + super.key, + }); + @override State createState() => _MyHomePageState(); } @@ -72,18 +93,41 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { late bool isPortrait; late double appBarHeight = 34.0; + bool isInitialized = false; + @override + void initState() { + super.initState(); + SettingController settingController = Get.put(SettingController()); + + SchedulerBinding.instance.addPostFrameCallback((_) async { + await loadData(settingController); + setState(() { + isInitialized = settingController.isInitialized; + Get.put(PlumDataController()); + Get.put(AntennaController()); + Get.put(TaskController()); + Get.put(RealController()); + Get.put(GnssController()); + }); + }); + } - final List _pages = [ - const Real(), - PassTrack( - // date: '', - ), - const TaskManagePage(), - const HistoryRecord(), - const SettingPortrait() - ]; @override Widget build(BuildContext context) { + if (!isInitialized) { + return const Scaffold( + body: Center( + child: CircularProgressIndicator(), + ), + ); + } + final List pages = [ + // const Real(), + PassTrack(), + const TaskManagePage(), + const HistoryRecord(), + const SettingPortrait() + ]; return Scaffold( resizeToAvoidBottomInset: false, drawerEdgeDragWidth: 0.0, // 禁止通过滑动打开drawer @@ -100,237 +144,152 @@ class _MyHomePageState extends State { appBarHeight = Orientation.portrait == orientation ? 56.0 : 34.0; isPortrait = Orientation.portrait == orientation ? true : false; appBarHeight = Orientation.portrait == orientation ? 56.0 : 34.0; - if (!isPortrait) { - return Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Expanded( - child: _pages[appcontroller.currentIndex.value], - ), - const VerticalDivider( - width: 1, // 设置高度为1 - thickness: 1, - ), - SizedBox( - width: 48, - child: SafeArea( - child: LayoutBuilder(builder: (context, constraints) { - // 根据屏幕宽度判断横屏或竖屏 - // if (!isPortrait) { - return Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Column( - children: [ - IconButton( - onPressed: () { - setState(() { - appcontroller.currentIndex.value = 0; - }); - }, - icon: const Icon(Icons.date_range_rounded), - color: appcontroller.currentIndex.value == 0 - ? const Color.fromARGB(255, 60, 95, 123) - : Colors.grey, - ), - Align( - alignment: Alignment.center, - child: Text( - '实时', - style: TextStyle( - fontSize: 12, - color: - appcontroller.currentIndex.value == - 0 - ? const Color.fromARGB( - 255, 60, 95, 123) - : Colors.grey, - ), - ), - ), - ], - ), - const Divider( - height: 1, // 设置高度为1 - thickness: 1, - ), - // - Column( - children: [ - IconButton( - onPressed: () { - setState(() { - appcontroller.currentIndex.value = 1; - }); - }, - icon: const Icon(Icons.map_outlined), - color: appcontroller.currentIndex.value == 1 - ? const Color.fromARGB(255, 60, 95, 123) - : Colors.grey, - ), - Align( - alignment: Alignment.center, - child: Text( - '桩点', - style: TextStyle( - fontSize: 12, - color: - appcontroller.currentIndex.value == - 1 - ? const Color.fromARGB( - 255, 60, 95, 123) - : Colors.grey, - ), - ), - ), - ], - ), - const Divider(), - Column( - children: [ - IconButton( - onPressed: () { - setState(() { - appcontroller.currentIndex.value = 2; - }); - }, - icon: const Icon(Icons.my_location_sharp), - color: appcontroller.currentIndex.value == 2 - ? const Color.fromARGB(255, 60, 95, 123) - : Colors.grey, - ), - Align( - alignment: Alignment.center, - child: Text( - '任务', - style: TextStyle( - fontSize: 12, - color: - appcontroller.currentIndex.value == - 2 - ? const Color.fromARGB( - 255, 60, 95, 123) - : Colors.grey, - ), - ), - ), - ], - ), - const Divider(), - Column( - children: [ - IconButton( - onPressed: () { - setState(() { - appcontroller.currentIndex.value = 3; - }); - }, - icon: - const Icon(Icons.table_chart_outlined), - color: appcontroller.currentIndex.value == 3 - ? const Color.fromARGB(255, 60, 95, 123) - : Colors.grey, - ), - Align( - alignment: Alignment.center, - child: Text( - '历史', - style: TextStyle( - fontSize: 12, - color: - appcontroller.currentIndex.value == - 3 - ? const Color.fromARGB( - 255, 60, 95, 123) - : Colors.grey, - ), - ), - ), - ], - ), - const Divider(), - Column( - children: [ - IconButton( - onPressed: () { - setState(() { - appcontroller.currentIndex.value = 4; - }); - }, - icon: const Icon(Icons.settings), - color: appcontroller.currentIndex.value == 4 - ? const Color.fromARGB(255, 60, 95, 123) - : Colors.grey, - ), - Align( - alignment: Alignment.center, - child: Text( - '设置', - style: TextStyle( - fontSize: 12, - color: - appcontroller.currentIndex.value == - 4 - ? const Color.fromARGB( - 255, 60, 95, 123) - : Colors.grey, - ), - ), - ), - ], - ) - ]); - // - }), + return Obx(() { + appcontroller.currentIndex.value; + if (!isPortrait) { + return Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Expanded( + child: pages[appcontroller.currentIndex.value], ), - ) - ]); - } // + const VerticalDivider( + width: 1, // 设置高度为1 + thickness: 1, + ), + SizedBox( + width: 48, + child: SafeArea( + child: LayoutBuilder(builder: (context, constraints) { + // 根据屏幕宽度判断横屏或竖屏 + // if (!isPortrait) { + return Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // buildIconButton( + // context: context, + // index: 0, + // icon: Icons.date_range_rounded, + // label: '实时', + // ), + // const Divider(), + buildIconButton( + context: context, + index: 0, + icon: Icons.map_outlined, + label: '桩点', + ), + const Divider(), + buildIconButton( + context: context, + index: 1, + icon: Icons.my_location_sharp, + label: '任务', + ), + const Divider(), + buildIconButton( + context: context, + index: 2, + icon: Icons.table_chart_outlined, + label: '历史', + ), + const Divider(), + buildIconButton( + context: context, + index: 3, + icon: Icons.settings, + label: '设置', + ), + ]); + // + }), + ), + ) + ]); + } // - else { - // 竖屏布局,保持原有底部导航栏样式 - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Expanded( - flex: 12, - child: _pages[appcontroller.currentIndex.value], - ), - // VerticalDivider(), - Expanded( - flex: 1, - child: SizedBox( - height: 48, - child: BottomNavigationBar( - type: BottomNavigationBarType.fixed, - currentIndex: appcontroller.currentIndex.value, - onTap: (index) { - setState(() { - appcontroller.currentIndex.value = index; - }); - }, - items: const [ - BottomNavigationBarItem( - icon: Icon(Icons.date_range_rounded), - label: "实时"), - BottomNavigationBarItem( - icon: Icon(Icons.map_outlined), label: "计划"), - BottomNavigationBarItem( - icon: Icon(Icons.my_location_sharp), - label: "任务"), - BottomNavigationBarItem( - icon: Icon(Icons.table_chart_outlined), - label: "历史"), - BottomNavigationBarItem( - icon: Icon(Icons.settings), label: "设置"), - ]), + else { + // 竖屏布局,保持原有底部导航栏样式 + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Expanded( + flex: 12, + child: pages[appcontroller.currentIndex.value], ), - ) - ]); - } + // VerticalDivider(), + Expanded( + flex: 1, + child: SizedBox( + height: 48, + child: BottomNavigationBar( + type: BottomNavigationBarType.fixed, + currentIndex: appcontroller.currentIndex.value, + onTap: (index) { + setState(() { + appcontroller.currentIndex.value = index; + }); + }, + items: const [ + // BottomNavigationBarItem( + // icon: Icon(Icons.date_range_rounded), + // label: "实时"), + BottomNavigationBarItem( + icon: Icon(Icons.map_outlined), label: "计划"), + BottomNavigationBarItem( + icon: Icon(Icons.my_location_sharp), + label: "任务"), + BottomNavigationBarItem( + icon: Icon(Icons.table_chart_outlined), + label: "历史"), + BottomNavigationBarItem( + icon: Icon(Icons.settings), label: "设置"), + ]), + ), + ) + ]); + } + }); }, ), ); } + + Widget buildIconButton({ + required BuildContext context, + required int index, + required IconData icon, + required String label, + }) { + return InkWell( + onTap: () { + setState(() { + appcontroller.currentIndex.value = index; + }); + }, + child: Column( + children: [ + Icon( + (icon), + color: appcontroller.currentIndex.value == index + ? const Color.fromARGB(255, 60, 95, 123) + : Colors.grey, + ), + Align( + alignment: Alignment.center, + child: Text( + label, + style: TextStyle( + fontSize: 12, + color: appcontroller.currentIndex.value == index + ? const Color.fromARGB(255, 60, 95, 123) + : Colors.grey, + ), + ), + ), + ], + ), + ); + } } diff --git a/lib/pages/aim_point/aimpoint_page.dart b/lib/pages/aim_point/aimpoint_page.dart index 544f480..755a38f 100644 --- a/lib/pages/aim_point/aimpoint_page.dart +++ b/lib/pages/aim_point/aimpoint_page.dart @@ -4,14 +4,13 @@ import 'dart:developer' as dev; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:scence_map/controllers/controller.dart'; -import '../../controllers/appcontroller.dart'; import '../../controllers/gnss_controller.dart'; import '../../service/pile/device_type.dart'; import 'aimpoint_controller.dart'; -final AimPointerController aimcontroller = Get.put(AimPointerController()); -final ScenceMapController mapcontroller = Get.put(ScenceMapController()); -final GnssController gnsscontroller = Get.put(GnssController()); +final AimPointerController aimcontroller = Get.find(); +final ScenceMapController mapcontroller = Get.find(); +final GnssController gnsscontroller = Get.find(); // ignore: must_be_immutable class AimPointer extends GetView { @@ -27,7 +26,7 @@ class AimPointer extends GetView { double rectWidth = size.width; final deviceType = getDeviceType(context); - Get.put(AppController()); + if (orientation == Orientation.landscape) { rectWidth = size.width / 2 - 60; if (deviceType == DeviceType.mobile) { @@ -149,7 +148,7 @@ class AimPointer extends GetView { aimcontroller.x.value / pixel2MeterRatio, child: Transform( transform: Matrix4.identity() - ..rotateZ(gnsscontroller.device.rotation + + ..rotateZ(gnsscontroller.device.rotation.value + pi / 2 + mapcontroller.rotation.value), alignment: FractionalOffset.center, diff --git a/lib/pages/history/component/canlender_select.dart b/lib/pages/history/component/canlender_select.dart index 510165a..2aedf81 100644 --- a/lib/pages/history/component/canlender_select.dart +++ b/lib/pages/history/component/canlender_select.dart @@ -52,7 +52,7 @@ class _CanlenderSelectState extends State { @override Widget build(BuildContext context) { - final isDarkMode = Theme.of(context).brightness == Brightness.dark; + final isDarkMode = Theme.of(context).brightness == Brightness.dark; var dayTextStyle = TextStyle( color: isDarkMode ? Colors.white : Colors.black, fontWeight: FontWeight.w700); @@ -104,15 +104,11 @@ class _CanlenderSelectState extends State { }) { Widget? dayWidget; for (var i = 0; i < widget.constructionData.length; i++) { - if (date.year == - int.parse( - widget.constructionData[i].toString().split("-")[0]) && - date.month == - int.parse( - widget.constructionData[i].toString().split("-")[1]) && - date.day == - int.parse( - widget.constructionData[i].toString().split("-")[2])) { + String cData = widget.constructionData[i].toString(); + + if (date.year == int.parse(cData.split("-")[0]) && + date.month == int.parse(cData.split("-")[1]) && + date.day == int.parse(cData.split("-")[2])) { dayWidget = Container( decoration: decoration, child: Center( @@ -192,7 +188,8 @@ class _CanlenderSelectState extends State { onPressed: () async { if (widget.height > 410) { final values = await showCalendarDatePicker2Dialog( - dialogBackgroundColor: isDarkMode ? Colors. black: Colors.white, + dialogBackgroundColor: + isDarkMode ? Colors.black : Colors.white, context: context, config: config, @@ -266,6 +263,4 @@ class _CanlenderSelectState extends State { return valueText; } - - } diff --git a/lib/pages/history/history_record.dart b/lib/pages/history/history_record.dart index 9314d82..c9e9628 100644 --- a/lib/pages/history/history_record.dart +++ b/lib/pages/history/history_record.dart @@ -1,17 +1,17 @@ +import 'package:cpnav/pages/setting/setting_controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:data_table_2/data_table_2.dart'; -import 'package:intl/intl.dart'; +import 'package:scence_map/controllers/controller.dart'; import 'package:scence_map/record_entity.dart'; - import '../../service/base.dart'; +import '../setting/project/model.dart'; import 'component/canlender_select.dart'; import 'component/custom_pager.dart'; import 'record_data_source.dart'; import 'table_col.dart'; -// import 'record_data_source.dart'; // bug 切换到对应proj_type 下 - +SettingController settingController = SettingController(); int currentPage = 1; List dataList = []; List constructionData = []; @@ -38,23 +38,17 @@ class _HistoryRecordState extends State { } PageSyncApproach pageSyncApproach = PageSyncApproach.doNothing; - List tableTitle = [ // 不能设置宽度超过 一定的值 不然会报错 尽量不设置宽度 剩余更多的宽度来均分 - TableCol("pileId", "桩点", 60, null + TableCol("tpId", "桩点", 80, null // (columnIndex, ascending) => // sort((d) => d.pileId, columnIndex, ascending) ), - TableCol('x', "坐标", 140, null), - TableCol('startTime', "开始时间", 170, null), - TableCol('endTime', "结束时间", 170, null), - TableCol('current1Avg', "电流(A)", 0, null), - TableCol('totalFlow', "累计浆量", 0, null), - TableCol('depth', "深度", 0, null), - TableCol('speed', "速度", 0, null), - TableCol('tiltAngle', "倾斜角", 0, null), + TableCol('x', "坐标", 130, null), + TableCol('startTime', "开始时间", 0, null), + TableCol('endTime', "结束时间", 0, null), TableCol('operation', "操作", 0, null), - TableCol('operation', "操作", 0, null) + // TableCol('operation', "操作", 0, null), ]; List tableTitleWidget = []; TextStyle fontstyle = const TextStyle(fontSize: 20); @@ -62,12 +56,13 @@ class _HistoryRecordState extends State { @override void initState() { + super.initState(); for (var i = 0; i < tableTitle.length; i++) { TableCol row = tableTitle[i]; - if (row.props == "pileId") { + if (row.props == "tpId") { //模型转化后的字段 row.onSort = (columnIndex, ascending) { - sort((d) => d.pileId, columnIndex, ascending); + sort((d) => d.tpId, columnIndex, ascending); _asyncrecordsDataSource.sort(row.props, _sortAscending); }; } @@ -93,14 +88,9 @@ class _HistoryRecordState extends State { } } fetchData(); - super.initState(); - if (GetServices().projType == "pile_cm") { - _asyncrecordsDataSource = RecordDataSourceAsync( - _rowsPerPage, selectedDataString ?? "", context); - } else { - _asyncrecordsDataSource = RecordDataSourceAsync( - _rowsPerPage, selectedDataString ?? "", context); - } + + _asyncrecordsDataSource = + RecordDataSourceAsync(_rowsPerPage, selectedDataString ?? "", context); } void getDateValue(String? value) { @@ -113,27 +103,36 @@ class _HistoryRecordState extends State { void fetchData() { dataList.clear(); + ProjectModel? project = settingController.currentProject.value; + project ??= settingController.getproject(); + DeviceItem? device = settingController.currentDevice.value; + device ??= settingController.getdevice(); + if (project == null) { + return; + } + int tid = device!.tid; // 异步加载数据或从API获取数据 SchedulerBinding.instance.addPostFrameCallback((_) async { - List getConstructionData = await GetServices().getworkDateData(); + String projType = settingController.projType; + List getConstructionData = await services.getworkDateData( + project!.orgCode, project.projCode, projType, tid); if (isfirst) { setState(() { if (getConstructionData.isNotEmpty) { selectedDataString = getConstructionData[0]; isfirst = false; } else { - selectedDataString = - DateFormat('yyyy-MM-dd').format(DateTime.now()); + selectedDataString = DateTime.now().toLocal().toString(); } constructionData = getConstructionData; }); } setState(() { - if (getConstructionData.isEmpty) { - constructionData = [selectedDataString]; - } else { - constructionData = getConstructionData; - } + getConstructionData = getConstructionData.where((data) { + // 过滤条件:排除包含 "Invalid Date" 的字符串 + return !data.toString().contains("Invalid Date"); + }).toList(); + constructionData = getConstructionData; }); _asyncrecordsDataSource.date = selectedDataString ?? ""; @@ -154,7 +153,7 @@ class _HistoryRecordState extends State { final ScrollController _controller = ScrollController(); PaginatorController pageController = PaginatorController(); int _rowsPerPage = 20; - final int _fixedRows = 1; + // final int _fixedRows = 1; int? _sortColumnIndex = 0; bool _sortAscending = false; @override @@ -224,10 +223,10 @@ class _HistoryRecordState extends State { verticalInside: BorderSide(width: 0.5, color: Colors.grey), ), headingRowColor: WidgetStateProperty.resolveWith( - (states) => _fixedRows > 0 ? Colors.grey[200] : Colors.transparent), - fixedColumnsColor: Colors.grey[300], - fixedCornerColor: Colors.grey[400], - minWidth: 1000, + (states) => isDarkMode ? Colors.black12 : Colors.grey[200]), + fixedColumnsColor: isDarkMode ? Colors.black12 : Colors.grey[300], + fixedCornerColor: isDarkMode ? Colors.black45 : Colors.grey[400], + minWidth: 600, fixedTopRows: 1, fixedLeftColumns: 1, sortColumnIndex: _sortColumnIndex, @@ -240,6 +239,7 @@ class _HistoryRecordState extends State { _asyncrecordsDataSource.refreshDatasource(); }, columns: tableTitleWidget, + source: _asyncrecordsDataSource, empty: Center( child: Container( diff --git a/lib/pages/history/line_chart.dart b/lib/pages/history/line_chart.dart new file mode 100644 index 0000000..1ef09b4 --- /dev/null +++ b/lib/pages/history/line_chart.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../real/component/chart.dart'; + +class MyLineChart extends StatefulWidget { + final int pileId; + const MyLineChart({super.key, required this.pileId}); + + @override + State createState() => _MyLineChartState(); +} + +class _MyLineChartState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + final size = MediaQuery.of(context).size; + // 锁定横屏 + SystemChrome.setPreferredOrientations([ + DeviceOrientation.landscapeLeft, + DeviceOrientation.landscapeRight, + ]); + return Scaffold( + appBar: AppBar( + toolbarHeight: 30, + title: Text("桩点${widget.pileId}过程"), + ), + body: SizedBox( + height: size.height - 30, + child: ProcessChart( + pileId: widget.pileId, + )), + ); + } +} diff --git a/lib/pages/history/record_data_source.dart b/lib/pages/history/record_data_source.dart index 0d09c93..743cf03 100644 --- a/lib/pages/history/record_data_source.dart +++ b/lib/pages/history/record_data_source.dart @@ -1,10 +1,11 @@ +import 'package:cpnav/pages/pass_track/view.dart'; import 'package:data_table_2/data_table_2.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:scence_map/record_entity.dart'; -import 'package:scence_map/scence_map.dart'; - import '../../service/base.dart'; +import '../setting/project/model.dart'; +import 'line_chart.dart'; class RecordDataSourceAsync extends AsyncDataTableSource { bool _empty = false; @@ -14,11 +15,11 @@ class RecordDataSourceAsync extends AsyncDataTableSource { BuildContext context; final RecordFakeWebService _repo = RecordFakeWebService(); RecordDataSourceAsync(this.size, this.date, this.context) { - // log(' created'); + // print(' created'); } RecordDataSourceAsync.empty(this.size, this.date, this.context) { _empty = true; - // log('empty created'); + // print('empty created'); } String _sortColumn = "tp_id"; @@ -32,30 +33,20 @@ class RecordDataSourceAsync extends AsyncDataTableSource { @override Future getRows(int startIndex, int count) async { - // log('getRows($startIndex, $count)'); page = startIndex ~/ count + 1; - - var data = await GetServices() - .getRcordData(page, count, date, _sortAscending, _sortColumn); + ProjectModel? project = settingController.currentProject.value; + project ??= settingController.getproject(); + if (project == null) { + return AsyncRowsResponse(0, []); + } + String projType = settingController.projType; + var data = await services.getRcordData(projType, project.orgCode, + project.projCode, page, count, date, _sortAscending, _sortColumn); if (data == null) { _empty = true; + } else { + _empty = false; } - // if (_errorCounter != null) { - // _errorCounter = _errorCounter! + 1; - - // if (_errorCounter! % 2 == 1) { - // await Future.delayed(const Duration(milliseconds: 1000)); - // throw 'Error #${((_errorCounter! - 1) / 2).round() + 1} has occured'; - // } - // } - - // final format = NumberFormat.decimalPercentPattern( - // locale: 'en', - // decimalDigits: 0, - // ); - // assert(startIndex >= 0); - - // List returned will be empty is there're fewer items than startingAt var x = _empty ? await Future.delayed(const Duration(milliseconds: 0), () => RecordFakeWebServiceResponse(0, [])) @@ -73,7 +64,7 @@ class RecordDataSourceAsync extends AsyncDataTableSource { } }, cells: [ - // DataCell(Text(item.tpId.toString())), + DataCell(Text(item.tpId.toString())), DataCell(Text( 'x:${item.x.toStringAsFixed(3)}\ny:${item.y.toStringAsFixed(3)}')), DataCell(Text( @@ -81,17 +72,29 @@ class RecordDataSourceAsync extends AsyncDataTableSource { DataCell( Text(DateFormat('yyyy-MM-dd HH:mm:ss').format(item.endTime))), DataCell(TextButton( - onPressed: () => Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const Scaffold( - body: ScenceMapView( - - children: [], - // DateFormat('yyyy-MM-dd') - // .format(item.startTime) - ), - ))), + onPressed: () { + String date = DateFormat('yyyy-MM-dd').format(item.startTime); + + Widget page = PassTrack( + currentPoint: item, + ); + + Navigator.push(context, MaterialPageRoute(builder: (context) { + return Scaffold( + appBar: AppBar( + title: Text("$date 历史轨迹"), + toolbarHeight: 40, + leading: IconButton( + icon: const Icon(Icons.arrow_back), + onPressed: () { + Navigator.pop(context); + }, + ), + ), + body: page, + ); + })); + }, child: const Text("位置"), )), // DataCell(TextButton( @@ -139,18 +142,22 @@ class RecordFakeWebService { Future getData( int startingAt, int count, Map? data) async { + if (data == null) { + return RecordFakeWebServiceResponse(0, []); + } List result = []; - - for (var i = 0; i < (data!["list"] as List).length; i++) { - RecordEntity item = RecordEntity.fromJson(data["list"][i]); + List list = data["list"]; + if (list.isEmpty) { + return RecordFakeWebServiceResponse(0, []); + } + for (var i = 0; i < list.length; i++) { + RecordEntity item = RecordEntity.fromJson(list[i]); result.add(item); } - return Future.delayed(const Duration(milliseconds: 0), () { // result.sort(_getComparisonFunction(sortedBy, sortedAsc)); int total = data["pagination"]["total"]; - return RecordFakeWebServiceResponse( - total , result.toList()); + return RecordFakeWebServiceResponse(total, result.toList()); }); } } diff --git a/lib/pages/login/login_page.dart b/lib/pages/login/login_page.dart index 2d21be2..beba2b3 100644 --- a/lib/pages/login/login_page.dart +++ b/lib/pages/login/login_page.dart @@ -44,16 +44,16 @@ class Login extends GetView { const TextStyle(color: Colors.grey), // 设置未选中标签的字体颜色为灰色 controller: controller.tabController, tabs: const [ - Tab(text: '手机号登录', icon: Icon(Icons.phone_android)), Tab(text: '账号登录', icon: Icon(Icons.account_box_outlined)), + Tab(text: '手机号登录', icon: Icon(Icons.phone_android)), ], ), Expanded( child: TabBarView( controller: controller.tabController, children: const [ - PhoneLoginPage(), AccountLoginPage(), + PhoneLoginPage(), ], ), ), @@ -79,9 +79,11 @@ class AccountLoginController extends GetxController { } Future changeCaptcha() async { - var captcha = await GetServices().getCaptcha(); - svgString.value = captcha['data']; - captchaId.value = captcha['captchaId']; + var captcha = await services.getCaptcha(); + if (captcha['data'] != null) { + svgString.value = captcha['data']; + captchaId.value = captcha['captchaId']; + } } void showErrorSnackbar(String text) { @@ -89,25 +91,10 @@ class AccountLoginController extends GetxController { content: Text(text), backgroundColor: Colors.red, ); - - ScaffoldMessenger.of(Get.context!).showSnackBar(snackBar); + if (Get.context != null) { + ScaffoldMessenger.of(Get.context!).showSnackBar(snackBar); + } } - - // Future login() async { - // if (formKey.currentState!.validate()) { - // formKey.currentState!.save(); - // var res = await GetServices().getAccountLogin( - // captchaId.value, password.value, username.value, verifyCode.value); - // if (res['code'] != 1000) { - // changeCaptcha(); - // showErrorSnackbar(res["message"]); - // } else { - // LoginPrefs().saveExpire(res["data"]["expire"]); - // LoginPrefs().saveToken(res["data"]["token"]); - // Get.offNamed('home'); // 跳转至首页 - // } - // } - // } } class AccountLoginPage extends GetView { @@ -205,6 +192,10 @@ class AccountLoginPage extends GetView { child: Obx(() => controller.svgString.isNotEmpty ? SvgPicture.string( controller.svgString.value, + colorFilter: const ColorFilter.mode( + Colors.black, // 设置颜色和透明度 + BlendMode.srcATop, // 设置混合模式 + ), width: 70, // 设置宽度 height: 40, // 设置高度 // color: Colors.black, @@ -218,7 +209,7 @@ class AccountLoginPage extends GetView { onPressed: () async { if (controller.formKey.currentState!.validate()) { controller.formKey.currentState!.save(); //必须 - var res = await GetServices().getAccountLogin( + var res = await services.getAccountLogin( controller.captchaId.value, controller.password.value, controller.username.value, @@ -230,6 +221,11 @@ class AccountLoginPage extends GetView { } else { loginPrefs.saveExpire((res["data"]["expire"])); loginPrefs.saveToken((res["data"]["token"])); + loginPrefs + .saveRefreshToken(res["data"]["refreshToken"]); + loginPrefs + .saveRefreshExpire(res["data"]["refreshExpire"]); + if (context.mounted) { Navigator.pushNamed(context, 'home'); //跳转至首页 } @@ -256,11 +252,11 @@ class PhoneLoginController extends GetxController { final smsText = '获取验证码'.obs; final _seconds = 60.obs; late Timer _timer; - + LoginPrefs loginPrefs = LoginPrefs(); @override void onInit() { super.onInit(); - phoneNumber.value = LoginPrefs().getPhone(); + phoneNumber.value = loginPrefs.getPhone(); } void startTimer() { @@ -289,9 +285,11 @@ class PhoneLoginController extends GetxController { if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); // 收回键盘 - FocusScope.of(Get.context!).unfocus(); - await GetServices().getsmsCode(phoneNumber.value); + if (Get.context != null) { + FocusScope.of(Get.context!).unfocus(); + } startTimer(); // 开始定时器 + await services.getsmsCode(phoneNumber.value); } } @@ -302,14 +300,16 @@ class PhoneLoginController extends GetxController { // 表单校验通过,执行提交逻辑... // 收回键盘 FocusScope.of(Get.context!).unfocus(); - var res = - await GetServices().phoneLogin(phoneNumber.value, smsCode.value); + var res = await services.phoneLogin(phoneNumber.value, smsCode.value); if (res['code'] != 1000) { showErrorSnackbar(res["message"]); } else { - LoginPrefs().savePhone(phoneNumber.value); - LoginPrefs().saveExpire(res["data"]["expire"]); - LoginPrefs().saveToken(res["data"]["token"]); + loginPrefs.savePhone(phoneNumber.value); + loginPrefs.saveExpire(res["data"]["expire"]); + loginPrefs.saveToken(res["data"]["token"]); + loginPrefs.saveRefreshToken(res["data"]["refreshToken"]); + loginPrefs.saveRefreshExpire(res["data"]["refreshExpire"]); + Get.offNamed('home'); // 跳转至首页 } } diff --git a/lib/pages/login/my_routes.dart b/lib/pages/login/my_routes.dart index 28e98d7..2f9d1a2 100644 --- a/lib/pages/login/my_routes.dart +++ b/lib/pages/login/my_routes.dart @@ -1,35 +1,28 @@ //配置路由 import 'package:flutter/material.dart'; - import '../../main.dart'; import '../../service/user/loginprefs.dart'; +import '../setting/setting_controller.dart'; import 'login_page.dart'; +Map routes = { + 'home': const MyHomePage(), //定义app路径 + 'login': const Login(), //定义login路径 +}; + /* * 这个方法是固定写法,功能就像是一个拦截器。 */ -Route? onGenerateRoute(RouteSettings settings) { - Map routes = { - 'home': const MyHomePage(title: 'Flutter Demo Home Page'), //定义app路径 - 'login': const Login(), //定义login路径 - }; +// String onGenerateRoute(RouteSettings settings) { +// String routerName = routeBeforeHook(settings); +// return routerName; - String routerName = routeBeforeHook(settings); - bool mathMap = false; - Route? mathWidget; - routes.forEach((key, v) { - if (key == routerName) { - mathMap = true; - mathWidget = MaterialPageRoute(builder: (BuildContext context) => v); - } - }); +// } - if (mathMap) { - return mathWidget; - } - return MaterialPageRoute( - builder: (BuildContext context) => const Text('404')); +loadData(SettingController settingController) async { + // 加载数据 + await settingController.init(); } String routeBeforeHook(RouteSettings settings) { diff --git a/lib/pages/pass_track/controller.dart b/lib/pages/pass_track/controller.dart index 056e080..7c01051 100644 --- a/lib/pages/pass_track/controller.dart +++ b/lib/pages/pass_track/controller.dart @@ -1,30 +1,50 @@ -import 'dart:ui'; +import 'dart:developer'; + +import 'package:cpnav/pages/setting/setting_controller.dart'; +import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:cpnav/service/base.dart'; +import 'package:intl/intl.dart'; import 'package:scence_map/controllers/controller.dart'; import 'package:scence_map/record_entity.dart'; +import '../../main.dart'; +import '../setting/project/model.dart'; + +SettingController settingController = Get.find(); + class PassTrackController extends GetxController { final mapController = Get.put(ScenceMapController()); - String projCode; - String projType; - late final GetServices service; - RecordEntity? selectedPilePoint; - PassTrackController(this.projCode, this.projType); + Rx selectedPilePoint = Rx(null); + var updateCount = 0.obs; + var date = "2023-11-1".obs; + RecordEntity? currentPoint; + PassTrackController(); @override - void onInit() { + void onInit() async { super.onInit(); - service = GetServices(projCode: projCode, projType: projType); - loadProject(); loadSideLine(); + loadData(); + ever(date, (val) { + loadData(); + }); + } + + loadData() { // loadBindDevice(); loadRcordList(); } loadBindDevice() async { - var binddevices = await service.getDeviceBind(); + ProjectModel? project = settingController.currentProject.value; + project ??= settingController.getproject(); + if (project == null) { + return; + } + String projType = settingController.projType; + var binddevices = await services.getDeviceBind(projType, project.projCode); for (var device in binddevices) { var dev = DeviceItem.fromJson(device); mapController.deviceList[dev.tid] = dev; @@ -33,10 +53,19 @@ class PassTrackController extends GetxController { loadCoorTrans() async {} - loadProject() async {} - loadSideLine() async { - var data = await service.getSideLine(); + mapController.sideLinListeMap.clear(); + ProjectModel? project = settingController.currentProject.value; + project ??= settingController.getproject(); + if (project == null) { + return; + } + String projType = settingController.projType; + var data = await services.getSideLine(project.projCode, projType); + if (data == null) { + return; + } + double maxX = -double.infinity; double maxY = -double.infinity; double minX = double.infinity; @@ -72,19 +101,51 @@ class PassTrackController extends GetxController { minY != double.infinity) { mapController.centerXY = Offset((maxX + minX) / 2, (maxY + minY) / 2); } + mapController.updateCount++; } loadRcordList() async { - List record = await service.getRcordList("2024-08-7"); + mapController.recordList.length = 0; + ProjectModel? project = settingController.currentProject.value; + project ??= settingController.getproject(); + if (project == null) { + return; + } + String projType = settingController.projType; + List record = await services.getRcordList( + project.orgCode, project.projCode, projType, date.value); + if (record.isNotEmpty) { for (var i = 0; i < record.length; i++) { RecordEntity item = RecordEntity.fromJson(record[i]); + if (currentPoint != null && (currentPoint!.tpId == item.tpId)) { + item.selected = true; + } mapController.recordList.add(item); } - mapController.centerXY = Offset( - mapController.recordList[mapController.recordList.length - 1].x, - mapController.recordList[mapController.recordList.length - 1].y); + if (currentPoint == null) { + mapController.centerXY = Offset( + mapController.recordList[mapController.recordList.length - 1].x, + mapController.recordList[mapController.recordList.length - 1].y); + } else { + mapController.centerXY = Offset(currentPoint!.x, currentPoint!.y); + } + //将地图或画布的中心定位到最新记录的位置上 + } else { + String now = DateFormat('yyyy-MM-dd').format(DateTime.now()); + if ((currentPoint == null && date.value == now) || + (DateFormat('yyyy-MM-dd').format(currentPoint!.startTime) == now)) { + log("${currentPoint?.startTime},now:$now"); + scaffoldMessengerKey.currentState?.showSnackBar( + SnackBar( + content: Text('提示: ${date.value}暂无施工数据'), + duration: const Duration(seconds: 5), + backgroundColor: const Color.fromARGB(255, 230, 162, 60), + ), + ); + } } + mapController.updateCount++; } } diff --git a/lib/pages/pass_track/view.dart b/lib/pages/pass_track/view.dart index 544ed36..c983960 100644 --- a/lib/pages/pass_track/view.dart +++ b/lib/pages/pass_track/view.dart @@ -6,6 +6,7 @@ import 'package:cpnav/main.dart'; import 'package:cpnav/pages/aim_point/aimpoint_page.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:intl/intl.dart'; import 'package:scence_map/controllers/controller.dart'; import 'package:scence_map/record_entity.dart'; import 'package:scence_map/scence_map.dart'; @@ -25,11 +26,13 @@ ScenceMapController mapcontroller = Get.put(ScenceMapController()); // State createState() => _PasstrackState(); // } +// ignore: must_be_immutable class PassTrack extends GetView { // final GlobalKey> _popupMenuKey = // GlobalKey>(); + RecordEntity? currentPoint; @override - final controller = Get.put(PassTrackController("TEST", "pile_cm")); + final controller = Get.put(PassTrackController()); final aimcontroller = Get.find(); // String str = "播放"; // int sWidth = 0; @@ -39,86 +42,48 @@ class PassTrack extends GetView { // int maxLength = 200; // final _rangevalues = const SfRangeValues(0.0, 200.0); - PassTrack({super.key}); - - // @override - // initState() { - // super.initState(); - // SchedulerBinding.instance.addPostFrameCallback((_) async { - // // sWidth = sqrt(screen.width * screen.width + screen.height * screen.height) - // // .ceil(); - - // // // scenceMapController.scale = passTrackPlugin.passTrack_getScale() * 1.0; - // // fileHandle.date = widget.date; - // // await fileHandle.init(); - // // //在帧绘制完成后执行数据渲染 - // // // await initPlatformState(); - // // if (fileHandle.pointData.isNotEmpty) { - // // DecodeDataObj obj = fileHandle.pointData[0].obj!; - // // scenceMapController.centerXY = Offset(obj.y / 20, obj.x / 20); - // // } - - // // for (var item in fileHandle.deviceList) { - // // if (item["point"] != null) { - // // bits = item["bits"]; - // // break; - // // } - // // } - // // // passTrackPlugin.map_setCenterDevice(bits); - // // setState(() { - // // if (fileHandle.pointData.isNotEmpty) { - // // maxLength = fileHandle.pointData.length; - // // // _value = maxLength; - // // _rangevalues = SfRangeValues(0.0, maxLength.toDouble()); - // // } - // // }); - // }); - // } - - Future initPlatformState() async { - // String platformVersion; - // try { - // platformVersion = await passTrackPlugin.getPlatformVersion() ?? - // 'Unknown platform version'; - // } on PlatformException { - // platformVersion = 'Failed to get platform version.'; - // } - // await passTrackPlugin.create(sWidth, sWidth); - // fileHandle.textureId = await passTrackPlugin.getTextureId() ?? -1; - // log("textureId: ${fileHandle.textureId}"); - - // if (!mounted) return; - - // setState(() { - // platformVersion = platformVersion; - // }); - } + PassTrack({super.key, this.currentPoint}); @override Widget build(BuildContext context) { - return OrientationBuilder(builder: (context, orientation) { - return Stack( - children: [ - ScenceMapView( - onUpdate: (Offset center, double scale, double rotation) { - log("center:$center scale:$scale rotation:$rotation"); - }, - forGroundPainter: appcontroller.currentIndex.value == 1 - ? BorderPainter(controller) - : null, - onUpdatePilePoint: (RecordEntity? selectedPilePoint, double scale, - double rotation) { - log( - "selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation"); - controller.selectedPilePoint = selectedPilePoint; - aimcontroller.selectedPilePoint = selectedPilePoint; - }, - children: const [], - ), - const SightGview(), - const RealDataShow(), - ], - ); + if (currentPoint == null) { + controller.date.value = DateFormat('yyyy-MM-dd').format(DateTime.now()); + } else { + controller.date.value = + DateFormat('yyyy-MM-dd').format(currentPoint!.startTime); + } + controller.currentPoint = currentPoint; + controller.loadData(); + + return Obx(() { + controller.updateCount.value; + CustomPainter? forGroundPainter = appcontroller.currentIndex.value == 1 + ? BorderPainter( + controller, + ) + : null; + return OrientationBuilder(builder: (context, orientation) { + return Stack( + children: [ + ScenceMapView( + onUpdate: (Offset center, double scale, double rotation) { + log("center:$center scale:$scale rotation:$rotation"); + }, + forGroundPainter: forGroundPainter, + onUpdatePilePoint: (RecordEntity? selectedPilePoint, double scale, + double rotation) { + log("selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation"); + controller.selectedPilePoint.value = selectedPilePoint; + aimcontroller.selectedPilePoint = selectedPilePoint; + controller.updateCount.value++; + }, + children: const [], + ), + const SightGview(), + const RealDataShow(), + ], + ); + }); }); } } @@ -139,9 +104,9 @@ class BorderPainter extends CustomPainter { final paint = Paint() ..color = Colors.red ..strokeWidth = 3.0; - if (controller.selectedPilePoint != null) { - var offset = Offset( - controller.selectedPilePoint!.x, controller.selectedPilePoint!.y); + RecordEntity? selectedPilePoint = controller.selectedPilePoint.value; + if (selectedPilePoint != null) { + var offset = Offset(selectedPilePoint.x, selectedPilePoint.y); Offset screenPos = mapcontroller.xy2Screen0(offset); // 计算圆的直径 @@ -163,40 +128,18 @@ class BorderPainter extends CustomPainter { } else if (mapcontroller.scale >= 10) { cornerLength = 0; } + paint.style = PaintingStyle.stroke; + canvas.drawRect(rect, paint); - // 左上角 - canvas.drawLine( - rect.topLeft, rect.topLeft + Offset(cornerLength, 0), paint); - canvas.drawLine( - rect.topLeft, rect.topLeft + Offset(0, cornerLength), paint); - - // 右上角 - canvas.drawLine( - rect.topRight, rect.topRight + Offset(-cornerLength, 0), paint); - canvas.drawLine( - rect.topRight, rect.topRight + Offset(0, cornerLength), paint); - - // 左下角 - canvas.drawLine( - rect.bottomLeft, rect.bottomLeft + Offset(cornerLength, 0), paint); - canvas.drawLine( - rect.bottomLeft, rect.bottomLeft + Offset(0, -cornerLength), paint); - - // 右下角 - canvas.drawLine( - rect.bottomRight, rect.bottomRight + Offset(-cornerLength, 0), paint); - canvas.drawLine( - rect.bottomRight, rect.bottomRight + Offset(0, -cornerLength), paint); - - Offset center = Offset(gnsscontroller.device.x, gnsscontroller.device.y); + Offset center = + Offset(gnsscontroller.device.x.value, gnsscontroller.device.y.value); Offset pilerCenter = mapcontroller.xy2Screen0(center); //绘制虚线 if (mapcontroller.deviceList.isNotEmpty) { Paint dashedPaint = Paint() ..color = Colors.red ..strokeWidth = 3.5; - var offset = Offset( - controller.selectedPilePoint!.x, controller.selectedPilePoint!.y); + var offset = Offset(selectedPilePoint.x, selectedPilePoint.y); Offset screenPos = mapcontroller.xy2Screen0(offset); drawDashedLine(canvas, pilerCenter, screenPos, dashedPaint); diff --git a/lib/pages/real/component/chart.dart b/lib/pages/real/component/chart.dart index 245edc7..a626717 100644 --- a/lib/pages/real/component/chart.dart +++ b/lib/pages/real/component/chart.dart @@ -5,11 +5,10 @@ import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:intl/intl.dart'; - import '../../../service/base.dart'; +import '../../setting/project/model.dart'; import '../process.dart'; - class ProcessChart extends StatefulWidget { final int pileId; const ProcessChart({super.key, required this.pileId}); @@ -35,8 +34,14 @@ class _ProcessChartState extends State { void fetchData() async { try { SchedulerBinding.instance.addPostFrameCallback((_) async { + ProjectModel project = settingController.currentProject.value!; + String projType = settingController.projType; //获取点的数据 - List detailCdate = await GetServices().getProcessData(widget.pileId); + List detailCdate = await services.getProcessData( + widget.pileId, + project.projCode, + projType, + ); setState(() { double ten1Max = 0; @@ -278,7 +283,7 @@ class ChartData { int intValue = (value).ceil(); if (intValue % (2 * radtio) == 0 && intValue <= maxYR) { text = (intValue / radtio).floor().toString(); - if (maxYR - intValue < 2 * radtio) { + if (maxYR - intValue < 2 * radtio) { text = "深度(m)"; } } else { diff --git a/lib/pages/real/process.dart b/lib/pages/real/process.dart index fbe0221..764a0c5 100644 --- a/lib/pages/real/process.dart +++ b/lib/pages/real/process.dart @@ -1,6 +1,5 @@ import 'dart:core'; - class ProcessEntity { double speed; double depth; @@ -65,3 +64,44 @@ class ProcessEntity { ); } } + +// class ProcessEntity { +// // String recvTime; +// double? azimuth; +// double alt = 0; +// double lng = 0; +// double lat = 0; +// int tp_id; +// int utc; +// int tid; +// int? id; +// int times; +// // impact_force +// // distance; +// // pith +// ProcessEntity( +// {this.times = 0, + +// // required this.recvTime, +// this.azimuth, +// this.alt = 0, +// this.lng = 0, +// this.lat = 0, +// required this.tp_id, +// required this.utc, +// required this.tid, +// this.id}); +// factory ProcessEntity.fromJson(Map json) { +// return ProcessEntity( +// // recvTime: json["recv_time"] ?? DateTime.now(), +// // azimuth: (json["azimuth"] ?? "0").toDouble(), +// alt: (json["ALT"] ?? "0").toDouble(), +// lng: (json["LNG"] ?? "0").toDouble(), +// lat: (json["LAT"] ?? "0").toDouble(), +// tp_id: json["tp_id"], +// utc: json["UTC"], +// tid: json['tid'], +// id: json["id"], +// ); +// } +// } diff --git a/lib/pages/real/real_data_card.dart b/lib/pages/real/real_data_card.dart index 2ab957f..206f734 100644 --- a/lib/pages/real/real_data_card.dart +++ b/lib/pages/real/real_data_card.dart @@ -122,24 +122,29 @@ class RealDataShow extends StatelessWidget { // final orientation = MediaQuery.of(context).orientation; // bool isPortrait = Orientation.portrait == orientation ? true : false; // 创建数据项列表 + // pile_cm + // List dataItems = [ + // DataItem( + // "速度(m/min):", + // () => realController.speed.abs() >= 100 + // ? realController.speed.toStringAsFixed(1) + // : realController.speed.toStringAsFixed(2)), + // DataItem("时间(min:s):", () => realController.time.value), + // DataItem("深度(m):", () => realController.depth.toStringAsFixed(2)), + // DataItem("1#瞬时流量(L/min):", + // () => realController.subtotalFlow1.toStringAsFixed(2)), + // DataItem("2#瞬时流量(L/min):", + // () => realController.subtotalFlow2.toStringAsFixed(2)), + // DataItem( + // "1#累计流量(L):", () => realController.totalFlow1.toStringAsFixed(2)), + // DataItem( + // "2#累计流量(L):", () => realController.totalFlow2.toStringAsFixed(2)), + // ]; + // hydraulic_tamping List dataItems = [ - DataItem( - "速度(m/min):", - () => realController.speed.abs() >= 100 - ? realController.speed.toStringAsFixed(1) - : realController.speed.toStringAsFixed(2)), DataItem("时间(min:s):", () => realController.time.value), - DataItem("深度(m):", () => realController.depth.toStringAsFixed(2)), - DataItem("1#瞬时流量(L/min):", - () => realController.subtotalFlow1.toStringAsFixed(2)), - DataItem("2#瞬时流量(L/min):", - () => realController.subtotalFlow2.toStringAsFixed(2)), - DataItem( - "1#累计流量(L):", () => realController.totalFlow1.toStringAsFixed(2)), - DataItem( - "2#累计流量(L):", () => realController.totalFlow2.toStringAsFixed(2)), + // DataItem("夯击次数:", () => realController.times.value) ]; - // 返回数据项的列表 return dataItems.map((item) { return Padding( diff --git a/lib/pages/setting/child_pages/XyChange/xy_change.dart b/lib/pages/setting/child_pages/XyChange/xy_change.dart index 1157b0a..5a9ec4e 100644 --- a/lib/pages/setting/child_pages/XyChange/xy_change.dart +++ b/lib/pages/setting/child_pages/XyChange/xy_change.dart @@ -6,6 +6,7 @@ import 'package:get/get.dart'; import '../../../../service/base.dart'; import '../../../../service/pile/device_type.dart'; +import '../../project/model.dart'; import '../connect/config/blue_params.dart'; import '../connect/controllers/blue_tooth_controller.dart'; import 'connect.dart'; @@ -45,7 +46,7 @@ BlueSetting blueSetting = BlueSetting(); // void initState() { // super.initState(); // SchedulerBinding.instance.addPostFrameCallback((_) async { -// List coordTransmap = await GetServices().getCoordTrans(); +// List coordTransmap = await services.getCoordTrans(); // if (coordTransmap.isNotEmpty) { // var mianBelt = // coordTransmap.firstWhere((element) => element['belt'] == 'main'); @@ -498,7 +499,17 @@ class XYChangeController extends GetxController { void onInit() { super.onInit(); SchedulerBinding.instance.addPostFrameCallback((_) async { - List coordTransmap = await GetServices().getCoordTrans(); + ProjectModel? project = settingController.currentProject.value; + project ??= settingController.getproject(); + if (project == null) { + return; + } + + String projType = settingController.projType; + List coordTransmap = await services.getCoordTrans( + projType, + project.projCode, + ); if (coordTransmap.isNotEmpty) { var mianBelt = coordTransmap.firstWhere((element) => element['belt'] == 'main'); diff --git a/lib/pages/setting/child_pages/antenna/antenna_setting.dart b/lib/pages/setting/child_pages/antenna/antenna_setting.dart index 13ef13c..dc13872 100644 --- a/lib/pages/setting/child_pages/antenna/antenna_setting.dart +++ b/lib/pages/setting/child_pages/antenna/antenna_setting.dart @@ -2,11 +2,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../XyChange/connect.dart'; -import '../connect/config/blue_params.dart'; import '../connect/controllers/blue_tooth_controller.dart'; final BlueToothController blueToothController = Get.put(BlueToothController()); -BlueSetting blueSetting = BlueSetting(); class AntennaSetting extends GetView { const AntennaSetting({super.key}); diff --git a/lib/pages/setting/child_pages/persondetail/person_details.dart b/lib/pages/setting/child_pages/persondetail/person_details.dart index ea0b065..3909cc8 100644 --- a/lib/pages/setting/child_pages/persondetail/person_details.dart +++ b/lib/pages/setting/child_pages/persondetail/person_details.dart @@ -24,7 +24,7 @@ class _PersonDetailsState extends State { SchedulerBinding.instance.addPostFrameCallback((_) async { UserModel? getUser = UserController().getUser(); if (getUser == null) { - var person = await GetServices().getPerson(); + var person = await services.getPerson(); UserController().setUser(person); user = UserModel.fromJson(person); } else {} diff --git a/lib/pages/setting/project/model.dart b/lib/pages/setting/project/model.dart new file mode 100644 index 0000000..99d7b38 --- /dev/null +++ b/lib/pages/setting/project/model.dart @@ -0,0 +1,35 @@ +class ProjectModel { + String? groups; + int id; + String name; + String? options; + String orgCode; + String projCode; + ProjectModel( + {this.groups, + required this.id, + required this.name, + this.options, + required this.orgCode, + required this.projCode}); + + factory ProjectModel.fromJson(Map json) { + return ProjectModel( + groups: json['groups'], + id: json['id'], + name: json['name'], + options: json['options'], + orgCode: json['org_code'], + projCode: json['proj_code']); + } + Map toJson() { + return { + 'groups': groups, + 'id': id, + 'name': name, + 'options': options, + 'org_code': orgCode, + 'proj_code': projCode + }; + } +} diff --git a/lib/pages/setting/project/view.dart b/lib/pages/setting/project/view.dart new file mode 100644 index 0000000..501b8be --- /dev/null +++ b/lib/pages/setting/project/view.dart @@ -0,0 +1,169 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:scence_map/controllers/controller.dart'; +import '../setting_controller.dart'; +import 'model.dart'; + +final SettingController sc = Get.find(); + +class ProjectView extends GetView { + const ProjectView({super.key}); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("项目设置"), + ), + body: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 5), + child: Column( + children: [ + Row( + children: [ + const Text("项目名称:"), + Expanded( + child: DropdownProject( + controller: controller, + ), + ) + ], + ), + const Divider(), + Row( + children: [ + const Text("设备列表:"), + Expanded( + child: DropdownDevice( + controller: controller, + ), + ) + ], + ), + ], + )), + ); + } +} + +class DropdownProject extends StatefulWidget { + final SettingController controller; + const DropdownProject({super.key, required this.controller}); + + @override + DropdownProjectState createState() => DropdownProjectState(); +} + +class DropdownProjectState extends State { + @override + Widget build(BuildContext context) { + SettingController controller = widget.controller; + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + PopupMenuButton( + offset: const Offset(0, 40), + onSelected: (String selectedValue) { + setState(() { + for (var value in controller.projectList) { + if (value.projCode == selectedValue) { + // controller.currentProject.update((p) { + // controller.currentProject.value = value; + controller.updateProject(value); + // }); + break; + } + } + }); + }, + itemBuilder: (BuildContext context) { + return controller.projectList + .map>((ProjectModel value) { + return PopupMenuItem( + value: value.projCode, + child: Text(value.name), + ); + }).toList(); + }, + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 5.0, horizontal: 10.0), // 设置按钮的内边距 + decoration: BoxDecoration( + border: Border.all(color: Colors.grey), + borderRadius: BorderRadius.circular(5.0), + ), + child: Obx(() { + String text = controller.currentProject.value?.name ?? '请选择一个项目'; + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(text), + const Icon(Icons.arrow_drop_down), + ], + ); + }), + ), + ), + ], + ); + } +} + +class DropdownDevice extends StatefulWidget { + final SettingController controller; + const DropdownDevice({super.key, required this.controller}); + + @override + DropdownDeviceState createState() => DropdownDeviceState(); +} + +class DropdownDeviceState extends State { + @override + Widget build(BuildContext context) { + SettingController controller = widget.controller; + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + PopupMenuButton( + offset: const Offset(0, 40), + onSelected: (String selectedValue) { + setState(() { + for (var value in controller.deviceList) { + if (value.tid == int.parse(selectedValue)) { + controller.currentDevice.value = value; + break; + } + } + }); + }, + itemBuilder: (BuildContext context) { + return controller.deviceList + .map>((DeviceItem value) { + return PopupMenuItem( + value: value.tid.toString(), + child: Text(value.name), + ); + }).toList(); + }, + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 5.0, horizontal: 10.0), // 设置按钮的内边距 + decoration: BoxDecoration( + border: Border.all(color: Colors.grey), + borderRadius: BorderRadius.circular(5.0), + ), + child: Obx(() { + String text = controller.currentDevice.value?.name ?? '请选择一个设备'; + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(text), + const Icon(Icons.arrow_drop_down), + ], + ); + }), + ), + ), + ], + ); + } +} diff --git a/lib/pages/setting/setting_controller.dart b/lib/pages/setting/setting_controller.dart new file mode 100644 index 0000000..03c8ab0 --- /dev/null +++ b/lib/pages/setting/setting_controller.dart @@ -0,0 +1,115 @@ +import 'package:cpnav/pages/pass_track/controller.dart'; +import 'package:cpnav/pages/setting/project/model.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:scence_map/controllers/controller.dart'; + +import '../../models/user.dart'; +import '../../service/base.dart'; +import '../../service/user/loginprefs.dart'; + +LoginPrefs loginPrefs = LoginPrefs(); +ScenceMapController mapController = Get.find(); +PassTrackController passTrackController = Get.find(); + +final box = GetStorage(); // 实例化 GetStorage + +class SettingController extends GetxController { + String projType = "hydraulic_tamping"; + List projectList = []; + Rx currentProject = Rx(null); + List deviceList = []; + Rx currentDevice = Rx(null); + var updateCount = 0.obs; + GetServices services = GetServices(); + var isInitialized = false; + // @override + // void onInit() async { + // super.onInit(); + + // } + + init() async { + isInitialized = false; + UserModel? getUser = UserController().getUser(); + // services.projType = projType; + if (getUser == null) { + Map? person = await services.getPerson(); + if (person == null || person.isEmpty) { + isInitialized = true; + return; + } + UserController().setUser(person); + getUser = UserModel.fromJson(person); + } + // services.org_code = getUser.orgCode; + + List projList = await services.getproject(getUser.orgCode, projType); + for (var element in projList) { + projectList.add(ProjectModel.fromJson(element)); + } + currentProject.value = getproject(); + currentDevice.value = getdevice(); + + if (currentProject.value == null && projectList.isNotEmpty) { + currentProject.value = projectList[0]; + setProject(currentProject.value!.toJson()); + // services.projCode = currentProject.value!.projCode; + await getBindService(services); + } + + isInitialized = true; + } + + getBindService(GetServices service) async { + deviceList.length = 0; + List list = + await service.getDeviceBind(projType, currentProject.value!.projCode); + mapController.deviceList = {}; + for (var element in list) { + DeviceItem device = DeviceItem.fromJson(element); + if (device.type != "rtk_base") { + deviceList.add(device); + mapController.addDevice(device); + } + } + if (deviceList.isNotEmpty) { + currentDevice.value = deviceList[0]; + } + setDevice(currentDevice.value!.toJson()); + } + + updateProject(ProjectModel val) async { + currentProject.value = val; + // services.projCode = val.projCode; + setProject(currentProject.value!.toJson()); + passTrackController.loadSideLine(); + await getBindService(services); + updateCount.value++; + } + + void setProject(Map data) { + box.write('project', data); + update(); + } + + void setDevice(Map data) { + box.write('device', data); + } + + ProjectModel? getproject() { + final p = box.read("project"); + if (p != null) { + return ProjectModel.fromJson(p); + } + return null; + } + + DeviceItem? getdevice() { + final d = box.read("device"); + if (d != null) { + return DeviceItem.fromJson(d); + } + return null; + } +} diff --git a/lib/pages/setting/setting_page.dart b/lib/pages/setting/setting_page.dart index 7afdc96..4a861ef 100644 --- a/lib/pages/setting/setting_page.dart +++ b/lib/pages/setting/setting_page.dart @@ -4,14 +4,15 @@ import 'package:get/get.dart'; import 'child_pages/XyChange/xy_change.dart'; import 'child_pages/antenna/antenna_setting.dart'; -import 'child_pages/connect/bluetooth_page.dart'; +// import 'child_pages/connect/bluetooth_page.dart'; import 'child_pages/persondetail/person_details.dart'; -import 'child_pages/connect/wifi_page.dart'; +// import 'child_pages/connect/wifi_page.dart'; import 'component/list_view_item.dart'; -import 'child_pages/connect/config/app_config.dart'; -import 'child_pages/connect/config/connect_type.dart'; +// import 'child_pages/connect/config/app_config.dart'; +// import 'child_pages/connect/config/connect_type.dart'; import 'child_pages/connect/controllers/blue_tooth_controller.dart'; +import 'project/view.dart'; //字体 TextStyle textStyle = const TextStyle(fontSize: 15); @@ -43,69 +44,73 @@ class _SettingPortraitState extends State { void initState() { super.initState(); items = [ - ListItem('连接设置', Icons.change_circle_outlined, () { - showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - title: const Text("选择连接方式"), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - ListTile( - title: const Text("蓝牙连接"), - onTap: () { - // items[0].text = "连接设置(蓝牙)"; - AppConfig.updateConfig("connectType", "bluetooth"); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const BlueTooth()), - ); - }, - ), - ListTile( - title: const Text("WiFi连接"), - onTap: () { - blueToothController.connectedType.value = - ConnectType.wifi; - AppConfig.updateConfig("connectType", "wifi"); - // items[0].text = "连接设置(WiFi)"; + // ListItem('连接设置', Icons.change_circle_outlined, () { + // showDialog( + // context: context, + // builder: (BuildContext context) { + // return AlertDialog( + // title: const Text("选择连接方式"), + // content: Column( + // mainAxisSize: MainAxisSize.min, + // children: [ + // ListTile( + // title: const Text("蓝牙连接"), + // onTap: () { + // // items[0].text = "连接设置(蓝牙)"; + // AppConfig.updateConfig("connectType", "bluetooth"); + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => const BlueTooth()), + // ); + // }, + // ), + // ListTile( + // title: const Text("WiFi连接"), + // onTap: () { + // blueToothController.connectedType.value = + // ConnectType.wifi; + // AppConfig.updateConfig("connectType", "wifi"); + // // items[0].text = "连接设置(WiFi)"; - // Connectivity() - // .checkConnectivity() - // .then((connectivityResult) { - // if (connectivityResult != ConnectivityResult.wifi) { - // OpenSettings.openWIFISetting(); - // } else { + // // Connectivity() + // // .checkConnectivity() + // // .then((connectivityResult) { + // // if (connectivityResult != ConnectivityResult.wifi) { + // // OpenSettings.openWIFISetting(); + // // } else { - // } - // }); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const WifiPage()), - ); - }, - ), - ], - ), - ); - }, - ); - }), + // // } + // // }); + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => const WifiPage()), + // ); + // }, + // ), + // ], + // ), + // ); + // }, + // ); + // }), // ListItem('规划点', Icons.download_outlined, () { // Navigator.push(context, // MaterialPageRoute(builder: (context) => const PlanPoint())); // }), - ListItem('坐标转换', Icons.settings, () { - Navigator.push(context, - MaterialPageRoute(builder: (context) => XyChangeView())); + ListItem('坐标转换', Icons.check_box_outlined, () { + Navigator.push( + context, MaterialPageRoute(builder: (context) => XyChangeView())); }), ListItem('个人中心', Icons.person_outline_outlined, () { Navigator.push(context, MaterialPageRoute(builder: (context) => const PersonDetails())); }), + ListItem('项目相关', Icons.insert_drive_file_outlined, () { + Navigator.push(context, + MaterialPageRoute(builder: (context) => const ProjectView())); + }), ListItem('天线位置设置', Icons.settings_input_antenna, () { Navigator.push(context, MaterialPageRoute(builder: (context) => const AntennaSetting())); diff --git a/lib/pages/task/info.dart b/lib/pages/task/info.dart new file mode 100644 index 0000000..a521dda --- /dev/null +++ b/lib/pages/task/info.dart @@ -0,0 +1,217 @@ +import 'package:cpnav/main.dart'; +import 'package:cpnav/pages/task/model.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'pile/pileNav/view.dart'; +import 'taskcontroller.dart'; + +// ignore: must_be_immutable +class TaskItemPage extends GetWidget { + TaskItem taskInfo; + TaskItemPage({super.key, required this.taskInfo}); + + toTaskView(context, TaskItem taskInfo) { + controller.currentask.value = taskInfo; + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const TaskView()), + ); + } + + @override + Widget build(BuildContext context) { + return Container( + // width: size.width * 0.8, + height: 85, + decoration: BoxDecoration( + border: Border.all(color: Colors.black), + borderRadius: BorderRadius.circular(10), + ), + margin: const EdgeInsets.only(bottom: 5), + clipBehavior: Clip.hardEdge, + child: Obx(() { + Color color = controller.currentask.value.utc == taskInfo.utc + ? Colors.green + : const Color.fromARGB(164, 75, 73, 73); + IconData icon = controller.currentask.value.utc == taskInfo.utc + ? Icons.task_rounded + : Icons.task_outlined; + if (controller.currentask.value.utc == taskInfo.utc) { + taskInfo = controller.currentask.value; + } + int workTotal = taskInfo.workTotal; + int listLength = taskInfo.list.length; + TextEditingController taskController = + TextEditingController(text: workTotal.toString()); + TextEditingController totalController = + TextEditingController(text: listLength.toString()); + Size size = MediaQuery.of(context).size; + return Stack( + children: [ + Row(children: [ + const SizedBox(width: 16), + IconButton( + onPressed: () { + controller.currentask.value = taskInfo; + appcontroller.currentIndex.value = 1; + }, + icon: Icon(icon, size: 50, color: color)), + const SizedBox(width: 16), + SizedBox( + width: size.width * 0.4, + child: InkWell( + onTap: () { + controller.currentask.value = taskInfo; + appcontroller.currentIndex.value = 1; + // toTaskView(context); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // SizedBox(height: 5), + Text( + taskInfo.name, + style: const TextStyle( + fontSize: 24, fontWeight: FontWeight.bold), + ), + Row(children: [ + Expanded( + child: TextField( + readOnly: true, + keyboardType: TextInputType.emailAddress, + controller: taskController, + decoration: const InputDecoration( + prefixText: '完成数量:', + border: InputBorder.none, + labelStyle: TextStyle( + fontSize: 16, + color: Color.fromARGB(164, 75, 73, 73)), + ), + ), + ), + const SizedBox(width: 5), + Expanded( + child: TextField( + readOnly: true, + controller: totalController, + keyboardType: TextInputType.emailAddress, + decoration: const InputDecoration( + prefixText: "桩点数:", + hintText: "0", + // prefixIcon: Icon(Icons.email), + border: InputBorder.none, //隐藏下划线 + labelStyle: TextStyle( + fontSize: 16, + color: Color.fromARGB(164, 75, 73, 73)), + ), + ), + ), + ]), + ], + )), + ), + // const SizedBox(width: 150), + InkWell( + onTap: () { + toTaskView(context, taskInfo); + }, + child: Container( + width: size.width * .3, + height: 80, + alignment: Alignment.center, + child: const Text( + "编辑桩点 >>>", + style: TextStyle( + fontSize: 14, + color: Color.fromARGB(164, 75, 73, 73)), + )), + ), + + InkWell( + onTap: () => editDialog(context, taskInfo), + child: Container( + width: size.width * .1, + height: 80, + alignment: Alignment.center, + child: const Text( + '编辑名称', + style: TextStyle( + fontSize: 14, color: Color.fromARGB(164, 75, 73, 73)), + ), + ), + ), + ]), + Positioned( + top: -3, // 调整文本的位置 + left: -37, // 调整文本的位置 + child: Transform.rotate( + angle: -40 * 3.14159 / 180, // 旋转 45° + child: Container( + width: 100, + padding: const EdgeInsets.all(4), // 添加一些内边距 + color: Colors.blue, + alignment: Alignment.bottomCenter, + // 背景颜色 + child: Text( + taskInfo.originLabel, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 16, color: Colors.white), // 设置字体颜色为白色 + ), + ), + ), + ), + ], + ); + })); + } + + editDialog(context, TaskItem info) { + TextEditingController taskController = + TextEditingController(text: info.name.toString()); + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text("新增任务"), + content: SizedBox( + height: 100, + child: Column( + children: [ + TextField( + keyboardType: TextInputType.emailAddress, + controller: taskController, + decoration: const InputDecoration( + hintText: '任务名称', + prefixText: '任务名称:', + border: InputBorder.none, + labelStyle: TextStyle( + fontSize: 16, color: Color.fromARGB(164, 75, 73, 73)), + ), + ) + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); // 关闭弹窗 + }, + child: const Text("取消"), + ), + TextButton( + onPressed: () async { + info.name = taskController.text.trim(); + await controller.editTask(info); + // ignore: use_build_context_synchronously + Navigator.of(context).pop(); + controller.updateCount++; + }, + child: const Text("确定"), + ), + ], + ); + }, + ); + } +} diff --git a/lib/pages/task/model.dart b/lib/pages/task/model.dart new file mode 100644 index 0000000..8d06f08 --- /dev/null +++ b/lib/pages/task/model.dart @@ -0,0 +1,87 @@ +import 'package:scence_map/controllers/controller.dart'; + +class TaskItem { + int id; + int utc; + String name; + int workTotal; + List list; + String originLabel; + CenterPileInfo centerPileInfo; //桩点生成中心设置 + + TaskItem({ + required this.id, + required this.utc, //创建时间 + required this.name, //任务名称 + required this.workTotal, + required this.list, + required this.originLabel, //任务来源标签(本地 平台) + required this.centerPileInfo, + }); + factory TaskItem.fromJson(Map data) { + return TaskItem( + id: data['id'], + utc: data['utc'], + name: data['name'], + workTotal: data['workTotal'], + originLabel: data['originLabel'], + centerPileInfo: CenterPileInfo.fromJson(data['centerPileInfo']), + list: (data['list'] as List) + .map((item) => PilePoint.fromJson(item)) + .toList(), + ); + } + Map toJson() { + return { + 'id': id, + 'name': name, + 'list': list.map((item) => item.toJson()).toList(), + 'utc': utc, + 'originLabel': originLabel, + 'workTotal': workTotal, + 'centerPileInfo': centerPileInfo.toJson(), + }; + } +} + +class CenterPileInfo { + double x; + double y; + // double direction; + double space; + double pileWidth; + double angle; + List distances; //桩点距离列表 + CenterPileInfo({ + required this.x, + required this.y, + // required this.direction, + this.angle = 0, + this.space = 5, + this.pileWidth = 400, + this.distances = const [5, 5, 5, 5], //上右下左(tips:和中心点的距离, 单位:米) + }); + factory CenterPileInfo.fromJson(Map data) { + return CenterPileInfo( + x: data['x'], + y: data['y'], + // direction: data['direction'], + space: data['space'], + pileWidth: data['pileWidth'], + angle: data['angle'], + distances: List.from( + data['distances'].map((item) => (item ?? 10).toDouble())), + ); + } + Map toJson() { + return { + 'x': x, + 'y': y, + // 'direction': direction, + 'space': space, + 'pileWidth': pileWidth, + 'angle': angle, + 'distances': distances, + }; + } +} diff --git a/lib/pages/task/pile/pileGenerateCard/pile_gener_controller.dart b/lib/pages/task/pile/pileGenerateCard/pile_gener_controller.dart deleted file mode 100644 index c5a7b99..0000000 --- a/lib/pages/task/pile/pileGenerateCard/pile_gener_controller.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:get/get.dart'; - -class PileGenerController extends GetxController { - var isPileCardVisible = false.obs; // 控制生成桩点的卡片是否可见 - var isRealViewCardVisible = false.obs; // 控制生成桩点的卡片是否可见 - - @override - void onInit() { - super.onInit(); - // 监听 isRealViewCardVisible 的变化 - - ever(isRealViewCardVisible, (bool isVisible) { - if (isVisible) { - isPileCardVisible.value = false; - } - }); - ever(isPileCardVisible, (bool isVisible) { - if (isVisible) { - isRealViewCardVisible.value = false; - } - }); - } -} diff --git a/lib/pages/task/pile/pileGenerateCard/pile_generate.dart b/lib/pages/task/pile/pileGenerateCard/pile_generate.dart deleted file mode 100644 index 9d54b0a..0000000 --- a/lib/pages/task/pile/pileGenerateCard/pile_generate.dart +++ /dev/null @@ -1,356 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:get/get.dart'; -import 'package:scence_map/controllers/controller.dart'; -import 'package:scence_map/controllers/plum_controller.dart'; - -import '../../../../service/pile/device_type.dart'; -import '../../../../service/pile/input.dart'; -import '../../../../service/pile/public_widget.dart'; -import '../../task_page.dart'; -import '../../taskcontroller.dart'; -import 'pile_gener_controller.dart'; - -final ScenceMapController mapController = Get.find(); -final PlumDataController controller = Get.find(); -final TaskController taskcontroller = Get.put(TaskController()); - -class PileGenerate extends StatefulWidget { - const PileGenerate({super.key}); - - @override - PileGenerateState createState() => PileGenerateState(); -} - -class PileGenerateState extends State { - late StepDialogManager _showStepDialog; - - @override - void initState() { - super.initState(); - _showStepDialog = StepDialogManager(context); - } - - @override - Widget build(BuildContext context) { - double titleTextWidth = 90; - double inputLength = 120; - FocusNode xFocus = FocusNode(); - FocusNode yFocus = FocusNode(); - FocusNode directionFocus = FocusNode(); - FocusNode pileSpaceFocus = FocusNode(); - FocusNode pileWidthFocus = FocusNode(); - DeviceType deviceType = getDeviceType(context); - double fontSize = 16; - if (deviceType == DeviceType.mobile) { - fontSize = 16; - } else { - fontSize = 20; - } - double centerPointX = controller.centerXY.value.dx; - double centerPointY = controller.centerXY.value.dy; - - final size = MediaQuery.of(context).size; - return OrientationBuilder(builder: ((context, orientation) { - return Scaffold( - appBar: AppBar( - title: const Text("桩点生成"), - toolbarHeight: 30, - leading: IconButton( - icon: const Icon(Icons.close), - onPressed: () { - setState(() { - pilecontroller.isPileCardVisible.value = false; - pilecontroller.isRealViewCardVisible.value = false; - }); - }, - ), - ), - body: SizedBox( - height: size.height, - child: Stack( - children: [ - SingleChildScrollView( - child: AlignWrapWidget( - children: [ - Row( - children: [ - const Text('地图显示:'), - Obx(() => Switch( - value: controller.isMap.value, - onChanged: ((value) { - controller.isMap.value = !controller.isMap.value; - }))), - ], - ), - AlignWrapWidget( - children: [ - ElevatedButton( - child: const Text("夯锤坐标"), - onPressed: () => {controller.isDirect.value = false}, - ), - const SizedBox( - width: 10, - ), - ElevatedButton( - child: const Text("桩点坐标"), - onPressed: () => { - controller.isGenerate.value = true, - controller.checkValue.value = "checkPile", - controller.isDirect.value = false, - pilecontroller.isPileCardVisible.value = false, - if (!taskcontroller.isDialogShown[1]) - { - _showStepDialog.showStepDialog(1), - taskcontroller.isDialogShown[1] = true - } - }), - const SizedBox( - width: 10, - ), - ElevatedButton( - child: const Text("方向设置"), - onPressed: () => { - controller.isGenerate.value = true, - controller.checkValue.value = "checkDirection", - controller.isDirect.value = true, - controller.centerXY.value = - Offset(centerPointX, centerPointY), - pilecontroller.isPileCardVisible.value = false, - if (!taskcontroller.isDialogShown[3]) - { - _showStepDialog.showStepDialog(3), - taskcontroller.isDialogShown[3] = true - } - }), - ], - ), - Row(children: [ - FixedWidthTextWidget(width: titleTextWidth, text: "X:"), - inputText( - inputLength: inputLength, - value: centerPointX.toString(), - fontsize: fontSize, - focusNode: yFocus, - onChanged: (value) => value.isNotEmpty - ? centerPointY = double.parse(value) - : '') - ]), - Row(children: [ - FixedWidthTextWidget(width: titleTextWidth, text: "Y:"), - inputText( - inputLength: inputLength, - value: centerPointY.toString(), - fontsize: fontSize, - focusNode: xFocus, - onChanged: (value) => value.isNotEmpty - ? centerPointX = double.parse(value) - : '') - ]), - Row(children: [ - FixedWidthTextWidget(width: titleTextWidth, text: "方向(°):"), - inputText( - inputLength: inputLength, - value: controller.direction.toString(), - fontsize: fontSize, - focusNode: directionFocus, - keyboardType: 0, - onChanged: (value) { - if (value.isNotEmpty) { - controller.direction.value = double.parse(value); - // bug 值修改后 绘制没有变化 - controller.angle.value = - controller.direction.value * pi / 180; - } - }) - ]), - Row(children: [ - FixedWidthTextWidget( - width: titleTextWidth + 10, text: "夯点间距(m):"), - inputText( - inputLength: inputLength - 10, - fontsize: fontSize, - value: controller.space.toString(), - focusNode: pileSpaceFocus, - onChanged: (value) => { - value.isNotEmpty - ? controller.space.value = double.parse(value) - : '', - }) - ]), - Row(children: [ - FixedWidthTextWidget( - width: titleTextWidth + 10, text: "宽度(m):"), - inputText( - inputLength: inputLength - 10, - fontsize: fontSize, - value: controller.pileWidth.toString(), - focusNode: pileWidthFocus, - onChanged: (value) => { - value.isNotEmpty - ? controller.pileWidth.value = - double.parse(value) - : '', - }) - ]), - Row(children: [ - const Icon( - Icons.tips_and_updates_outlined, - color: Colors.red, - ), - Text( - controller.isPileId.value - ? '选中桩点:${controller.checkName.value}' - : ' 未选中桩点', - style: TextStyle( - color: !controller.isPileId.value - ? Colors.red - : Colors.black), - ) - ]), - ], - )), - Positioned( - bottom: 10, - child: Row( - children: [ - TextButton( - child: const Text('取消'), - onPressed: () { - controller.isGenerate.value = false; - controller.isDirect.value = false; - controller.isSave.value = false; - // 执行取消的逻辑 - }, - ), - TextButton( - child: const Text('确定'), - onPressed: () { - // 执行确定的逻辑 - var dx = (controller.canvasSize.width) / 2; - var dy = (controller.canvasSize.height) / 2; - var rotation = mapController.rotation.value; - for (int i = 0; i < controller.plumList.length; i++) { - Offset item = controller.plumList[i]; - - var dx1 = ((item.dx - dx) * cos(rotation) + - (item.dy - dy) * sin(rotation)); - var dy1 = -(item.dx - dx) * sin(rotation) + - (item.dy - dy) * cos(rotation); - - Offset xy = mapController.screenCenter2xy(dx1, dy1); - PilePoint pilePoint = PilePoint( - x: (xy.dx * 1000).roundToDouble() / 1000, - y: (xy.dy * 1000).roundToDouble() / 1000, - times: 0, - id: i + 1, - radius: 0.3); - mapController.pilePoints.add(pilePoint); - } - controller.isGenerate.value = false; - controller.isDirect.value = false; - controller.isSave.value = true; - controller.centerXY.value = - Offset(centerPointX, centerPointY); - }, - ), - ], - )) - ], - ), - ), - ); - })); - } -} - -final PileGenerController pilecontroller = Get.put(PileGenerController()); - -//卡片 -class PileGenerateCard extends StatelessWidget { - const PileGenerateCard({super.key}); - - @override - Widget build(BuildContext context) { - final Size size = MediaQuery.of(context).size; - final mediaQueryData = MediaQueryData.fromView(View.of(context)); //获取当前屏幕信息 - final orientation = mediaQueryData.orientation; //获得设备方向 - double rectWidth = size.width; - final deviceType = getDeviceType(context); - if (orientation == Orientation.landscape) { - rectWidth = size.width / 2; - if (deviceType == DeviceType.mobile) { - rectWidth = size.height - 130; - } - } else { - rectWidth = size.height / 2; - if (deviceType == DeviceType.mobile) { - rectWidth = size.width - 5; - } - } - - return Obx(() => Visibility( - visible: pilecontroller.isPileCardVisible.value, - child: Positioned( - right: 0, - top: 0, - width: rectWidth - 30, - height: rectWidth + 45, - child: Stack(children: [ - Container( - decoration: const BoxDecoration(color: Colors.transparent), - child: const Stack(children: [ - Card( - color: Colors.transparent, - elevation: 5.0, - child: PileGenerate(), - ), - ])) - ])))); - } -} - -//卡片 -class PileGenerateCard1 extends StatelessWidget { - const PileGenerateCard1({super.key}); - - @override - Widget build(BuildContext context) { - final Size size = MediaQuery.of(context).size; - final mediaQueryData = MediaQueryData.fromView(View.of(context)); //获取当前屏幕信息 - final orientation = mediaQueryData.orientation; //获得设备方向 - double rectWidth = size.width; - final deviceType = getDeviceType(context); - if (orientation == Orientation.landscape) { - rectWidth = size.width / 2; - if (deviceType == DeviceType.mobile) { - rectWidth = size.height - 130; - } - } else { - rectWidth = size.height / 2; - if (deviceType == DeviceType.mobile) { - rectWidth = size.width - 5; - } - } - - return Obx(() => Visibility( - visible: pilecontroller.isRealViewCardVisible.value, - child: Positioned( - right: 0, - top: 0, - width: rectWidth - 30, - height: rectWidth + 45, - child: Stack(children: [ - Container( - decoration: const BoxDecoration(color: Colors.transparent), - child: const Stack(children: [ - Card( - color: Colors.transparent, - elevation: 5.0, - child: PileGenerate(), - ), - ])) - ])))); - } -} diff --git a/lib/pages/task/pile/pileGenerateCard/pile_point_table.dart b/lib/pages/task/pile/pileGenerateCard/pile_point_table.dart index 1940586..ed3220d 100644 --- a/lib/pages/task/pile/pileGenerateCard/pile_point_table.dart +++ b/lib/pages/task/pile/pileGenerateCard/pile_point_table.dart @@ -1,30 +1,28 @@ import 'package:flutter/material.dart'; import 'package:scence_map/controllers/controller.dart'; +import 'package:scence_map/scence_map.dart'; class PilePointTable extends StatefulWidget { final List pilePoints; final Function(List) onUpdate; - const PilePointTable({super.key, required this.pilePoints, required this.onUpdate}); + const PilePointTable( + {super.key, required this.pilePoints, required this.onUpdate}); @override PilePointTableState createState() => PilePointTableState(); } class PilePointTableState extends State { - List _selected = []; - @override void initState() { super.initState(); - _selected = List.filled(widget.pilePoints.length, false); } void _deleteSelected() { setState(() { - widget.pilePoints - .removeWhere((point) => _selected[widget.pilePoints.indexOf(point)]); - _selected = List.filled(widget.pilePoints.length, false); + widget.pilePoints.removeWhere((point) => point.isSelected); + widget.onUpdate(widget.pilePoints); }); } @@ -33,90 +31,91 @@ class PilePointTableState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title:const Text('桩点列表'), + title: const Text('桩点列表'), actions: [ IconButton( - icon:const Icon(Icons.delete), + icon: const Icon(Icons.delete), onPressed: _deleteSelected, ), ], + leading: IconButton( + icon: const Icon(Icons.arrow_back), + onPressed: () { + plumDataController.showList.value = false; + for (var point in widget.pilePoints) { + point.isSelected = false; + } + widget.onUpdate(widget.pilePoints); + }), ), body: SingleChildScrollView( scrollDirection: Axis.vertical, - child: Table( - border: const TableBorder( - verticalInside: BorderSide(color: Colors.grey, width: 1.0), - horizontalInside: BorderSide(color: Colors.grey, width: 1.0), - ), - columnWidths: const { - 0: IntrinsicColumnWidth(), - 1: IntrinsicColumnWidth(), - 2: IntrinsicColumnWidth(), - 3: IntrinsicColumnWidth(), - }, - children: [ - const TableRow( - children: [ - Center(child: Text('选择')), - Center(child: Text('ID')), - Center(child: Text('X')), - Center(child: Text('Y')), - ], - ), - ...List.generate( - widget.pilePoints.length, - (index) => TableRow( + child: widget.pilePoints.isEmpty + ? const Center(child: Text('暂无桩点数据')) + : Table( + border: const TableBorder( + verticalInside: BorderSide(color: Colors.grey, width: 1.0), + horizontalInside: BorderSide(color: Colors.grey, width: 1.0), + ), + columnWidths: const { + 0: IntrinsicColumnWidth(), + 1: IntrinsicColumnWidth(), + 2: FlexColumnWidth(), + 3: FlexColumnWidth(), + }, children: [ - TableCell( - verticalAlignment: TableCellVerticalAlignment.middle, - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0), - child: Checkbox( - value: _selected[index], - onChanged: (bool? value) { - setState(() { - _selected[index] = value ?? false; - }); - }, - ), - ), + TableRow( + children: [ + Center( + child: TextButton( + onPressed: () { + setState(() { + for (var point in widget.pilePoints) { + point.isSelected = !point.isSelected; + } + }); + }, + child: const Text('选择'))), + const Center(child: Text('ID')), + const Center(child: Text('X')), + const Center(child: Text('Y')), + ], ), - TableCell( - verticalAlignment: TableCellVerticalAlignment.middle, - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0), - child: Text(widget.pilePoints[index].id.toString()), - ), - ), - TableCell( - verticalAlignment: TableCellVerticalAlignment.middle, - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0), - child: GestureDetector( - onTap: () => _editPilePoint(context, index, 'x'), - child: Text(widget.pilePoints[index].x.toString()), - ), - ), - ), - TableCell( - verticalAlignment: TableCellVerticalAlignment.middle, - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0), - child: GestureDetector( - onTap: () => _editPilePoint(context, index, 'y'), - child: Text(widget.pilePoints[index].y.toString()), - ), + ...List.generate( + widget.pilePoints.length, + (index) => TableRow( + children: [ + _buildTableCell( + Checkbox( + value: widget.pilePoints[index].isSelected, + onChanged: (bool? value) { + setState(() { + widget.pilePoints[index].isSelected = + value ?? false; + }); + }, + ), + ), + _buildTableCell( + Text(widget.pilePoints[index].id.toString()), + ), + _buildTableCell( + GestureDetector( + onTap: () => _editPilePoint(context, index, 'x'), + child: Text(widget.pilePoints[index].x.toString()), + ), + ), + _buildTableCell( + GestureDetector( + onTap: () => _editPilePoint(context, index, 'y'), + child: Text(widget.pilePoints[index].y.toString()), + ), + ), + ], ), ), ], ), - ), - ], - ), ), ); } @@ -132,7 +131,7 @@ class PilePointTableState extends State { context: context, builder: (context) { return AlertDialog( - title:const Text('编辑桩点'), + title: const Text('编辑桩点'), content: TextField( controller: controller, keyboardType: TextInputType.number, @@ -151,17 +150,27 @@ class PilePointTableState extends State { }); Navigator.of(context).pop(); }, - child:const Text('保存'), + child: const Text('保存'), ), TextButton( onPressed: () { Navigator.of(context).pop(); }, - child:const Text('取消'), + child: const Text('取消'), ), ], ); }, ); } + + Widget _buildTableCell(Widget child) { + return TableCell( + verticalAlignment: TableCellVerticalAlignment.middle, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0), + child: child, + ), + ); + } } diff --git a/lib/pages/task/pile/pileNav/draw_pile.dart b/lib/pages/task/pile/pileNav/draw_pile.dart index 0d0d0ed..f6fd1b7 100644 --- a/lib/pages/task/pile/pileNav/draw_pile.dart +++ b/lib/pages/task/pile/pileNav/draw_pile.dart @@ -1,11 +1,12 @@ - -import 'dart:developer'; +import 'dart:developer' as dev; +// import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:scence_map/controllers/controller.dart'; import 'package:scence_map/controllers/plum_controller.dart'; +import 'view.dart'; ScenceMapController mapController = Get.find(); @@ -27,7 +28,8 @@ class DrawDirection extends CustomPainter { ..style = PaintingStyle.stroke ..color = isDarkMode ? Colors.white : Colors.black; if (controller.linePointOffset.value == Offset.zero || - controller.centerXY.value == Offset.zero) { + controller.centerXY.value == Offset.zero || + controller.checkValue.value == "checkPile") { return; } @@ -39,79 +41,213 @@ class DrawDirection extends CustomPainter { linePointOffset = linePointOffset + pos; centerOffset = controller.centerOffset.value + pos; } - log("-----矩阵中心$centerOffset,$centerXY"); + dev.log("-----矩阵中心$centerOffset,$centerXY"); path.moveTo(centerOffset.dx, centerOffset.dy); path.lineTo(linePointOffset.dx, linePointOffset.dy); canvas.drawPath(path, paint); paint.style = PaintingStyle.fill; - canvas.drawCircle(linePointOffset, 10, paint); - // canvas.translate(centerOffset.dx, centerOffset.dy); - // canvas.rotate(controller.angle.value); - // canvas.translate(-centerOffset.dx, -centerOffset.dy); + // double deLength = 100; + + // double angle = atan2((linePointOffset.dy - centerOffset.dy), + // (linePointOffset.dx - centerOffset.dx)); + // // dev.log("-----角度$angle,${controller.angle.value}"); + // canvas.drawCircle(linePointOffset, 10, paint); + // var dx1 = (deLength * cos(angle + pi / 2)) + centerOffset.dx; + // var dy1 = (deLength) * sin(angle + pi / 2) + centerOffset.dy; + + // canvas.drawCircle(Offset(dx1, dy1), 10, paint); + + // dx1 = (deLength * cos(angle + pi)) + centerOffset.dx; + // dy1 = (deLength) * sin(angle + pi) + centerOffset.dy; + + // canvas.drawCircle(Offset(dx1, dy1), 10, paint); + + // dx1 = (deLength * cos(angle + pi / 2 * 3)) + centerOffset.dx; + // dy1 = (deLength) * sin(angle + pi / 2 * 3) + centerOffset.dy; + + // canvas.drawCircle(Offset(dx1, dy1), 10, paint); + paint // ..color = Colors.grey.withOpacity(.4) .style = PaintingStyle.stroke; if (controller.isUp.value && controller.angle.value != 0) { - double unit = - mapController.plottingScale.value / mapController.pixel2MeterRatio; + List rect = getRect(controller.distancesOffset); + List outRect = getOutRect(rect, centerOffset, linePointOffset); + double unit = controller.space / mapController.pixel2MeterRatio; + + paint.color = Colors.grey; + + canvas.drawLine(rect[0], rect[1], paint); // 绘制上边 + canvas.drawLine(rect[1], rect[2], paint); // 绘制右边 + canvas.drawLine(rect[2], rect[3], paint); // 绘制下边 + canvas.drawLine(rect[3], rect[0], paint); // 绘制左边 // 沿着路径绘制圆圈 - double distance = (linePointOffset - centerOffset).distance; - int horizonalCircles = (distance / unit).floor(); - int verticalCircles = (controller.pileWidth / unit).floor(); - - // controller.plumList.length = 0; + double distance = (outRect[2] - outRect[0]).distance; + int horizonalCircles = (distance / unit).ceil(); + taskcontroller.currentask.value.list.length = 0; List circlePoints = []; - // List plumList = []; - controller.plumList.length = 0; - for (int i = 0; i <= horizonalCircles; i++) { - double t = i * unit / distance; + paint.color = Colors.yellow; + // + double minY = rect[0].dy; + double maxY = rect[2].dy; + double minX = rect[0].dx; + double maxX = rect[2].dx; + bool centerEven = false; + for (int j = -1; j <= horizonalCircles; j++) { + double t = j * unit / distance; Offset point = Offset.lerp(centerOffset, linePointOffset, t)!; - canvas.drawCircle(point, .3 / mapController.pixel2MeterRatio, paint); circlePoints.add(point); - // Offset xy = mapController.screen2xy(point.dx, point.dy); - // plumList.add(Offset(xy.dx, xy.dy)); - controller.plumList.add(point); + if (j > 1) { + Offset point1 = Offset.lerp(centerOffset, linePointOffset, -t)!; + if (point1.dx >= (minX - unit) && + point1.dx <= (maxX + unit) && + point1.dy >= (minY - unit) && + point1.dy <= (maxY + unit)) { + circlePoints.add(point1); + if (point1 - centerOffset < Offset(unit, unit)) { + centerEven = circlePoints.length % 2 == 0; + } + } + // + } } - - // 在反方向延长线上绘制对称的圆圈 - for (int i = 1; i <= horizonalCircles; i++) { - double t = i * unit / distance; - Offset point = Offset.lerp(centerOffset, linePointOffset, -t)!; - canvas.drawCircle(point, .3 / mapController.pixel2MeterRatio, paint); - circlePoints.add(point); - controller.plumList.add(point); - - //List保存 - } - - // 计算垂直于path的方向向量 + circlePoints.sort((a, b) => a.dx.compareTo(b.dx)); Offset direction = (linePointOffset - centerOffset).scale(1 / distance, 1 / distance); Offset perpendicular = Offset(-direction.dy, direction.dx); - + controller.plumList.length = 0; // 绘制上下方的圆圈,形成正方形矩阵 - for (Offset point in circlePoints) { - for (int j = 0; j <= verticalCircles / 2; j++) { + + for (int p = 0; p <= circlePoints.length - 1; p++) { + Offset point = circlePoints[p]; + + for (int j = 0; j <= horizonalCircles; j++) { Offset upPoint = point + perpendicular * (j * unit); Offset downPoint = point - perpendicular * (j * unit); - canvas.drawCircle( - upPoint, .3 / mapController.pixel2MeterRatio, paint); - canvas.drawCircle( - downPoint, .3 / mapController.pixel2MeterRatio, paint); + bool isUpPointInRect = upPoint.dx >= minX && + upPoint.dx <= maxX && + upPoint.dy >= minY && + upPoint.dy <= maxY; + bool isDownPointInRect = downPoint.dx >= minX && + downPoint.dx <= maxX && + downPoint.dy >= minY && + downPoint.dy <= maxY; + if (controller.isPlum.value) { + if ((j % 2 == p % 2) == centerEven) { + paint.style = PaintingStyle.fill; + } else { + paint.style = PaintingStyle.stroke; + } + if (isDownPointInRect && j > 0) { + canvas.drawCircle( + downPoint, .3 / mapController.pixel2MeterRatio, paint); + if ((j % 2 == p % 2) == centerEven) { + Offset xy1 = mapController.screen2xy0(downPoint); + controller.plumList.add(xy1); + } + } - // Offset xy = mapController.screen2xy0(upPoint); - // Offset xy1 = mapController.screen2xy0(downPoint); - controller.plumList.add(upPoint); - controller.plumList.add(downPoint); + if (isUpPointInRect) { + canvas.drawCircle( + upPoint, .3 / mapController.pixel2MeterRatio, paint); + if ((j % 2 == p % 2) != centerEven) { + Offset xy = mapController.screen2xy0(upPoint); + controller.plumList.add(xy); + } + } + continue; + } + + if (isUpPointInRect) { + // TextPainter textPainter = TextPainter( + // text: TextSpan( + // text: '$p,$j', + // style: TextStyle(color: Colors.blue, fontSize: 16)), + // textDirection: TextDirection.ltr, + // ); + // textPainter.layout(); + // textPainter.paint(canvas, upPoint); + canvas.drawCircle( + upPoint, .3 / mapController.pixel2MeterRatio, paint); + Offset xy = mapController.screen2xy0(upPoint); + controller.plumList.add(xy); + } + + if (isDownPointInRect && j > 0) { + // TextPainter textPainter = TextPainter( + // text: TextSpan( + // text: '$p,$j', + // style: TextStyle(color: Colors.blue, fontSize: 16)), + // textDirection: TextDirection.ltr, + // ); + // textPainter.layout(); + // textPainter.paint(canvas, downPoint); + canvas.drawCircle( + downPoint, .3 / mapController.pixel2MeterRatio, paint); + Offset xy1 = mapController.screen2xy0(downPoint); + controller.plumList.add(xy1); + } } } - + dev.log("controller.plumList:${controller.plumList.length}"); } } + getRect(List list) { + List rect = []; + double minx = double.infinity; + double maxx = double.negativeInfinity; + double miny = double.infinity; + double maxy = double.negativeInfinity; + for (var point in list) { + minx = point.dx < minx ? point.dx : minx; + maxx = point.dx > maxx ? point.dx : maxx; + miny = point.dy < miny ? point.dy : miny; + maxy = point.dy > maxy ? point.dy : maxy; + } + minx += controller.transOff.dx; + maxx += controller.transOff.dx; + miny += controller.transOff.dy; + maxy += controller.transOff.dy; + // 根据最小最大坐标生成矩形的四个顶点 + rect.add(Offset(minx, miny)); // 左下角 + rect.add(Offset(maxx, miny)); // 右下角 + rect.add(Offset(maxx, maxy)); // 右上角 + rect.add(Offset(minx, maxy)); // 左上角 + + return rect; + } + + getOutRect(List rect, Offset centerOffset, Offset linePointOffset) { + // double height = rect[2].dy - rect[0].dy; + // double width = rect[1].dx - rect[0].dx; + double newHeight = (centerOffset.dy - linePointOffset.dy) * 2; + double newWidth = (centerOffset.dx - linePointOffset.dx) * 2; + // if (newHeight < height) { + // newHeight = height; + // } + // if (newWidth < width) { + // newWidth = width; + // } + Offset topLeft = + Offset(centerOffset.dx - newWidth / 2, centerOffset.dy - newHeight / 2); + Offset topRight = + Offset(centerOffset.dx + newWidth / 2, centerOffset.dy - newHeight / 2); + Offset bottomLeft = + Offset(centerOffset.dx - newWidth / 2, centerOffset.dy + newHeight / 2); + Offset bottomRight = + Offset(centerOffset.dx + newWidth / 2, centerOffset.dy + newHeight / 2); + return [ + bottomLeft, + bottomRight, + topRight, + topLeft, + ]; + } + @override bool shouldRepaint(covariant CustomPainter oldDelegate) => true; } diff --git a/lib/pages/task/pile/pileNav/view.dart b/lib/pages/task/pile/pileNav/view.dart index f5e0df8..97de51d 100644 --- a/lib/pages/task/pile/pileNav/view.dart +++ b/lib/pages/task/pile/pileNav/view.dart @@ -8,25 +8,28 @@ import 'package:scence_map/record_entity.dart'; import 'package:get/get.dart'; +import '../../../../main.dart'; +import '../../../../service/pile/device_type.dart'; +import '../../../../service/pile/input.dart'; +import '../../../../service/pile/public_widget.dart'; +import '../../model.dart'; import '../../task_page.dart'; import '../../taskcontroller.dart'; -import '../pileGenerateCard/pile_generate.dart'; +import '../pileGenerateCard/pile_point_table.dart'; import 'draw_pile.dart'; -final TaskController taskcontroller = Get.put(TaskController()); +final TaskController taskcontroller = Get.find(); +final ScenceMapController mapController = Get.find(); -class RealView extends StatefulWidget { - const RealView({super.key}); +class TaskView extends StatefulWidget { + const TaskView({super.key}); @override - State createState() => _RealViewState(); + State createState() => _TaskViewState(); } -class _RealViewState extends State { - final ScenceMapController scenceMapController = - Get.put(ScenceMapController()); +class _TaskViewState extends State { final controller = Get.find(); - late StepDialogManager _showStepDialog; @override void dispose() { super.dispose(); @@ -36,28 +39,66 @@ class _RealViewState extends State { @override void initState() { super.initState(); - _showStepDialog = StepDialogManager(context); - scenceMapController.update(); + mapController.update(); isInit = true; } @override Widget build(BuildContext context) { + ever(controller.showList, (bool val) { + if (val) { + taskcontroller.currentask.update((task) { + double centerPointX = controller.centerXY.value.dx; + double centerPointY = controller.centerXY.value.dy; + task?.list.length = 0; + var dx = (controller.canvasSize.width) / 2; + var dy = (controller.canvasSize.height) / 2; + var rotation = mapController.rotation.value; + List currentPoints = []; + for (int i = 0; i < controller.plumList.length; i++) { + Offset item = controller.plumList[i]; + + var dx1 = ((item.dx - dx) * cos(rotation) + + (item.dy - dy) * sin(rotation)); + var dy1 = -(item.dx - dx) * sin(rotation) + + (item.dy - dy) * cos(rotation); + + // Offset xy = mapController.screenCenter2xy(dx1, dy1); + Offset xy = Offset(dx1, dy1); + PilePoint pilePoint = PilePoint( + x: (xy.dx * 1000).roundToDouble() / 1000, + y: (xy.dy * 1000).roundToDouble() / 1000, + times: 0, + id: i + 1, + radius: 0.3); + currentPoints.add(pilePoint); + } + task?.list = currentPoints; + task?.centerPileInfo = CenterPileInfo( + x: (centerPointX * 1000).round() / 1000, + y: (centerPointY * 1000).round() / 1000, + // direction: controller.direction.value, + space: controller.space.value, + pileWidth: controller.pileWidth.value, + ); + }); + } + }); + final size = MediaQuery.of(context).size; final isDarkMode = Theme.of(context).brightness == Brightness.dark; - double diagonal = scenceMapController.diagonal; - double mapWidth = scenceMapController.width; - double mapHeight = scenceMapController.height; + double diagonal = mapController.diagonal; + double mapWidth = mapController.width; + double mapHeight = mapController.height; Offset scOffset = Offset(mapWidth / 2 - diagonal / 2, mapHeight / 2 - diagonal / 2); onTapDown(TapDownDetails details) { isInit = false; if (controller.checkValue.value == "checkPile") { - // controller.centerOffset.value = details.localPosition; - Offset sc2xy = scenceMapController.screen2xy0(details.localPosition); + Offset sc2xy = mapController.screen2xy0(details.localPosition); controller.centerXY.value = sc2xy; RecordEntity? checkPoint = - scenceMapController.pointInfo(controller.centerXY.value); + mapController.pointInfo(controller.centerXY.value); if (checkPoint != null) { controller.isPileId.value = true; @@ -66,12 +107,14 @@ class _RealViewState extends State { controller.isPileId.value = false; controller.checkName.value = "未找到"; } - } + controller.linePointOffset.value = Offset.zero; + } else {} } onScaleStart(ScaleStartDetails details) { if (controller.checkValue.value != "checkPile") { controller.linePointOffset.value = details.localFocalPoint; + controller.updateDistances(0.0); } // controller.shouldPaint.value = true; } @@ -80,17 +123,19 @@ class _RealViewState extends State { controller.isUp.value = false; // controller.shouldPaint.value = true; if (controller.checkValue.value != "checkPile") { - if (controller.linePointOffset.value != details.localFocalPoint) { - controller.linePointXY.value = - scenceMapController.screen2xy0(details.localFocalPoint); + Offset offset = details.localFocalPoint; + controller.linePointOffset.value = offset; + controller.linePointXY.value = mapController.screen2xy0(offset); + double distance = + (controller.centerOffset.value - controller.linePointOffset.value) + .distance; + controller.distanceOfCenter[controller.currentDir.value.index] = + (distance * 100).round() / 100; + controller.updateDistances(controller.direction.value); - controller.updateLinePoint(details.localFocalPoint); - } + controller.updateCount++; } controller.isUp.value = true; - } - - onScaleEnd(ScaleEndDetails details) { double deg = (atan2( controller.linePointOffset.value.dy - controller.centerOffset.value.dy, @@ -102,20 +147,24 @@ class _RealViewState extends State { controller.direction.value = deg + 90; controller.angle.value = ((controller.direction.value * pi / 180) * 100).round() / 100; + } + onScaleEnd(ScaleEndDetails details) { controller.isUp.value = true; + controller.updateCount++; } // 中间 var center = Obx(() { + controller.updateCount; // 桩点生成 if (!controller.isGenerate.value) { return const Text(""); } return Positioned( - width: scenceMapController.diagonal, - height: scenceMapController.diagonal, + width: mapController.diagonal, + height: mapController.diagonal, top: scOffset.dy, left: scOffset.dx, child: GestureDetector( @@ -136,16 +185,38 @@ class _RealViewState extends State { ], ), child: Obx(() { - ////必须写 因为 需要监听 -- 的值发生变化 刷新 + controller.updateCount; + List buttons = controller.distancesOffset; - controller.linePointOffset.value; - controller.isUp.value; - return CustomPaint( - // size: Size(scenceMapController.diagonal, - // scenceMapController.diagonal), - foregroundPainter: - DrawDirection(controller, scOffset, isDarkMode, isInit), - // child: + buttons[controller.currentDir.value.index] = + controller.linePointOffset.value - controller.transOff; + if (controller.checkValue.value == "checkPile") { + buttons = [ + Offset.zero, + Offset.zero, + Offset.zero, + Offset.zero + ]; + } + List buttonsList = []; + for (int b = 0; b < buttons.length; b++) { + buttonsList + .add(buildPositionedButton(buttons[b], -3.14 / 2, () { + controller.currentDir.value = dirList[b]; + // controller.direction.value += dirList[b].angle + 3.14 / 2; + })); + } + return Stack( + children: [ + CustomPaint( + // size: Size(scenceMapController.diagonal, + // scenceMapController.diagonal), + foregroundPainter: DrawDirection( + controller, scOffset, isDarkMode, isInit), + // child: + ), + ...buttonsList + ], ); }), ), @@ -154,17 +225,18 @@ class _RealViewState extends State { // 桩点生成时返回按钮 var back = Obx(() { // bug :有时候点击的位置不准确 8寸屏的是正常的 - - controller.centerOffset.value = scenceMapController.xy2Screen( + controller.centerOffset.value = mapController.xy2Screen( controller.centerXY.value.dx, controller.centerXY.value.dy); if (isInit) { - controller.centerOffset.value = scenceMapController.xy2Screen( + controller.centerOffset.value = mapController.xy2Screen( controller.centerXY.value.dx, controller.centerXY.value.dy) - scOffset; } + // controller.linePointOffset.value = controller.centerOffset.value; + dev.log( - "中心${controller.centerOffset.value},${controller.centerXY.value},${scenceMapController.centerXY},$scOffset,$isInit"); + "中心${controller.centerOffset.value},${controller.centerXY.value},${mapController.centerXY},$scOffset,$isInit"); // dev.log(scenceMapController.xy2Screen( // controller.centerXY.value.dx, controller.centerXY.value.dy)); @@ -190,35 +262,373 @@ class _RealViewState extends State { ), child: const Icon(Icons.keyboard_return), onPressed: () { - pilecontroller.isRealViewCardVisible.value = true; - controller.isDirect.value = true; - if (!taskcontroller.isDialogShown[3]) { - _showStepDialog.showStepDialog(3); - - taskcontroller.isDialogShown[3] = true; + controller.isGenerate.value = false; + controller.updateDistances(controller.angle.value); + if (controller.checkValue.value == "checkPile") { + centerPointDialog(context, controller); + } else { + controller.showList.value = true; } + controller.checkValue.value = ""; }, ), )); }); - return Stack( - children: [ - Obx(() => AbsorbPointer( - absorbing: controller.isGenerate.value - ? true - : false, //设置CenterLayout 内的GestureDetector 不生效 - // child: const ScenceMapView( - // children: [], - // ), - child:const TaskPage(), // 任务页面 - // PassTrack( - // date: '', - // ) - )), - center, - back, - const PileGenerateCard1() - ], + + return Scaffold( + appBar: AppBar( + title: const Text('任务页面'), + actions: [ + ElevatedButton( + child: const Text("桩点坐标"), + onPressed: () => { + controller.checkValue.value = "checkPile", + }), + const SizedBox( + width: 10, + ), + ElevatedButton( + child: const Text("生成"), + onPressed: () => { + controller.checkValue.value = "checkDirection", + }), + UnconstrainedBox( + child: IconButton( + onPressed: () { + int index = controller.currentDir.value.index; + // controller.distancesOffset[index] = + // controller.linePointOffset.value - controller.transOff; + if (index + 1 == dirList.length) { + index = -1; + } + + controller.currentDir.value = dirList[index + 1]; + // controller.direction.value += + // controller.currentDir.value.angle + 3.14 / 2; + controller.updateDistances(controller.direction.value); + controller.linePointOffset.value = + controller.distancesOffset[index + 1]; + controller.updateCount++; + }, + icon: Obx(() { + int index = controller.currentDir.value.index; + return Transform.rotate( + angle: dirList[index].angle, + child: const Icon(Icons.arrow_back), + ); + }), + ), + ), + UnconstrainedBox( + child: SizedBox( + height: 30, + child: Builder( + builder: (context) => Obx( + () => InkWell( + child: Icon( + Icons.list, + size: 35, + color: appcontroller.isDarkMode.value + ? Colors.white70 + : const Color.fromARGB(200, 29, 28, 28), + ), + onTap: () { + controller.showList.value = + !controller.showList.value; + }), + ), + ), + ), + ), + ], + ), + body: Stack( + children: [ + Obx(() { + controller.isGenerate.value; + return AbsorbPointer( + absorbing: controller.isGenerate.value + ? true + : false, //设置CenterLayout 内的GestureDetector 不生效 + + child: const TaskPage(), // 任务页面 + ); + }), + center, + back, + Obx(() { + if (controller.showList.value) { + return Positioned( + right: 0, + top: 0, + width: size.width * 0.4, + height: size.height, + child: PilePointTable( + pilePoints: taskcontroller.currentask.value.list, + onUpdate: (updatedPilePoints) => + updatePoints(updatedPilePoints), + ), + ); + } else { + return const Text(""); + } + }) + + // const PileGenerateCard1() + ], + )); + } + + Widget buildPositionedButton( + Offset position, double rotationAngle, VoidCallback press) { + Color color = Colors.black; + + return Positioned( + left: position.dx, + top: position.dy, + child: IconButton( + onPressed: press, + icon: Transform.rotate( + angle: rotationAngle, + child: Icon( + Icons.arrow_back, + color: color, + ), + ), + ), ); } } + +centerPointDialog(context, PlumDataController controller) { + double titleTextWidth = 90; + double inputLength = 120; + FocusNode xFocus = FocusNode(); + FocusNode yFocus = FocusNode(); + FocusNode directionFocus = FocusNode(); + FocusNode pileSpaceFocus = FocusNode(); + // FocusNode pileWidthFocus = FocusNode(); + DeviceType deviceType = getDeviceType(context); + double fontSize = 16; + if (deviceType == DeviceType.mobile) { + fontSize = 16; + } else { + fontSize = 20; + } + showDialog( + context: context, + builder: (context) { + final size = MediaQuery.of(context).size; + double centerPointX = controller.centerXY.value.dx; + double centerPointY = controller.centerXY.value.dy; + return AlertDialog( + title: const Text("设置"), + contentPadding: const EdgeInsets.symmetric(horizontal: 3), + actionsPadding: const EdgeInsets.only(bottom: 5), + actions: [ + TextButton( + child: const Text('取消'), + onPressed: () { + controller.isGenerate.value = false; + controller.isSave.value = false; + Navigator.of(context).pop(); + // 执行取消的逻辑 + }, + ), + TextButton( + child: const Text('确定'), + onPressed: () { + // 执行确定的逻辑 + + controller.isGenerate.value = false; + controller.isSave.value = true; + controller.centerXY.value = Offset(centerPointX, centerPointY); + Navigator.of(context).pop(); + }, + ), + ], + content: SizedBox( + height: size.height * 0.45, + width: size.width * 0.5, + child: SingleChildScrollView( + child: AlignWrapWidget( + children: [ + Row(children: [ + FixedWidthTextWidget(width: titleTextWidth, text: "X:"), + inputText( + inputLength: inputLength, + value: centerPointX.toString(), + fontsize: fontSize, + focusNode: yFocus, + onChanged: (value) => value.isNotEmpty + ? centerPointY = + (double.parse(value) * 1000).round() / 1000 + : '') + ]), + Row(children: [ + FixedWidthTextWidget(width: titleTextWidth, text: "Y:"), + inputText( + inputLength: inputLength, + value: centerPointY.toString(), + fontsize: fontSize, + focusNode: xFocus, + onChanged: (value) => value.isNotEmpty + ? centerPointX = + (double.parse(value) * 1000).round() / 1000 + : '') + ]), + Row(children: [ + FixedWidthTextWidget(width: titleTextWidth, text: "方向(°):"), + inputText( + inputLength: inputLength, + value: controller.direction.toString(), + fontsize: fontSize, + focusNode: directionFocus, + keyboardType: 0, + onChanged: (value) { + if (value.isNotEmpty) { + controller.direction.value = double.parse(value); + // bug 值修改后 绘制没有变化 + controller.angle.value = + controller.direction.value * pi / 180; + } + }) + ]), + Row( + children: [ + FixedWidthTextWidget( + width: titleTextWidth + 10, text: "夯点间距(m):"), + inputText( + inputLength: inputLength - 10, + fontsize: fontSize, + value: controller.space.toString(), + focusNode: pileSpaceFocus, + onChanged: (value) => { + value.isNotEmpty + ? controller.space.value = double.parse(value) + : '', + }) + ], + ), + Row(children: [ + FixedWidthTextWidget( + width: titleTextWidth + 10, text: "是否为梅花桩:"), + Obx(() { + bool c = controller.isPlum.value; + return Switch( + onChanged: (val) { + controller.isPlum.value = val; + }, + value: c, + ); + }) + ]), + // Row(children: [ + // FixedWidthTextWidget( + // width: titleTextWidth + 10, text: "宽度(m):"), + // inputText( + // inputLength: inputLength - 10, + // fontsize: fontSize, + // value: controller.pileWidth.toString(), + // focusNode: pileWidthFocus, + // onChanged: (value) => { + // value.isNotEmpty + // ? controller.pileWidth.value = + // double.parse(value) + // : '', + // }) + // ]), + Row(children: [ + const Icon( + Icons.tips_and_updates_outlined, + color: Colors.red, + ), + Text( + controller.isPileId.value + ? '选中桩点:${controller.checkName.value}' + : ' 未选中桩点', + style: TextStyle( + color: !controller.isPileId.value + ? Colors.red + : Colors.black), + ) + ]), + ], + )), + ), + ); + }); +} + +updatePoints(List updatedPilePoints) { + taskcontroller.currentask.update((task) { + task?.list = updatedPilePoints; + }); + // 这里可以处理更新后的桩点列表 + // dev.log("生成桩点${updatedPilePoints.length},"); + // for (var updatedPilePoint in updatedPilePoints) { + // // 查找 recordList 中对应的 RecordEntity + // RecordEntity? recordEntity = + // mapController.recordList.firstWhere( + // (record) => record.id == updatedPilePoint.id, + // orElse: () => RecordEntity( + // id: -1, // 使用一个无效的 id 表示未找到 + // tid: 0, + // startTime: DateTime.now(), + // endTime: DateTime.now(), + // pileId: 0, + // name: '', + // times: 0, + // lat: 0.0, + // lng: 0.0, + // x: 0.0, + // y: 0.0, + // h: 0.0, + // totalFlow: 0.0, + // titlXavg: 0.0, + // titlYavg: 0.0, + // current1Avg: 0.0, + // current2Avg: 0.0, + // quality: 0, + // reason: '', + // remark: '', + // depth: 0, + // speed: 0.0, + // ), + // ); + + // if (recordEntity.id != -1) { + // // 更新 RecordEntity 的属性 + // recordEntity.x = updatedPilePoint.x; + // recordEntity.y = updatedPilePoint.y; + // // 其他属性的更新 + // } else { + // // 如果找不到对应的 RecordEntity,则添加新的 + // recordEntity = RecordEntity( + // id: updatedPilePoint.id, + // tid: 0, + // startTime: DateTime.now(), + // endTime: DateTime.now(), + // pileId: 0, + // name: '', + // times: 0, + // lat: 0.0, + // lng: 0.0, + // x: updatedPilePoint.x, + // y: updatedPilePoint.y, + // h: 0.0, + // totalFlow: 0.0, + // titlXavg: 0.0, + // titlYavg: 0.0, + // current1Avg: 0.0, + // current2Avg: 0.0, + // quality: 0, + // reason: '', + // remark: '', + // depth: 0, + // speed: 0.0, + // ); + // mapController.recordList.add(recordEntity); + // } + // } +} diff --git a/lib/pages/task/task_page.dart b/lib/pages/task/task_page.dart index b880e1d..75cf469 100644 --- a/lib/pages/task/task_page.dart +++ b/lib/pages/task/task_page.dart @@ -1,7 +1,10 @@ +import 'dart:convert'; import 'dart:developer'; +import 'dart:io'; import 'package:cpnav/main.dart'; -import 'package:cpnav/pages/task/pile/pileGenerateCard/pile_generate.dart'; +import 'package:cpnav/pages/task/info.dart'; +import 'package:cpnav/pages/task/model.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:scence_map/controllers/controller.dart'; @@ -9,109 +12,13 @@ import 'package:scence_map/record_entity.dart'; import 'package:scence_map/scence_map.dart'; import '../pass_track/controller.dart'; import '../pass_track/view.dart'; -import 'pile/pileGenerateCard/pile_point_table.dart'; -import 'pile/pileNav/view.dart'; + import 'taskcontroller.dart'; +import 'package:path_provider/path_provider.dart'; -final ScenceMapController mapcontroller = Get.put(ScenceMapController()); - -class TaskManagePage extends StatelessWidget { - const TaskManagePage({super.key}); - - @override - Widget build(BuildContext context) { - final size = MediaQuery.of(context).size; - return OrientationBuilder(builder: ((context, orientation) { - return Center( - child: Container( - width: size.width * 0.8, - height: size.height * 0.18, - decoration: BoxDecoration( - border: Border.all(color: Colors.black), - borderRadius: BorderRadius.circular(10), - ), - child: SingleChildScrollView( - child: Row(children: [ - const SizedBox(width: 16), - const Icon(Icons.task, - size: 50, color: Color.fromARGB(164, 75, 73, 73)), - const SizedBox(width: 16), - SizedBox( - width: size.width * 0.4, - child: const Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 5), - Text( - '任务', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), - Row(children: [ - Expanded( - child: TextField( - keyboardType: TextInputType.emailAddress, - decoration: InputDecoration( - labelText: "任务:", - hintText: "", - // prefixIcon: Icon(Icons.email), - border: InputBorder.none, //隐藏下划线 - labelStyle: TextStyle( - fontSize: 16, - color: Color.fromARGB(164, 75, 73, 73)), - ), - ), - ), - SizedBox(width: 5), - Expanded( - child: TextField( - keyboardType: TextInputType.emailAddress, - decoration: InputDecoration( - labelText: "桩点数:", - hintText: "0", - // prefixIcon: Icon(Icons.email), - border: InputBorder.none, //隐藏下划线 - labelStyle: TextStyle( - fontSize: 16, - color: Color.fromARGB(164, 75, 73, 73)), - ), - ), - ), - ]), - ], - ), - ), - // const SizedBox(width: 150), - Expanded( - child: Container( - alignment: Alignment.centerRight, - child: - Row(mainAxisAlignment: MainAxisAlignment.end, children: [ - const Text( - '编辑', - style: TextStyle( - fontSize: 14, color: Color.fromARGB(164, 75, 73, 73)), - ), - const SizedBox(width: 12), - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const RealView()), - ); - }, - child: const Icon(Icons.arrow_forward_ios, - size: 30, color: Color.fromARGB(164, 75, 73, 73)), - ) - ]))) - ])), - )); - })); - } -} - -final controller = Get.put(PassTrackController("TEST", "pile_cm")); -final TaskController taskcontroller = Get.put(TaskController()); +final ScenceMapController mapcontroller = Get.find(); +final pscontroller = Get.put(PassTrackController()); +final TaskController taskcontroller = Get.find(); // class TaskPage extends StatelessWidget { class TaskPage extends StatefulWidget { @@ -122,197 +29,156 @@ class TaskPage extends StatefulWidget { } class TaskPageState extends State { - late StepDialogManager _showStepDialog; - @override void initState() { super.initState(); - _showStepDialog = StepDialogManager(context); } @override Widget build(BuildContext context) { - final size = MediaQuery.of(context).size; // final mediaQueryData = MediaQueryData.fromView(View.of(context)); //获取当前屏幕信息 // final orientation = mediaQueryData.orientation; //获得设备方向 // bool isPortrait = Orientation.portrait == orientation ? true : false; - return Scaffold( - endDrawer: Drawer( - width: size.width * .5, - child: PilePointTable( - pilePoints: mapcontroller.pilePoints, - onUpdate: (updatedPilePoints) { - // 这里可以处理更新后的桩点列表 - log("生成桩点$updatedPilePoints,"); - for (var updatedPilePoint in updatedPilePoints) { - // 查找 recordList 中对应的 RecordEntity - RecordEntity? recordEntity = - mapController.recordList.firstWhere( - (record) => record.id == updatedPilePoint.id, - orElse: () => RecordEntity( - id: -1, // 使用一个无效的 id 表示未找到 - tid: 0, - startTime: DateTime.now(), - endTime: DateTime.now(), - pileId: 0, - name: '', - times: 0, - lat: 0.0, - lng: 0.0, - x: 0.0, - y: 0.0, - h: 0.0, - totalFlow: 0.0, - titlXavg: 0.0, - titlYavg: 0.0, - current1Avg: 0.0, - current2Avg: 0.0, - quality: 0, - reason: '', - remark: '', - depth: 0, - speed: 0.0, - ), - ); - - if (recordEntity.id != -1) { - // 更新 RecordEntity 的属性 - recordEntity.x = updatedPilePoint.x; - recordEntity.y = updatedPilePoint.y; - // 其他属性的更新 - } else { - // 如果找不到对应的 RecordEntity,则添加新的 - recordEntity = RecordEntity( - id: updatedPilePoint.id, - tid: 0, - startTime: DateTime.now(), - endTime: DateTime.now(), - pileId: 0, - name: '', - times: 0, - lat: 0.0, - lng: 0.0, - x: updatedPilePoint.x, - y: updatedPilePoint.y, - h: 0.0, - totalFlow: 0.0, - titlXavg: 0.0, - titlYavg: 0.0, - current1Avg: 0.0, - current2Avg: 0.0, - quality: 0, - reason: '', - remark: '', - depth: 0, - speed: 0.0, - ); - mapController.recordList.add(recordEntity); - } - } - }, - ), - ), - appBar: AppBar( - title: const Text('任务页面'), - actions: [ - UnconstrainedBox( - child: SizedBox( - height: 30, - child: Builder( - builder: (context) => Obx( - () => InkWell( - child: Icon( - Icons.close, - size: 35, - color: appcontroller.isDarkMode.value - ? Colors.white70 - : const Color.fromARGB(200, 29, 28, 28), - ), - onTap: () => Scaffold.of(context).openEndDrawer(), - ), - ), - ), - ), - ), - UnconstrainedBox( - child: SizedBox( - height: 30, - child: InkWell( - child: Obx( - () => Icon( - Icons.settings_outlined, - size: 35, - color: appcontroller.isDarkMode.value - ? Colors.white70 - : const Color.fromARGB(200, 29, 28, 28), - ), - ), - onTap: () { - pilecontroller.isPileCardVisible.value = true; - if (!taskcontroller.isDialogShown[0]) { - _showStepDialog.showStepDialog(0); - taskcontroller.isDialogShown[0] = true; - } - }, - ), - ), - ), - ], - ), - body: Stack( - children: [ - ScenceMapView( - onUpdate: (Offset center, double scale, double rotation) { - log("center:$center scale:$scale rotation:$rotation"); - }, - forGroundPainter: appcontroller.currentIndex.value == 1 - ? BorderPainter(controller) - : null, - onUpdatePilePoint: (RecordEntity? selectedPilePoint, double scale, - double rotation) { - log( - "selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation"); - }, - children: const [], - ), - // ), - if (pilecontroller.isPileCardVisible.value) - const PileGenerateCard(), - ], - )); + return ScenceMapView( + onUpdate: (Offset center, double scale, double rotation) { + log("center:$center scale:$scale rotation:$rotation"); + }, + forGroundPainter: appcontroller.currentIndex.value == 1 + ? BorderPainter(pscontroller) + : null, + onUpdatePilePoint: + (RecordEntity? selectedPilePoint, double scale, double rotation) { + log("selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation"); + }, + children: const [], + ); } } -//对话框 -class StepDialogManager { - final BuildContext context; - final List _stepTexts = [ - '点击屏幕即可确定桩点中心。', - '这是步骤 2 的提示对话框。', - '这是步骤 3 的提示对话框。', - '点击方向设置按钮和输入宽度值可设置桩点范围。', - '手指在屏幕上拖动可确定桩点范围' - ]; +class TaskManagePage extends GetView { + const TaskManagePage({super.key}); - StepDialogManager(this.context); + @override + Widget build(BuildContext context) { + final size = MediaQuery.of(context).size; + return OrientationBuilder(builder: ((context, orientation) { + return Stack( + children: [ + SizedBox( + height: size.height * 0.8, + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), + child: Obx(() { + controller.updateCount; + List children = []; + if (controller.taskList.isEmpty) { + children.add(Container( + width: 120, + margin: EdgeInsets.symmetric( + horizontal: size.width * .4, + vertical: size.height * 0.4), + child: const FloatingActionButton( + onPressed: null, child: Text('暂无任务')))); + } else { + for (int i = 0; i < controller.taskList.length; i++) { + Widget child = + TaskItemPage(taskInfo: controller.taskList[i]); + children.add(child); + } + } + return Column( + children: children, + ); + }), + ), + ), + Positioned( + bottom: 5, + right: 5, + child: Row( + children: [ + ElevatedButton( + onPressed: () { + controller.updateCount++; + }, + child: const Text("同步")), + const SizedBox(width: 10), + ElevatedButton( + onPressed: () => addDialog(context), + child: const Text("新增"), + ), + ], + )) + ], + ); + })); + } - void showStepDialog(int step) { + addDialog(context) { + // 点击新增按钮时显示弹窗 + TaskItem addTask = TaskItem( + list: [], + name: " ", + id: 0, + utc: 0, + originLabel: "本地", + workTotal: 0, + centerPileInfo: CenterPileInfo( + x: 0, + y: 0, + )); + TextEditingController taskController = + TextEditingController(text: addTask.name.toString()); showDialog( context: context, builder: (BuildContext context) { return AlertDialog( - title: const Text('步骤提示'), - content: Text(_stepTexts[step]), + title: const Text("新增任务"), + content: SizedBox( + height: 100, + child: Column( + children: [ + TextField( + keyboardType: TextInputType.emailAddress, + controller: taskController, + decoration: const InputDecoration( + hintText: '任务名称', + prefixText: '任务名称:', + border: InputBorder.none, + labelStyle: TextStyle( + fontSize: 16, color: Color.fromARGB(164, 75, 73, 73)), + ), + ) + ], + ), + ), actions: [ TextButton( - child: const Text('确定'), onPressed: () { - Navigator.of(context).pop(); - for (int i = 0; i < taskcontroller.isDialogShown.length; i++) { - taskcontroller.isDialogShown[i] = false; - } + Navigator.of(context).pop(); // 关闭弹窗 }, + child: const Text("取消"), + ), + TextButton( + onPressed: () async { + addTask.name = taskController.text.trim(); + addTask.utc = DateTime.now().millisecondsSinceEpoch ~/ 1000; + final directory = await getApplicationDocumentsDirectory(); + final filePath = '${directory.path}/tasks/${addTask.utc}.json'; + final file = File(filePath); + final folder = Directory('${directory.path}/tasks'); + await folder.create(recursive: true); + String jsonString = jsonEncode(addTask.toJson()); + + // 写入 JSON 字符串到文件 + await file.writeAsString(jsonString); + controller.taskList.add(addTask); + controller.updateCount++; + // ignore: use_build_context_synchronously + Navigator.of(context).pop(); + }, + child: const Text("确定"), ), ], ); diff --git a/lib/pages/task/taskcontroller.dart b/lib/pages/task/taskcontroller.dart index 4a13b94..c03f274 100644 --- a/lib/pages/task/taskcontroller.dart +++ b/lib/pages/task/taskcontroller.dart @@ -1,5 +1,136 @@ +import 'dart:convert'; +import 'dart:developer'; +import 'dart:io'; +import 'package:cpnav/pages/task/model.dart'; +import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:scence_map/scence_map.dart'; + +import 'task_page.dart'; class TaskController extends GetxController { - List isDialogShown = [false, false, false, false, false].obs; + final box = GetStorage(); // 实例化 GetStorage + // List isDialogShown = [false, false, false, false, false].obs; + var currentask = TaskItem( + list: [], + name: " ", + id: 0, + utc: 0, + originLabel: "本地", + workTotal: 0, + centerPileInfo: CenterPileInfo( + x: 0, + y: 0, + // direction: 0, + )).obs; + var updateCount = 0.obs; + var taskList = [].obs; + @override + void onInit() { + loadTasks(); + super.onInit(); + TaskItem? sysTask = getTask(); + if (sysTask != null) { + currentask.value = sysTask; + } + ever(currentask, (task) { + mapcontroller.pilePoints.value = task.list; + mapcontroller.updateCount++; + plumDataController.centerXY.value = + Offset(task.centerPileInfo.x, task.centerPileInfo.y); + // plumDataController.direction.value=task.centerPileInfo.direction; + plumDataController.angle.value = task.centerPileInfo.angle; + plumDataController.space.value = task.centerPileInfo.space; + plumDataController.pileWidth.value = task.centerPileInfo.pileWidth; + List distances = []; //px + for (var i = 0; i < 4; i++) { + double distance = task.centerPileInfo.distances[i]; + // m->px + distances.add(distance / mapcontroller.pixel2MeterRatio); + } + plumDataController.distanceOfCenter.value = distances; + updateCount++; + editTask(task); + loadTasks(); + Map data = task.toJson(); + setTask(data); + update(); + }); + TaskItem? loadtask = getTask(); + if (loadtask != null) { + currentask.value = loadtask; + } + } + + Future> _getLocalFiles() async { + final directory = await getApplicationDocumentsDirectory(); + final folder = Directory('${directory.path}/tasks'); + + // 检查文件夹是否存在,不存在则创建 + if (!await folder.exists()) { + await folder.create(recursive: true); + } + + // 获取所有 JSON 文件 + return folder + .listSync() + .whereType() + .where((file) => file.path.endsWith('.json')) + .toList(); + } + + Future> readAllTaskItems() async { + List allTasks = []; + List files = await _getLocalFiles(); + + for (File file in files) { + try { + String contents = await file.readAsString(); + + allTasks.add(TaskItem.fromJson(jsonDecode(contents))); + } catch (e) { + // 处理读取文件或解析 JSON 的错误 + log('Error reading ${file.path}: $e'); + } + } + + return allTasks; + } + + Future loadTasks() async { + List tasks = await readAllTaskItems(); + taskList.value = tasks; + } + + Future editTask(TaskItem info) async { + final directory = await getApplicationDocumentsDirectory(); + final filePath = '${directory.path}/tasks/${info.utc}.json'; + final file = File(filePath); + Map data = info.toJson(); + String jsonString = jsonEncode(data); + + // 写入 JSON 字符串到文件 + await file.writeAsString(jsonString); + } + + setTask(Map data) { + box.write('task', data); + } + + TaskItem? getTask() { + final p = box.read("task"); + if (p != null) { + return TaskItem.fromJson(p); + } + return null; + } } + +// 任务问题 +// 2. 二次进入任务页面 可设置的点不重合 +// 3. 移动之后 点有问题 (中心点点完之后就跑了) +// 4. 当没点坐标 就点了方向设置就坏了 +// 5. 当list 删除部分点之后保存数据有问题(over 直接删了保存到文件中 合适吗?) +// 状态 (规划 完成 不在规划范围内) \ No newline at end of file diff --git a/lib/service/base.dart b/lib/service/base.dart index f36f4ee..61fdbec 100644 --- a/lib/service/base.dart +++ b/lib/service/base.dart @@ -2,38 +2,70 @@ import 'dart:convert'; import 'dart:developer'; import 'dart:io'; import 'package:cpnav/models/pilePoint/coord_trans.dart'; +import 'package:cpnav/pages/setting/setting_controller.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import 'package:http/http.dart' as http; +import '../main.dart'; import 'user/loginprefs.dart'; - LoginPrefs loginPrefs = LoginPrefs(); +SettingController settingController = Get.put(SettingController()); +GetServices services = settingController.services; class BaseService { //创建client实例 final _client = http.Client(); - final String token = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc1IiOjAsInJvbGVJZHMiOlsiMSIsIjI0Il0sInVzZXJuYW1lIjoiYWRtaW4iLCJ1c2VySWQiOjEsIlBWIjo1LCJvcmciOiJhIiwiaWF0IjoxNzMwNzg3MDE3LCJleHAiOjE3MzIwODMwMTd9.hhWpQAqv160E6tNi5ymyHigzRzZTM4CfwSsraomvJWM"; - - // String baseUrl = "http://192.168.1.154:8001";//本地 + String token = ""; + // String baseUrl = "http://192.168.1.154:8001"; //本地 String baseUrl = "http://v5.rdc.pub"; //线上 String loginstatus = "登录失效"; + Duration timeout = const Duration(seconds: 10); //发送GET请求 getClient(String url, [bool useBaseUrl = true]) async { + checkExpire(); + if (token == "") { + token = loginPrefs.getToken(); + } + try { - Uri fullUrl =Uri.parse(useBaseUrl ? (baseUrl + url) : url); - http.Response response = await _client - .get(fullUrl, headers: { + Uri fullUrl = Uri.parse(useBaseUrl ? (baseUrl + url) : url); + // log("请求地址: $fullUrl \n token: $token"); + http.Response response = await _client.get(fullUrl, headers: { HttpHeaders.contentTypeHeader: "application/json", HttpHeaders.authorizationHeader: token, - }); + }).timeout(timeout); var res = json.decode(response.body); if (res['message'].contains(loginstatus)) { loginPrefs.clearLogin(); return; } - return res; + if (res['code'] == 1000) { + return res; + } else { + log(res); + String msg = res['message'].toString(); + if (res['code'] == 404) { + msg = "当前接口不存在:$msg"; + } + scaffoldMessengerKey.currentState?.showSnackBar( + SnackBar( + content: Text('发生错误: $msg'), + duration: const Duration(seconds: 5), + backgroundColor: Colors.red, + ), + ); + return {}; + } } catch (e) { + scaffoldMessengerKey.currentState?.showSnackBar( + SnackBar( + content: Text('发生错误: ${e.toString()}'), + duration: const Duration(seconds: 5), + backgroundColor: Colors.red, + ), + ); log(e.toString()); return {}; } @@ -41,14 +73,21 @@ class BaseService { //发送POST请求 postClient(String url, body) async { + checkExpire(); + if (token == "") { + token = loginPrefs.getToken(); + } + try { var data = json.encode(body); - http.Response response = await _client.post(Uri.parse(baseUrl + url), - headers: { - HttpHeaders.contentTypeHeader: "application/json", - HttpHeaders.authorizationHeader: token, - }, - body: data); + http.Response response = await _client + .post(Uri.parse(baseUrl + url), + headers: { + HttpHeaders.contentTypeHeader: "application/json", + HttpHeaders.authorizationHeader: token, + }, + body: data) + .timeout(timeout); var res = json.decode(response.body); if (res['message'].contains(loginstatus)) { loginPrefs.clearLogin(); @@ -60,78 +99,114 @@ class BaseService { return {}; } } + + checkExpire() { + int old = loginPrefs.getRefreshExpire(); + int now = DateTime.now().millisecond; + + if (now - old <= 2000) { + //2s + refreshToken(); + } + } + + refreshToken() async { + String refreshToken = loginPrefs.getRefreshToken(); + if (refreshToken == "") { + token = ""; + return; + } + try { + Uri fullUrl = Uri.parse( + "$baseUrl/admin/base/open/refreshToken?refreshToken=$refreshToken"); + http.Response response = await _client.get(fullUrl).timeout(timeout); + var res = json.decode(response.body); + + if (res['code'] == 1000 && res["data"] != null) { + token = res["data"]["token"]; + loginPrefs.saveExpire(res["data"]["expire"]); + loginPrefs.saveToken(token); + loginPrefs.saveRefreshToken(res["data"]["refreshToken"]); + loginPrefs.saveRefreshExpire(res["data"]["refreshExpire"]); + } + } catch (e) { + log("refreshToken error: $e"); + } + + } } class GetServices { BaseService service = BaseService(); // String projCode = 'CJGKJEBYYB'; - // int tid = 109; - String projType; - String projCode; - GetServices({this.projCode = "", this.projType = ""}); + // int tid = 0; + // String projType = ""; + // String projCode = ""; + // String org_code = "a"; + // int tid = 1000; - // String projType = "pile_cm"; + // 道路边线 - Future getSideLine() async { + getSideLine(projCode, projType) async { try { - Map res = await service.getClient( + Map? res = await service.getClient( '/api/comm/side_line/list?proj_code=$projCode&proj_type=$projType'); - return res['data']; + if (res != null && res['data'] != null) { + return res['data']; + } } catch (e) { - return {}; + return null; } + return null; } // 设备绑定 --- 获取设备 - Future getDeviceBind() async { + Future getDeviceBind(projType, projCode) async { Map res = await service.getClient( - // '/api/sys/device_bind/list?proj_type=$projType&proj_code=$projCode'); - // if (res['code'] == 1000) { - // return res['data']; - // } else { - // return []; - // } '/api/sys/device_bind/list?proj_type=$projType&proj_code=$projCode'); - if (res['code'] == 1000) { + if (res['data'] != null) { return res['data']; - } else { - return []; } + + return []; } // 项目列表 - getproject() async { - Map res = await service - .getClient('/api/sys/project/list?org_code=a&proj_type=$projType'); - return res['data']; + getproject(org_code, projType) async { + Map res = await service.getClient( + '/api/sys/project/list?org_code=$org_code&proj_type=$projType'); + if (res['data'] != null) { + return res['data']; + } + return []; } // 液压夯 - // getRcordData(int page, int size, String date, - // [String sort = "desc", String order = "tp_id"]) async { - // Map res = await service.getClient( - // "/api/$projType/record/page?page=$page&size=$size&org_code=a&proj_code=$projCode&date=$date&sort=$sort&order=$order"); - // return res['data']; - // } + getRcordData(projType, org_code, projCode, int page, int size, String date, + [String sort = "desc", String order = "tp_id"]) async { + Map res = await service.getClient( + "/api/$projType/record/page?page=$page&size=$size&org_code=$org_code&proj_code=$projCode&date=$date&sort=$sort&order=$order"); + return res['data']; + } //获取水泥搅拌桩点数据 // getRcordData(int page, int size, String date, // [String sort = "desc", String order = "pile_id"]) async { // Map res = await service.getClient( - // "/api/$projType/record/page?page=$page&size=$size&org_code=a&proj_code=$projCode&tid=$tid&date=$date&sort=$sort&order=$order"); + // "/api/$projType/record/page?page=$page&size=$size&org_code=$org_code&proj_code=$projCode&tid=$tid&date=$date&sort=$sort&order=$order"); // return res['data']; // } // getRcordList(String date, String? dateEnd) async { // dateEnd ??= date; // Map res = await service.getClient( - // "/api/$projType/record/list?org_code=a&proj_code=$projCode&tid=$tid&date=$date&dateEnd=$dateEnd"); + // "/api/$projType/record/list?org_code=$org_code&proj_code=$projCode&tid=$tid&date=$date&dateEnd=$dateEnd"); // return res['data']; // } // getRcordList(String date, [String? dateEnd]) async { // dateEnd ??= date; // Map res = await service.getClient( - // "/api/$projType/record/list?org_code=a&proj_code=$projCode&date=$date&dateEnd=$dateEnd"); + // "/api/$projType/record/list?org_code=$org_code&proj_code=$projCode&date=$date&dateEnd=$dateEnd"); // if (res['code'] == 1000) { // return res['data']; // } else { @@ -140,21 +215,25 @@ class GetServices { // } //获取施工记录的日期 - getworkDateData() async { + getworkDateData( + String org_code, String projCode, String projType, int tid) async { Map res = await service.getClient( - "/api/$projType/record/work_date?org_code=a&proj_code=$projCode"); - if (res['code'] == 1000) { - return res['data'] ?? []; - } else { - return []; + "/api/$projType/record/work_date?org_code=$org_code&proj_code=$projCode&tid=$tid"); + if (res['data'] != null) { + return res['data']; } + + return []; } //施工详细记录 - getProcessData(int pileId) async { + getProcessData(int pileId, String projCode, String projType) async { Map res = await service.getClient( - "/api/$projType/process/list?pile_id=$pileId&proj_code=$projCode"); - return res['data']; + "/api/$projType/process/list?tpId=$pileId&proj_code=$projCode"); + if (res['data'] != null) { + return res['data']; + } + return []; } // 验证码 @@ -173,15 +252,21 @@ class GetServices { // 获取用户信息 getPerson() async { - Map res = await service.getClient("/admin/base/comm/person"); - return res['data']; + Map? res = await service.getClient("/admin/base/comm/person"); + if (res != null && res['data'] != null) { + return res['data']; + } + return res; } // 验证码 getCaptcha() async { Map res = await service.getClient("/admin/base/open/captcha?height=40&width=150"); - return res['data']; + if (res['data'] != null) { + return res['data']; + } + return {}; } getAccountLogin(String captchaId, String password, String username, @@ -195,40 +280,54 @@ class GetServices { return res; } - getRtuLast() async { + getRtuLast(String projType, String projCode) async { Map res = await service.getClient( "/api/t2n/rtu/rtu_last?proj_type=$projType&proj_code=$projCode"); - return res['data']; + if (res['data'] != null) { + return res['data']; + } + return []; } - getCoordTrans() async { + getCoordTrans(String projType, String projCode) async { Map res = await service.getClient( "/api/comm/coord_trans/list?proj_type=$projType&proj_code=$projCode"); - return res['data']; + if (res['data'] != null) { + return res['data']; + } + return {}; } - //获取水泥搅拌桩点数据 - getRcordData(int page, int size, String date, - [String sort = "desc", String order = "pile_id", int? tid]) async { - Map res = await service.getClient( - "/api/$projType/record/page?page=$page&size=$size&org_code=a&proj_code=$projCode&tid=$tid&date=$date&sort=$sort&order=$order"); - return res['data']; - } + // //获取水泥搅拌桩点数据 + // getRcordData(int page, int size, String date, + // [String sort = "desc", String order = "pile_id", int? tid]) async { + // Map res = await service.getClient( + // "/api/$projType/record/page?page=$page&size=$size&org_code=$org_code&proj_code=$projCode&tid=$tid&date=$date&sort=$sort&order=$order"); + // if (res['data'] != null) { + // return res['data']; + // } + // return []; + // } - getRcordList(String date, [String? dateEnd, int? tid]) async { + getRcordList(String org_code, String projCode, String projType, String date, + [String? dateEnd, int? tid]) async { dateEnd ??= date; - Map res = await service.getClient( - "/api/$projType/record/list?org_code=a&proj_code=$projCode&date=$date&dateEnd=$dateEnd"); //&tid=1000 - return res['data']; + Map? res = await service.getClient( + "/api/$projType/record/list?org_code=$org_code&proj_code=$projCode&date=$date&dateEnd=$dateEnd"); //&tid=1000 + if (res != null && res['data'] != null) { + return res['data']; + } + + return []; } - plumAdd(List list) async { + plumAdd(String projType, String projCode, List list) async { // Map res = await service.postClient("/api/$projType/xx/add", {"list": list}); return res; } - getPlumList(String name) async { + getPlumList(String projType, String projCode, String name) async { Map res = await service.getClient( "/api/$projType/xx/list?proj_code=$projCode&name=$name"); //&tid=1000 return res['data']; diff --git a/lib/service/pile_cm.dart b/lib/service/pile_cm.dart deleted file mode 100644 index 1b79eb8..0000000 --- a/lib/service/pile_cm.dart +++ /dev/null @@ -1,109 +0,0 @@ -import 'package:get/get.dart'; -import 'base.dart'; - -// String projCode = 'CJGKJEBYYB'; -// String tid = "109"; -// String projType = "hydraulic_tamping"; -String projCode = 'TEST'; -String tid = "1000"; -String projType = "pile_cm"; -BaseService service = BaseService(); - -class ProjController extends GetxController { - ProjController(); -// 道路边线 - Future getSideLine() async { - Map res = await service.getClient( - '/api/comm/side_line/list?proj_code=$projCode&proj_type=$projType'); - return res['data']; - } - -// 设备绑定 --- 获取设备 - Future getDeviceBind() async { - Map res = await service.getClient( - '/api/sys/device_bind/list?proj_type=$projType&proj_code=$projCode'); - return res['data']; - } - - // 项目列表 - getproject() async { - Map res = await service.getClient( - '/api/sys/project/list?org_code=a&proj_type=$projType&proj_code=$projCode'); - return res['data']; - } -} - -class LoginController { - // 验证码 - getsmsCode(String phone) async { - Map res = - await service.postClient("/admin/base/open/smsCode", {"phone": phone}); - return res; - } - - // 手机号登录 - phoneLogin(String phone, String smsCode) async { - Map res = await service.postClient( - "/admin/base/open/phone", {"phone": phone, "smsCode": smsCode}); - return res; - } - - // 获取用户信息 - getPerson() async { - Map res = await service.getClient("/admin/base/comm/person"); - return res['data']; - } - - // 验证码 - getCaptcha() async { - Map res = - await service.getClient("/admin/base/open/captcha?height=40&width=150"); - return res['data']; - } - - getAccountLogin(String captchaId, String password, String username, - String verifyCode) async { - Map res = await service.postClient("/admin/base/open/login", { - "captchaId": captchaId, - "password": password, - "username": username, - "verifyCode": verifyCode - }); - return res; - } -} - -class PileCmController { - //获取水泥搅拌桩点数据 - getRcordData(int page, int size, String date, - [String sort = "desc", String order = "pile_id"]) async { - Map res = await service.getClient( - "/api/$projType/record/page?page=$page&size=$size&org_code=a&proj_code=$projCode&tid=$tid&date=$date&sort=$sort&order=$order"); - return res['data']; - } - - getRcordList(String date, String? dateEnd) async { - dateEnd ??= date; - Map res = await service.getClient( - "/api/$projType/record/list?org_code=a&proj_code=$projCode&tid=$tid&date=$date&dateEnd=$dateEnd"); - return res['data']; - } - - //获取施工记录的日期 - getworkDateData() async { - Map res = await service.getClient( - "/api/$projType/record/work_date?org_code=a&proj_code=$projCode&tid=$tid"); - if (res['code'] == 1000) { - return res['data'] ?? []; - } else { - return []; - } - } - - //施工详细记录 - getProcessData(int pileId) async { - Map res = await service.getClient( - "/api/$projType/process/list?pile_id=$pileId&proj_code=$projCode&tid=$tid"); - return res['data']; - } -} diff --git a/lib/service/user/loginprefs.dart b/lib/service/user/loginprefs.dart index 6a33920..2cb07d0 100644 --- a/lib/service/user/loginprefs.dart +++ b/lib/service/user/loginprefs.dart @@ -3,6 +3,8 @@ import 'package:get_storage/get_storage.dart'; import 'package:cpnav/models/user.dart'; +import '../base.dart'; + class LoginPrefs extends GetxController { static const String expireStr = "expire"; //用户名 static const String tokenStr = "token"; //token @@ -15,6 +17,8 @@ class LoginPrefs extends GetxController { } void saveExpire(int expire) { + int now = DateTime.now().millisecondsSinceEpoch; + expire = now + expire * 1000; box.write(expireStr, expire); update(); } @@ -23,22 +27,43 @@ class LoginPrefs extends GetxController { return box.read(expireStr) ?? 0; } - void saveToken(String token) { + void saveToken(String token) async { box.write(tokenStr, token); + // 保存用户信息 + var person = await services.getPerson(); + if (person != null) { + UserController().setUser(person); + } update(); } + saveRefreshToken(String token) async { + box.write("refreshToken", token); + } + + String getRefreshToken() { + return box.read("refreshToken") ?? ""; + } + + saveRefreshExpire(int expire) { + int now = DateTime.now().millisecondsSinceEpoch; + expire = now + expire * 1000; + box.write("refreshExpire", expire); + } + + int getRefreshExpire() { + return box.read("refreshExpire") ?? 0; + } + String getToken() { return box.read(tokenStr) ?? ""; } - void removeExpire() { + remove() { box.remove(expireStr); - update(); - } - - void removeToken() { box.remove(tokenStr); + box.remove("refreshToken"); + box.remove("refreshExpire"); update(); } @@ -55,6 +80,12 @@ class LoginPrefs extends GetxController { box.erase(); // 清除所有数据 update(); } + + @override + void dispose() { + super.dispose(); + remove(); + } } class UserController extends GetxController { @@ -62,7 +93,7 @@ class UserController extends GetxController { UserModel? getUser() { final userMap = box.read('user'); - if (userMap != null) { + if (userMap != null && userMap.length > 0) { return UserModel.fromJson(userMap); } return null; diff --git a/pubspec.lock b/pubspec.lock index 4b2d0c7..22fa0d5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -174,6 +174,11 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "3.0.2" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_svg: dependency: "direct main" description: @@ -520,6 +525,14 @@ packages: relative: true source: path version: "0.0.1" + searchfield: + dependency: "direct main" + description: + name: searchfield + sha256: "837721576ca1de1ce40c9841760e40cd7452d3068ea2a22a7b25d06133a7d989" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.7" sky_engine: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 83a13d6..a35fd14 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -60,6 +60,9 @@ dependencies: wifi_iot: ^0.3.19+1 path_provider: ^2.1.4 intl: ^0.19.0 + flutter_localizations: + sdk: flutter + searchfield: ^1.1.7 dev_dependencies: