液压夯
This commit is contained in:
parent
0c480a2d5b
commit
94abe69ac5
File diff suppressed because one or more lines are too long
20
README.md
20
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
|
||||
|
@ -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:
|
||||
|
@ -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<AimPointerController>();
|
||||
final RealController realcontroller = Get.find<RealController>();
|
||||
final TaskController taskcontroller = Get.find<TaskController>();
|
||||
final SettingController settingcontroller = Get.find<SettingController>();
|
||||
|
||||
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(
|
||||
|
@ -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) {
|
||||
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
@ -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<SettingController>();
|
||||
|
||||
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<ScenceMapController>();
|
||||
|
||||
aimcontroller = Get.find<AimPointerController>();
|
||||
if (settingController.currentDevice.value != null) {
|
||||
device = settingController.currentDevice.value!;
|
||||
} else {
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
319
lib/main.dart
319
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<ScaffoldMessengerState> scaffoldMessengerKey =
|
||||
GlobalKey<ScaffoldMessengerState>();
|
||||
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<MyHomePage> createState() => _MyHomePageState();
|
||||
}
|
||||
@ -72,18 +93,41 @@ class MyHomePage extends StatefulWidget {
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
late bool isPortrait;
|
||||
late double appBarHeight = 34.0;
|
||||
bool isInitialized = false;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
SettingController settingController = Get.put(SettingController());
|
||||
|
||||
final List<Widget> _pages = [
|
||||
const Real(),
|
||||
PassTrack(
|
||||
// date: '',
|
||||
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());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!isInitialized) {
|
||||
return const Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
final List<Widget> pages = [
|
||||
// const Real(),
|
||||
PassTrack(),
|
||||
const TaskManagePage(),
|
||||
const HistoryRecord(),
|
||||
const SettingPortrait()
|
||||
];
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
drawerEdgeDragWidth: 0.0, // 禁止通过滑动打开drawer
|
||||
@ -100,12 +144,14 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
appBarHeight = Orientation.portrait == orientation ? 56.0 : 34.0;
|
||||
isPortrait = Orientation.portrait == orientation ? true : false;
|
||||
appBarHeight = Orientation.portrait == orientation ? 56.0 : 34.0;
|
||||
return Obx(() {
|
||||
appcontroller.currentIndex.value;
|
||||
if (!isPortrait) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Expanded(
|
||||
child: _pages[appcontroller.currentIndex.value],
|
||||
child: pages[appcontroller.currentIndex.value],
|
||||
),
|
||||
const VerticalDivider(
|
||||
width: 1, // 设置高度为1
|
||||
@ -121,165 +167,40 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
// 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(),
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
buildIconButton(
|
||||
context: context,
|
||||
index: 1,
|
||||
icon: Icons.my_location_sharp,
|
||||
label: '任务',
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
buildIconButton(
|
||||
context: context,
|
||||
index: 2,
|
||||
icon: Icons.table_chart_outlined,
|
||||
label: '历史',
|
||||
),
|
||||
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,
|
||||
buildIconButton(
|
||||
context: context,
|
||||
index: 3,
|
||||
icon: Icons.settings,
|
||||
label: '设置',
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
'设置',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color:
|
||||
appcontroller.currentIndex.value ==
|
||||
4
|
||||
? const Color.fromARGB(
|
||||
255, 60, 95, 123)
|
||||
: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
]);
|
||||
//
|
||||
}),
|
||||
@ -295,7 +216,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: _pages[appcontroller.currentIndex.value],
|
||||
child: pages[appcontroller.currentIndex.value],
|
||||
),
|
||||
// VerticalDivider(),
|
||||
Expanded(
|
||||
@ -311,9 +232,9 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
});
|
||||
},
|
||||
items: const [
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.date_range_rounded),
|
||||
label: "实时"),
|
||||
// BottomNavigationBarItem(
|
||||
// icon: Icon(Icons.date_range_rounded),
|
||||
// label: "实时"),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.map_outlined), label: "计划"),
|
||||
BottomNavigationBarItem(
|
||||
@ -329,8 +250,46 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
)
|
||||
]);
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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<AimPointerController>();
|
||||
final ScenceMapController mapcontroller = Get.find<ScenceMapController>();
|
||||
final GnssController gnsscontroller = Get.find<GnssController>();
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class AimPointer extends GetView<AimPointerController> {
|
||||
@ -27,7 +26,7 @@ class AimPointer extends GetView<AimPointerController> {
|
||||
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<AimPointerController> {
|
||||
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,
|
||||
|
@ -104,15 +104,11 @@ class _CanlenderSelectState extends State<CanlenderSelect> {
|
||||
}) {
|
||||
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<CanlenderSelect> {
|
||||
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<CanlenderSelect> {
|
||||
|
||||
return valueText;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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<HistoryRecord> {
|
||||
}
|
||||
|
||||
PageSyncApproach pageSyncApproach = PageSyncApproach.doNothing;
|
||||
|
||||
List<TableCol> tableTitle = [
|
||||
// 不能设置宽度超过 一定的值 不然会报错 尽量不设置宽度 剩余更多的宽度来均分
|
||||
TableCol("pileId", "桩点", 60, null
|
||||
TableCol("tpId", "桩点", 80, null
|
||||
// (columnIndex, ascending) =>
|
||||
// sort<num>((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<DataColumn2> tableTitleWidget = [];
|
||||
TextStyle fontstyle = const TextStyle(fontSize: 20);
|
||||
@ -62,12 +56,13 @@ class _HistoryRecordState extends State<HistoryRecord> {
|
||||
|
||||
@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<num>((d) => d.pileId, columnIndex, ascending);
|
||||
sort<num>((d) => d.tpId, columnIndex, ascending);
|
||||
_asyncrecordsDataSource.sort(row.props, _sortAscending);
|
||||
};
|
||||
}
|
||||
@ -93,14 +88,9 @@ class _HistoryRecordState extends State<HistoryRecord> {
|
||||
}
|
||||
}
|
||||
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<HistoryRecord> {
|
||||
|
||||
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 {
|
||||
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<HistoryRecord> {
|
||||
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<HistoryRecord> {
|
||||
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<HistoryRecord> {
|
||||
_asyncrecordsDataSource.refreshDatasource();
|
||||
},
|
||||
columns: tableTitleWidget,
|
||||
|
||||
source: _asyncrecordsDataSource,
|
||||
empty: Center(
|
||||
child: Container(
|
||||
|
40
lib/pages/history/line_chart.dart
Normal file
40
lib/pages/history/line_chart.dart
Normal file
@ -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<MyLineChart> createState() => _MyLineChartState();
|
||||
}
|
||||
|
||||
class _MyLineChartState extends State<MyLineChart> {
|
||||
@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,
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
@ -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<AsyncRowsResponse> 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(
|
||||
onPressed: () {
|
||||
String date = DateFormat('yyyy-MM-dd').format(item.startTime);
|
||||
|
||||
children: [],
|
||||
// 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<RecordFakeWebServiceResponse> getData(
|
||||
int startingAt, int count, Map? data) async {
|
||||
if (data == null) {
|
||||
return RecordFakeWebServiceResponse(0, []);
|
||||
}
|
||||
List<RecordEntity> result = [];
|
||||
|
||||
for (var i = 0; i < (data!["list"] as List).length; i++) {
|
||||
RecordEntity item = RecordEntity.fromJson(data["list"][i]);
|
||||
List<dynamic> 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());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -44,16 +44,16 @@ class Login extends GetView<LoginPageController> {
|
||||
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,35 +79,22 @@ class AccountLoginController extends GetxController {
|
||||
}
|
||||
|
||||
Future<void> changeCaptcha() async {
|
||||
var captcha = await GetServices().getCaptcha();
|
||||
var captcha = await services.getCaptcha();
|
||||
if (captcha['data'] != null) {
|
||||
svgString.value = captcha['data'];
|
||||
captchaId.value = captcha['captchaId'];
|
||||
}
|
||||
}
|
||||
|
||||
void showErrorSnackbar(String text) {
|
||||
final snackBar = SnackBar(
|
||||
content: Text(text),
|
||||
backgroundColor: Colors.red,
|
||||
);
|
||||
|
||||
if (Get.context != null) {
|
||||
ScaffoldMessenger.of(Get.context!).showSnackBar(snackBar);
|
||||
}
|
||||
|
||||
// Future<void> 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<AccountLoginController> {
|
||||
@ -205,6 +192,10 @@ class AccountLoginPage extends GetView<AccountLoginController> {
|
||||
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<AccountLoginController> {
|
||||
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<AccountLoginController> {
|
||||
} 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();
|
||||
// 收回键盘
|
||||
if (Get.context != null) {
|
||||
FocusScope.of(Get.context!).unfocus();
|
||||
await GetServices().getsmsCode(phoneNumber.value);
|
||||
}
|
||||
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'); // 跳转至首页
|
||||
}
|
||||
}
|
||||
|
@ -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<String, Widget> routes = {
|
||||
'home': const MyHomePage(), //定义app路径
|
||||
'login': const Login(), //定义login路径
|
||||
};
|
||||
|
||||
/*
|
||||
* 这个方法是固定写法,功能就像是一个拦截器。
|
||||
*/
|
||||
Route<dynamic>? onGenerateRoute(RouteSettings settings) {
|
||||
Map<String, Widget> 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<dynamic>? 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) {
|
||||
|
@ -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<SettingController>();
|
||||
|
||||
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<RecordEntity?> selectedPilePoint = Rx<RecordEntity?>(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);
|
||||
}
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
@ -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<PassTrack> createState() => _PasstrackState();
|
||||
// }
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class PassTrack extends GetView<PassTrackController> {
|
||||
// final GlobalKey<PopupMenuButtonState<int>> _popupMenuKey =
|
||||
// GlobalKey<PopupMenuButtonState<int>>();
|
||||
RecordEntity? currentPoint;
|
||||
@override
|
||||
final controller = Get.put(PassTrackController("TEST", "pile_cm"));
|
||||
final controller = Get.put(PassTrackController());
|
||||
final aimcontroller = Get.find<AimPointerController>();
|
||||
// String str = "播放";
|
||||
// int sWidth = 0;
|
||||
@ -39,63 +42,26 @@ class PassTrack extends GetView<PassTrackController> {
|
||||
// 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<void> 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) {
|
||||
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: [
|
||||
@ -103,15 +69,13 @@ class PassTrack extends GetView<PassTrackController> {
|
||||
onUpdate: (Offset center, double scale, double rotation) {
|
||||
log("center:$center scale:$scale rotation:$rotation");
|
||||
},
|
||||
forGroundPainter: appcontroller.currentIndex.value == 1
|
||||
? BorderPainter(controller)
|
||||
: null,
|
||||
forGroundPainter: forGroundPainter,
|
||||
onUpdatePilePoint: (RecordEntity? selectedPilePoint, double scale,
|
||||
double rotation) {
|
||||
log(
|
||||
"selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation");
|
||||
controller.selectedPilePoint = selectedPilePoint;
|
||||
log("selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation");
|
||||
controller.selectedPilePoint.value = selectedPilePoint;
|
||||
aimcontroller.selectedPilePoint = selectedPilePoint;
|
||||
controller.updateCount.value++;
|
||||
},
|
||||
children: const [],
|
||||
),
|
||||
@ -120,6 +84,7 @@ class PassTrack extends GetView<PassTrackController> {
|
||||
],
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
@ -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<ProcessChart> {
|
||||
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;
|
||||
|
@ -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<String, dynamic> 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"],
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
@ -122,24 +122,29 @@ class RealDataShow extends StatelessWidget {
|
||||
// final orientation = MediaQuery.of(context).orientation;
|
||||
// bool isPortrait = Orientation.portrait == orientation ? true : false;
|
||||
// 创建数据项列表
|
||||
// pile_cm
|
||||
// List<DataItem> 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<DataItem> 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(
|
||||
|
@ -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');
|
||||
|
@ -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<AntennaController> {
|
||||
const AntennaSetting({super.key});
|
||||
|
@ -24,7 +24,7 @@ class _PersonDetailsState extends State<PersonDetails> {
|
||||
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 {}
|
||||
|
35
lib/pages/setting/project/model.dart
Normal file
35
lib/pages/setting/project/model.dart
Normal file
@ -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<String, dynamic> json) {
|
||||
return ProjectModel(
|
||||
groups: json['groups'],
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
options: json['options'],
|
||||
orgCode: json['org_code'],
|
||||
projCode: json['proj_code']);
|
||||
}
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'groups': groups,
|
||||
'id': id,
|
||||
'name': name,
|
||||
'options': options,
|
||||
'org_code': orgCode,
|
||||
'proj_code': projCode
|
||||
};
|
||||
}
|
||||
}
|
169
lib/pages/setting/project/view.dart
Normal file
169
lib/pages/setting/project/view.dart
Normal file
@ -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<SettingController>();
|
||||
|
||||
class ProjectView extends GetView<SettingController> {
|
||||
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<DropdownProject> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SettingController controller = widget.controller;
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
PopupMenuButton<String>(
|
||||
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<PopupMenuEntry<String>>((ProjectModel value) {
|
||||
return PopupMenuItem<String>(
|
||||
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<DropdownDevice> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SettingController controller = widget.controller;
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
PopupMenuButton<String>(
|
||||
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<PopupMenuEntry<String>>((DeviceItem value) {
|
||||
return PopupMenuItem<String>(
|
||||
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),
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
115
lib/pages/setting/setting_controller.dart
Normal file
115
lib/pages/setting/setting_controller.dart
Normal file
@ -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<ScenceMapController>();
|
||||
PassTrackController passTrackController = Get.find<PassTrackController>();
|
||||
|
||||
final box = GetStorage(); // 实例化 GetStorage
|
||||
|
||||
class SettingController extends GetxController {
|
||||
String projType = "hydraulic_tamping";
|
||||
List<ProjectModel> projectList = [];
|
||||
Rx<ProjectModel?> currentProject = Rx<ProjectModel?>(null);
|
||||
List<DeviceItem> deviceList = [];
|
||||
Rx<DeviceItem?> currentDevice = Rx<DeviceItem?>(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;
|
||||
}
|
||||
}
|
@ -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<SettingPortrait> {
|
||||
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: <Widget>[
|
||||
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: <Widget>[
|
||||
// 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()));
|
||||
|
217
lib/pages/task/info.dart
Normal file
217
lib/pages/task/info.dart
Normal file
@ -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<TaskController> {
|
||||
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: <Widget>[
|
||||
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("确定"),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
87
lib/pages/task/model.dart
Normal file
87
lib/pages/task/model.dart
Normal file
@ -0,0 +1,87 @@
|
||||
import 'package:scence_map/controllers/controller.dart';
|
||||
|
||||
class TaskItem {
|
||||
int id;
|
||||
int utc;
|
||||
String name;
|
||||
int workTotal;
|
||||
List<PilePoint> 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<dynamic, dynamic> 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<dynamic>)
|
||||
.map((item) => PilePoint.fromJson(item))
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
Map<String, dynamic> 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<double> 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<String, dynamic> data) {
|
||||
return CenterPileInfo(
|
||||
x: data['x'],
|
||||
y: data['y'],
|
||||
// direction: data['direction'],
|
||||
space: data['space'],
|
||||
pileWidth: data['pileWidth'],
|
||||
angle: data['angle'],
|
||||
distances: List<double>.from(
|
||||
data['distances'].map((item) => (item ?? 10).toDouble())),
|
||||
);
|
||||
}
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'x': x,
|
||||
'y': y,
|
||||
// 'direction': direction,
|
||||
'space': space,
|
||||
'pileWidth': pileWidth,
|
||||
'angle': angle,
|
||||
'distances': distances,
|
||||
};
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -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<ScenceMapController>();
|
||||
final PlumDataController controller = Get.find<PlumDataController>();
|
||||
final TaskController taskcontroller = Get.put(TaskController());
|
||||
|
||||
class PileGenerate extends StatefulWidget {
|
||||
const PileGenerate({super.key});
|
||||
|
||||
@override
|
||||
PileGenerateState createState() => PileGenerateState();
|
||||
}
|
||||
|
||||
class PileGenerateState extends State<PileGenerate> {
|
||||
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(),
|
||||
),
|
||||
]))
|
||||
]))));
|
||||
}
|
||||
}
|
@ -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<PilePoint> pilePoints;
|
||||
final Function(List<PilePoint>) 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<PilePointTable> {
|
||||
List<bool> _selected = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_selected = List<bool>.filled(widget.pilePoints.length, false);
|
||||
}
|
||||
|
||||
void _deleteSelected() {
|
||||
setState(() {
|
||||
widget.pilePoints
|
||||
.removeWhere((point) => _selected[widget.pilePoints.indexOf(point)]);
|
||||
_selected = List<bool>.filled(widget.pilePoints.length, false);
|
||||
widget.pilePoints.removeWhere((point) => point.isSelected);
|
||||
|
||||
widget.onUpdate(widget.pilePoints);
|
||||
});
|
||||
}
|
||||
@ -40,10 +38,21 @@ class PilePointTableState extends State<PilePointTable> {
|
||||
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(
|
||||
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),
|
||||
@ -51,67 +60,57 @@ class PilePointTableState extends State<PilePointTable> {
|
||||
columnWidths: const {
|
||||
0: IntrinsicColumnWidth(),
|
||||
1: IntrinsicColumnWidth(),
|
||||
2: IntrinsicColumnWidth(),
|
||||
3: IntrinsicColumnWidth(),
|
||||
2: FlexColumnWidth(),
|
||||
3: FlexColumnWidth(),
|
||||
},
|
||||
children: [
|
||||
const TableRow(
|
||||
TableRow(
|
||||
children: [
|
||||
Center(child: Text('选择')),
|
||||
Center(child: Text('ID')),
|
||||
Center(child: Text('X')),
|
||||
Center(child: Text('Y')),
|
||||
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')),
|
||||
],
|
||||
),
|
||||
...List<TableRow>.generate(
|
||||
widget.pilePoints.length,
|
||||
(index) => TableRow(
|
||||
children: [
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0),
|
||||
child: Checkbox(
|
||||
value: _selected[index],
|
||||
_buildTableCell(
|
||||
Checkbox(
|
||||
value: widget.pilePoints[index].isSelected,
|
||||
onChanged: (bool? value) {
|
||||
setState(() {
|
||||
_selected[index] = value ?? false;
|
||||
widget.pilePoints[index].isSelected =
|
||||
value ?? false;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
_buildTableCell(
|
||||
Text(widget.pilePoints[index].id.toString()),
|
||||
),
|
||||
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(
|
||||
_buildTableCell(
|
||||
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(
|
||||
_buildTableCell(
|
||||
GestureDetector(
|
||||
onTap: () => _editPilePoint(context, index, 'y'),
|
||||
child: Text(widget.pilePoints[index].y.toString()),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -164,4 +163,14 @@ class PilePointTableState extends State<PilePointTable> {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTableCell(Widget child) {
|
||||
return TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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<ScenceMapController>();
|
||||
|
||||
@ -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,78 +41,212 @@ 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<Offset> rect = getRect(controller.distancesOffset);
|
||||
List<Offset> 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<Offset> circlePoints = [];
|
||||
// List<Offset> 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);
|
||||
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);
|
||||
|
||||
// Offset xy = mapController.screen2xy0(upPoint);
|
||||
// Offset xy1 = mapController.screen2xy0(downPoint);
|
||||
controller.plumList.add(upPoint);
|
||||
controller.plumList.add(downPoint);
|
||||
if ((j % 2 == p % 2) == centerEven) {
|
||||
Offset xy1 = mapController.screen2xy0(downPoint);
|
||||
controller.plumList.add(xy1);
|
||||
}
|
||||
}
|
||||
|
||||
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<Offset> list) {
|
||||
List<Offset> 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<Offset> 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;
|
||||
|
@ -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<TaskController>();
|
||||
final ScenceMapController mapController = Get.find<ScenceMapController>();
|
||||
|
||||
class RealView extends StatefulWidget {
|
||||
const RealView({super.key});
|
||||
class TaskView extends StatefulWidget {
|
||||
const TaskView({super.key});
|
||||
|
||||
@override
|
||||
State<RealView> createState() => _RealViewState();
|
||||
State<TaskView> createState() => _TaskViewState();
|
||||
}
|
||||
|
||||
class _RealViewState extends State<RealView> {
|
||||
final ScenceMapController scenceMapController =
|
||||
Get.put(ScenceMapController());
|
||||
class _TaskViewState extends State<TaskView> {
|
||||
final controller = Get.find<PlumDataController>();
|
||||
late StepDialogManager _showStepDialog;
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
@ -36,28 +39,66 @@ class _RealViewState extends State<RealView> {
|
||||
@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<PilePoint> 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<RealView> {
|
||||
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<RealView> {
|
||||
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<RealView> {
|
||||
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<RealView> {
|
||||
],
|
||||
),
|
||||
child: Obx(() {
|
||||
////必须写 因为 需要监听 -- 的值发生变化 刷新
|
||||
controller.updateCount;
|
||||
List<Offset> buttons = controller.distancesOffset;
|
||||
|
||||
controller.linePointOffset.value;
|
||||
controller.isUp.value;
|
||||
return CustomPaint(
|
||||
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<Widget> 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),
|
||||
foregroundPainter: DrawDirection(
|
||||
controller, scOffset, isDarkMode, isInit),
|
||||
// child:
|
||||
),
|
||||
...buttonsList
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
@ -154,17 +225,18 @@ class _RealViewState extends State<RealView> {
|
||||
// 桩点生成时返回按钮
|
||||
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<RealView> {
|
||||
),
|
||||
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(
|
||||
|
||||
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(() => AbsorbPointer(
|
||||
Obx(() {
|
||||
controller.isGenerate.value;
|
||||
return AbsorbPointer(
|
||||
absorbing: controller.isGenerate.value
|
||||
? true
|
||||
: false, //设置CenterLayout 内的GestureDetector 不生效
|
||||
// child: const ScenceMapView(
|
||||
// children: [],
|
||||
// ),
|
||||
|
||||
child: const TaskPage(), // 任务页面
|
||||
// PassTrack(
|
||||
// date: '',
|
||||
// )
|
||||
)),
|
||||
);
|
||||
}),
|
||||
center,
|
||||
back,
|
||||
const PileGenerateCard1()
|
||||
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<PilePoint> 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);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
@ -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<ScenceMapController>();
|
||||
final pscontroller = Get.put(PassTrackController());
|
||||
final TaskController taskcontroller = Get.find<TaskController>();
|
||||
|
||||
// class TaskPage extends StatelessWidget {
|
||||
class TaskPage extends StatefulWidget {
|
||||
@ -122,197 +29,156 @@ class TaskPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class TaskPageState extends State<TaskPage> {
|
||||
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(
|
||||
return ScenceMapView(
|
||||
onUpdate: (Offset center, double scale, double rotation) {
|
||||
log("center:$center scale:$scale rotation:$rotation");
|
||||
},
|
||||
forGroundPainter: appcontroller.currentIndex.value == 1
|
||||
? BorderPainter(controller)
|
||||
? BorderPainter(pscontroller)
|
||||
: null,
|
||||
onUpdatePilePoint: (RecordEntity? selectedPilePoint, double scale,
|
||||
double rotation) {
|
||||
log(
|
||||
"selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation");
|
||||
onUpdatePilePoint:
|
||||
(RecordEntity? selectedPilePoint, double scale, double rotation) {
|
||||
log("selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation");
|
||||
},
|
||||
children: const [],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TaskManagePage extends GetView<TaskController> {
|
||||
const TaskManagePage({super.key});
|
||||
|
||||
@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<Widget> 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("新增"),
|
||||
),
|
||||
// ),
|
||||
if (pilecontroller.isPileCardVisible.value)
|
||||
const PileGenerateCard(),
|
||||
],
|
||||
))
|
||||
],
|
||||
);
|
||||
}));
|
||||
}
|
||||
|
||||
addDialog(context) {
|
||||
// 点击新增按钮时显示弹窗
|
||||
TaskItem addTask = TaskItem(
|
||||
list: [],
|
||||
name: " ",
|
||||
id: 0,
|
||||
utc: 0,
|
||||
originLabel: "本地",
|
||||
workTotal: 0,
|
||||
centerPileInfo: CenterPileInfo(
|
||||
x: 0,
|
||||
y: 0,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
//对话框
|
||||
class StepDialogManager {
|
||||
final BuildContext context;
|
||||
final List<String> _stepTexts = [
|
||||
'点击屏幕即可确定桩点中心。',
|
||||
'这是步骤 2 的提示对话框。',
|
||||
'这是步骤 3 的提示对话框。',
|
||||
'点击方向设置按钮和输入宽度值可设置桩点范围。',
|
||||
'手指在屏幕上拖动可确定桩点范围'
|
||||
];
|
||||
|
||||
StepDialogManager(this.context);
|
||||
|
||||
void showStepDialog(int step) {
|
||||
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: <Widget>[
|
||||
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("确定"),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -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<bool> isDialogShown = [false, false, false, false, false].obs;
|
||||
final box = GetStorage(); // 实例化 GetStorage
|
||||
// List<bool> 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 = <TaskItem>[].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<double> 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<List<File>> _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<File>()
|
||||
.where((file) => file.path.endsWith('.json'))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<List<TaskItem>> readAllTaskItems() async {
|
||||
List<TaskItem> allTasks = [];
|
||||
List<File> 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<void> loadTasks() async {
|
||||
List<TaskItem> tasks = await readAllTaskItems();
|
||||
taskList.value = tasks;
|
||||
}
|
||||
|
||||
Future<void> 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 直接删了保存到文件中 合适吗?)
|
||||
// 状态 (规划 完成 不在规划范围内)
|
@ -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 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: {
|
||||
// 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;
|
||||
}
|
||||
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),
|
||||
http.Response response = await _client
|
||||
.post(Uri.parse(baseUrl + url),
|
||||
headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: token,
|
||||
},
|
||||
body: data);
|
||||
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');
|
||||
if (res != null && res['data'] != null) {
|
||||
return res['data'];
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
} catch (e) {
|
||||
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');
|
||||
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,22 +215,26 @@ 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");
|
||||
"/api/$projType/process/list?tpId=$pileId&proj_code=$projCode");
|
||||
if (res['data'] != null) {
|
||||
return res['data'];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
// 验证码
|
||||
getsmsCode(String phone) async {
|
||||
@ -173,16 +252,22 @@ class GetServices {
|
||||
|
||||
// 获取用户信息
|
||||
getPerson() async {
|
||||
Map res = await service.getClient("/admin/base/comm/person");
|
||||
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");
|
||||
if (res['data'] != null) {
|
||||
return res['data'];
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
getAccountLogin(String captchaId, String password, String username,
|
||||
String verifyCode) async {
|
||||
@ -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");
|
||||
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");
|
||||
if (res['data'] != null) {
|
||||
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=a&proj_code=$projCode&tid=$tid&date=$date&sort=$sort&order=$order");
|
||||
return res['data'];
|
||||
return {};
|
||||
}
|
||||
|
||||
getRcordList(String date, [String? dateEnd, int? tid]) async {
|
||||
// //获取水泥搅拌桩点数据
|
||||
// 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 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
|
||||
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'];
|
||||
}
|
||||
|
||||
plumAdd(List<PointXY> list) async {
|
||||
return [];
|
||||
}
|
||||
|
||||
plumAdd(String projType, String projCode, List<PointXY> 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'];
|
||||
|
@ -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'];
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
13
pubspec.lock
13
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
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user