液压夯

This commit is contained in:
刘媛 2024-11-15 17:42:52 +08:00
parent 0c480a2d5b
commit 94abe69ac5
40 changed files with 2635 additions and 1694 deletions

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

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

View File

@ -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>();
device = DeviceItem(
name: 'GNSS',
tid: 1001,
type: 2,
height: 3.0,
width: 3.0,
lat: 3790621.123,
lon: 577052.547,
image: ['assets/images/pilerCar.png']);
mapController.addDevice(device);
if (settingController.currentDevice.value != null) {
device = settingController.currentDevice.value!;
} else {
device = DeviceItem(
name: "",
tid: 0,
type: "",
height: 0.0,
width: 0.0,
image: "",
);
}
if (device.x.value == 0 && device.y.value == 0) {
device.x.value = 3790621.123;
device.y.value = 577052.547;
}
// device = DeviceItem(
// name: 'GNSS',
// tid: 1001,
// // type: 2,
// height: 3.0,
// width: 3.0,
// lat: 3790621.123,
// lon: 577052.547,
// image: 'assets/images/pilerCar.png');
// mapController.addDevice(device);
// pilerCenterPoint = PilerPointCalculate(
// maindrilldistance.value,
// auxdrilldistance.value,
@ -91,26 +112,25 @@ class GnssController extends GetxController {
if (lastPilePoint != aimcontroller.selectedPilePoint) {
lastPilePoint = aimcontroller.selectedPilePoint;
if (aimcontroller.selectedPilePoint != null) {
var dx = device.x - aimcontroller.selectedPilePoint!.x;
var dy = device.y - aimcontroller.selectedPilePoint!.y;
var dx = device.x.value - aimcontroller.selectedPilePoint!.x;
var dy = device.y.value - aimcontroller.selectedPilePoint!.y;
var distance = sqrt(dx * dx + dy * dy);
if (distance > 2) {
dx = (aimcontroller.selectedPilePoint!.x - device.x) /
dx = (aimcontroller.selectedPilePoint!.x - device.x.value) /
(distance / 2);
dy = (aimcontroller.selectedPilePoint!.y - device.y) /
dy = (aimcontroller.selectedPilePoint!.y - device.y.value) /
(distance / 2);
device.x = aimcontroller.selectedPilePoint!.x + dx;
device.y = aimcontroller.selectedPilePoint!.y + dy;
device.x.value = aimcontroller.selectedPilePoint!.x + dx;
device.y.value = aimcontroller.selectedPilePoint!.y + dy;
}
_dx = -dx / 10;
_dy = -dy / 10;
}
}
// if ((aimcontroller.selectedPilePoint!.x - device.x).abs() > _dx.abs()) {
device.x += _dx;
device.y += _dy;
device.x.value += _dx;
device.y.value += _dy;
// } else {
// device.x = aimcontroller.selectedPilePoint!.x;
// device.y = aimcontroller.selectedPilePoint!.y;
@ -118,14 +138,27 @@ class GnssController extends GetxController {
// device.x += 0.05;
// device.y += 0.05;
device.rotation = device.rotation + pi / 180; // 0-360
device.rotation.value += pi / 180; // 0-360
device.update.value++;
checkDistance();
});
gnss = Gnss(port: "/dev/ttysWK2", baudrate: 115200);
// gnss = Gnss(port: "COM1", baudrate: 115200);
gnss.start();
try {
gnss.start();
} catch (e) {
scaffoldMessengerKey.currentState?.showSnackBar(
SnackBar(
content: Text('发生错误: ${e.toString()}'),
duration: const Duration(seconds: 25),
backgroundColor: Colors.red,
),
);
return;
}
gnss.locationStream.listen((location) {
locationData = location;
// log(locationData);

View File

@ -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());
SchedulerBinding.instance.addPostFrameCallback((_) async {
await loadData(settingController);
setState(() {
isInitialized = settingController.isInitialized;
Get.put(PlumDataController());
Get.put(AntennaController());
Get.put(TaskController());
Get.put(RealController());
Get.put(GnssController());
});
});
}
final List<Widget> _pages = [
const Real(),
PassTrack(
// date: '',
),
const TaskManagePage(),
const HistoryRecord(),
const SettingPortrait()
];
@override
Widget build(BuildContext context) {
if (!isInitialized) {
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
final List<Widget> pages = [
// const Real(),
PassTrack(),
const TaskManagePage(),
const HistoryRecord(),
const SettingPortrait()
];
return Scaffold(
resizeToAvoidBottomInset: false,
drawerEdgeDragWidth: 0.0, // drawer
@ -100,237 +144,152 @@ class _MyHomePageState extends State<MyHomePage> {
appBarHeight = Orientation.portrait == orientation ? 56.0 : 34.0;
isPortrait = Orientation.portrait == orientation ? true : false;
appBarHeight = Orientation.portrait == orientation ? 56.0 : 34.0;
if (!isPortrait) {
return Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: _pages[appcontroller.currentIndex.value],
),
const VerticalDivider(
width: 1, // 1
thickness: 1,
),
SizedBox(
width: 48,
child: SafeArea(
child: LayoutBuilder(builder: (context, constraints) {
//
// if (!isPortrait) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Column(
children: [
IconButton(
onPressed: () {
setState(() {
appcontroller.currentIndex.value = 0;
});
},
icon: const Icon(Icons.date_range_rounded),
color: appcontroller.currentIndex.value == 0
? const Color.fromARGB(255, 60, 95, 123)
: Colors.grey,
),
Align(
alignment: Alignment.center,
child: Text(
'实时',
style: TextStyle(
fontSize: 12,
color:
appcontroller.currentIndex.value ==
0
? const Color.fromARGB(
255, 60, 95, 123)
: Colors.grey,
),
),
),
],
),
const Divider(
height: 1, // 1
thickness: 1,
),
//
Column(
children: [
IconButton(
onPressed: () {
setState(() {
appcontroller.currentIndex.value = 1;
});
},
icon: const Icon(Icons.map_outlined),
color: appcontroller.currentIndex.value == 1
? const Color.fromARGB(255, 60, 95, 123)
: Colors.grey,
),
Align(
alignment: Alignment.center,
child: Text(
'桩点',
style: TextStyle(
fontSize: 12,
color:
appcontroller.currentIndex.value ==
1
? const Color.fromARGB(
255, 60, 95, 123)
: Colors.grey,
),
),
),
],
),
const Divider(),
Column(
children: [
IconButton(
onPressed: () {
setState(() {
appcontroller.currentIndex.value = 2;
});
},
icon: const Icon(Icons.my_location_sharp),
color: appcontroller.currentIndex.value == 2
? const Color.fromARGB(255, 60, 95, 123)
: Colors.grey,
),
Align(
alignment: Alignment.center,
child: Text(
'任务',
style: TextStyle(
fontSize: 12,
color:
appcontroller.currentIndex.value ==
2
? const Color.fromARGB(
255, 60, 95, 123)
: Colors.grey,
),
),
),
],
),
const Divider(),
Column(
children: [
IconButton(
onPressed: () {
setState(() {
appcontroller.currentIndex.value = 3;
});
},
icon:
const Icon(Icons.table_chart_outlined),
color: appcontroller.currentIndex.value == 3
? const Color.fromARGB(255, 60, 95, 123)
: Colors.grey,
),
Align(
alignment: Alignment.center,
child: Text(
'历史',
style: TextStyle(
fontSize: 12,
color:
appcontroller.currentIndex.value ==
3
? const Color.fromARGB(
255, 60, 95, 123)
: Colors.grey,
),
),
),
],
),
const Divider(),
Column(
children: [
IconButton(
onPressed: () {
setState(() {
appcontroller.currentIndex.value = 4;
});
},
icon: const Icon(Icons.settings),
color: appcontroller.currentIndex.value == 4
? const Color.fromARGB(255, 60, 95, 123)
: Colors.grey,
),
Align(
alignment: Alignment.center,
child: Text(
'设置',
style: TextStyle(
fontSize: 12,
color:
appcontroller.currentIndex.value ==
4
? const Color.fromARGB(
255, 60, 95, 123)
: Colors.grey,
),
),
),
],
)
]);
//
}),
return Obx(() {
appcontroller.currentIndex.value;
if (!isPortrait) {
return Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: pages[appcontroller.currentIndex.value],
),
)
]);
} //
const VerticalDivider(
width: 1, // 1
thickness: 1,
),
SizedBox(
width: 48,
child: SafeArea(
child: LayoutBuilder(builder: (context, constraints) {
//
// if (!isPortrait) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// buildIconButton(
// context: context,
// index: 0,
// icon: Icons.date_range_rounded,
// label: '实时',
// ),
// const Divider(),
buildIconButton(
context: context,
index: 0,
icon: Icons.map_outlined,
label: '桩点',
),
const Divider(),
buildIconButton(
context: context,
index: 1,
icon: Icons.my_location_sharp,
label: '任务',
),
const Divider(),
buildIconButton(
context: context,
index: 2,
icon: Icons.table_chart_outlined,
label: '历史',
),
const Divider(),
buildIconButton(
context: context,
index: 3,
icon: Icons.settings,
label: '设置',
),
]);
//
}),
),
)
]);
} //
else {
//
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
flex: 12,
child: _pages[appcontroller.currentIndex.value],
),
// VerticalDivider(),
Expanded(
flex: 1,
child: SizedBox(
height: 48,
child: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: appcontroller.currentIndex.value,
onTap: (index) {
setState(() {
appcontroller.currentIndex.value = index;
});
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.date_range_rounded),
label: "实时"),
BottomNavigationBarItem(
icon: Icon(Icons.map_outlined), label: "计划"),
BottomNavigationBarItem(
icon: Icon(Icons.my_location_sharp),
label: "任务"),
BottomNavigationBarItem(
icon: Icon(Icons.table_chart_outlined),
label: "历史"),
BottomNavigationBarItem(
icon: Icon(Icons.settings), label: "设置"),
]),
else {
//
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
flex: 12,
child: pages[appcontroller.currentIndex.value],
),
)
]);
}
// VerticalDivider(),
Expanded(
flex: 1,
child: SizedBox(
height: 48,
child: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: appcontroller.currentIndex.value,
onTap: (index) {
setState(() {
appcontroller.currentIndex.value = index;
});
},
items: const [
// BottomNavigationBarItem(
// icon: Icon(Icons.date_range_rounded),
// label: "实时"),
BottomNavigationBarItem(
icon: Icon(Icons.map_outlined), label: "计划"),
BottomNavigationBarItem(
icon: Icon(Icons.my_location_sharp),
label: "任务"),
BottomNavigationBarItem(
icon: Icon(Icons.table_chart_outlined),
label: "历史"),
BottomNavigationBarItem(
icon: Icon(Icons.settings), label: "设置"),
]),
),
)
]);
}
});
},
),
);
}
Widget buildIconButton({
required BuildContext context,
required int index,
required IconData icon,
required String label,
}) {
return InkWell(
onTap: () {
setState(() {
appcontroller.currentIndex.value = index;
});
},
child: Column(
children: [
Icon(
(icon),
color: appcontroller.currentIndex.value == index
? const Color.fromARGB(255, 60, 95, 123)
: Colors.grey,
),
Align(
alignment: Alignment.center,
child: Text(
label,
style: TextStyle(
fontSize: 12,
color: appcontroller.currentIndex.value == index
? const Color.fromARGB(255, 60, 95, 123)
: Colors.grey,
),
),
),
],
),
);
}
}

View File

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

View File

@ -52,7 +52,7 @@ class _CanlenderSelectState extends State<CanlenderSelect> {
@override
Widget build(BuildContext context) {
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
var dayTextStyle = TextStyle(
color: isDarkMode ? Colors.white : Colors.black,
fontWeight: FontWeight.w700);
@ -104,15 +104,11 @@ class _CanlenderSelectState extends State<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;
}
}

View File

@ -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 {
constructionData = getConstructionData;
}
getConstructionData = getConstructionData.where((data) {
// "Invalid Date"
return !data.toString().contains("Invalid Date");
}).toList();
constructionData = getConstructionData;
});
_asyncrecordsDataSource.date = selectedDataString ?? "";
@ -154,7 +153,7 @@ class _HistoryRecordState extends State<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(

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

View File

@ -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(
children: [],
// DateFormat('yyyy-MM-dd')
// .format(item.startTime)
),
))),
onPressed: () {
String date = DateFormat('yyyy-MM-dd').format(item.startTime);
Widget page = PassTrack(
currentPoint: item,
);
Navigator.push(context, MaterialPageRoute(builder: (context) {
return Scaffold(
appBar: AppBar(
title: Text("$date 历史轨迹"),
toolbarHeight: 40,
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
),
body: page,
);
}));
},
child: const Text("位置"),
)),
// DataCell(TextButton(
@ -139,18 +142,22 @@ class RecordFakeWebService {
Future<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());
});
}
}

View File

@ -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,9 +79,11 @@ class AccountLoginController extends GetxController {
}
Future<void> changeCaptcha() async {
var captcha = await GetServices().getCaptcha();
svgString.value = captcha['data'];
captchaId.value = captcha['captchaId'];
var captcha = await services.getCaptcha();
if (captcha['data'] != null) {
svgString.value = captcha['data'];
captchaId.value = captcha['captchaId'];
}
}
void showErrorSnackbar(String text) {
@ -89,25 +91,10 @@ class AccountLoginController extends GetxController {
content: Text(text),
backgroundColor: Colors.red,
);
ScaffoldMessenger.of(Get.context!).showSnackBar(snackBar);
if (Get.context != null) {
ScaffoldMessenger.of(Get.context!).showSnackBar(snackBar);
}
}
// Future<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();
//
FocusScope.of(Get.context!).unfocus();
await GetServices().getsmsCode(phoneNumber.value);
if (Get.context != null) {
FocusScope.of(Get.context!).unfocus();
}
startTimer(); //
await services.getsmsCode(phoneNumber.value);
}
}
@ -302,14 +300,16 @@ class PhoneLoginController extends GetxController {
// ...
//
FocusScope.of(Get.context!).unfocus();
var res =
await GetServices().phoneLogin(phoneNumber.value, smsCode.value);
var res = await services.phoneLogin(phoneNumber.value, smsCode.value);
if (res['code'] != 1000) {
showErrorSnackbar(res["message"]);
} else {
LoginPrefs().savePhone(phoneNumber.value);
LoginPrefs().saveExpire(res["data"]["expire"]);
LoginPrefs().saveToken(res["data"]["token"]);
loginPrefs.savePhone(phoneNumber.value);
loginPrefs.saveExpire(res["data"]["expire"]);
loginPrefs.saveToken(res["data"]["token"]);
loginPrefs.saveRefreshToken(res["data"]["refreshToken"]);
loginPrefs.saveRefreshExpire(res["data"]["refreshExpire"]);
Get.offNamed('home'); //
}
}

View File

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

View File

@ -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);
}
mapController.centerXY = Offset(
mapController.recordList[mapController.recordList.length - 1].x,
mapController.recordList[mapController.recordList.length - 1].y);
if (currentPoint == null) {
mapController.centerXY = Offset(
mapController.recordList[mapController.recordList.length - 1].x,
mapController.recordList[mapController.recordList.length - 1].y);
} else {
mapController.centerXY = Offset(currentPoint!.x, currentPoint!.y);
}
//
} else {
String now = DateFormat('yyyy-MM-dd').format(DateTime.now());
if ((currentPoint == null && date.value == now) ||
(DateFormat('yyyy-MM-dd').format(currentPoint!.startTime) == now)) {
log("${currentPoint?.startTime},now:$now");
scaffoldMessengerKey.currentState?.showSnackBar(
SnackBar(
content: Text('提示: ${date.value}暂无施工数据'),
duration: const Duration(seconds: 5),
backgroundColor: const Color.fromARGB(255, 230, 162, 60),
),
);
}
}
mapController.updateCount++;
}
}

View File

@ -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,86 +42,48 @@ 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) {
return OrientationBuilder(builder: (context, orientation) {
return Stack(
children: [
ScenceMapView(
onUpdate: (Offset center, double scale, double rotation) {
log("center:$center scale:$scale rotation:$rotation");
},
forGroundPainter: appcontroller.currentIndex.value == 1
? BorderPainter(controller)
: null,
onUpdatePilePoint: (RecordEntity? selectedPilePoint, double scale,
double rotation) {
log(
"selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation");
controller.selectedPilePoint = selectedPilePoint;
aimcontroller.selectedPilePoint = selectedPilePoint;
},
children: const [],
),
const SightGview(),
const RealDataShow(),
],
);
if (currentPoint == null) {
controller.date.value = DateFormat('yyyy-MM-dd').format(DateTime.now());
} else {
controller.date.value =
DateFormat('yyyy-MM-dd').format(currentPoint!.startTime);
}
controller.currentPoint = currentPoint;
controller.loadData();
return Obx(() {
controller.updateCount.value;
CustomPainter? forGroundPainter = appcontroller.currentIndex.value == 1
? BorderPainter(
controller,
)
: null;
return OrientationBuilder(builder: (context, orientation) {
return Stack(
children: [
ScenceMapView(
onUpdate: (Offset center, double scale, double rotation) {
log("center:$center scale:$scale rotation:$rotation");
},
forGroundPainter: forGroundPainter,
onUpdatePilePoint: (RecordEntity? selectedPilePoint, double scale,
double rotation) {
log("selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation");
controller.selectedPilePoint.value = selectedPilePoint;
aimcontroller.selectedPilePoint = selectedPilePoint;
controller.updateCount.value++;
},
children: const [],
),
const SightGview(),
const RealDataShow(),
],
);
});
});
}
}
@ -139,9 +104,9 @@ class BorderPainter extends CustomPainter {
final paint = Paint()
..color = Colors.red
..strokeWidth = 3.0;
if (controller.selectedPilePoint != null) {
var offset = Offset(
controller.selectedPilePoint!.x, controller.selectedPilePoint!.y);
RecordEntity? selectedPilePoint = controller.selectedPilePoint.value;
if (selectedPilePoint != null) {
var offset = Offset(selectedPilePoint.x, selectedPilePoint.y);
Offset screenPos = mapcontroller.xy2Screen0(offset);
//
@ -163,40 +128,18 @@ class BorderPainter extends CustomPainter {
} else if (mapcontroller.scale >= 10) {
cornerLength = 0;
}
paint.style = PaintingStyle.stroke;
canvas.drawRect(rect, paint);
//
canvas.drawLine(
rect.topLeft, rect.topLeft + Offset(cornerLength, 0), paint);
canvas.drawLine(
rect.topLeft, rect.topLeft + Offset(0, cornerLength), paint);
//
canvas.drawLine(
rect.topRight, rect.topRight + Offset(-cornerLength, 0), paint);
canvas.drawLine(
rect.topRight, rect.topRight + Offset(0, cornerLength), paint);
//
canvas.drawLine(
rect.bottomLeft, rect.bottomLeft + Offset(cornerLength, 0), paint);
canvas.drawLine(
rect.bottomLeft, rect.bottomLeft + Offset(0, -cornerLength), paint);
//
canvas.drawLine(
rect.bottomRight, rect.bottomRight + Offset(-cornerLength, 0), paint);
canvas.drawLine(
rect.bottomRight, rect.bottomRight + Offset(0, -cornerLength), paint);
Offset center = Offset(gnsscontroller.device.x, gnsscontroller.device.y);
Offset center =
Offset(gnsscontroller.device.x.value, gnsscontroller.device.y.value);
Offset pilerCenter = mapcontroller.xy2Screen0(center);
//线
if (mapcontroller.deviceList.isNotEmpty) {
Paint dashedPaint = Paint()
..color = Colors.red
..strokeWidth = 3.5;
var offset = Offset(
controller.selectedPilePoint!.x, controller.selectedPilePoint!.y);
var offset = Offset(selectedPilePoint.x, selectedPilePoint.y);
Offset screenPos = mapcontroller.xy2Screen0(offset);
drawDashedLine(canvas, pilerCenter, screenPos, dashedPaint);

View File

@ -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;
@ -278,7 +283,7 @@ class ChartData {
int intValue = (value).ceil();
if (intValue % (2 * radtio) == 0 && intValue <= maxYR) {
text = (intValue / radtio).floor().toString();
if (maxYR - intValue < 2 * radtio) {
if (maxYR - intValue < 2 * radtio) {
text = "深度(m)";
}
} else {

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

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

View File

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

View File

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

View File

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

View File

@ -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);
});
}
@ -33,90 +31,91 @@ class PilePointTableState extends State<PilePointTable> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title:const Text('桩点列表'),
title: const Text('桩点列表'),
actions: [
IconButton(
icon:const Icon(Icons.delete),
icon: const Icon(Icons.delete),
onPressed: _deleteSelected,
),
],
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
plumDataController.showList.value = false;
for (var point in widget.pilePoints) {
point.isSelected = false;
}
widget.onUpdate(widget.pilePoints);
}),
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Table(
border: const TableBorder(
verticalInside: BorderSide(color: Colors.grey, width: 1.0),
horizontalInside: BorderSide(color: Colors.grey, width: 1.0),
),
columnWidths: const {
0: IntrinsicColumnWidth(),
1: IntrinsicColumnWidth(),
2: IntrinsicColumnWidth(),
3: IntrinsicColumnWidth(),
},
children: [
const TableRow(
children: [
Center(child: Text('选择')),
Center(child: Text('ID')),
Center(child: Text('X')),
Center(child: Text('Y')),
],
),
...List<TableRow>.generate(
widget.pilePoints.length,
(index) => TableRow(
child: widget.pilePoints.isEmpty
? const Center(child: Text('暂无桩点数据'))
: Table(
border: const TableBorder(
verticalInside: BorderSide(color: Colors.grey, width: 1.0),
horizontalInside: BorderSide(color: Colors.grey, width: 1.0),
),
columnWidths: const {
0: IntrinsicColumnWidth(),
1: IntrinsicColumnWidth(),
2: FlexColumnWidth(),
3: FlexColumnWidth(),
},
children: [
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0),
child: Checkbox(
value: _selected[index],
onChanged: (bool? value) {
setState(() {
_selected[index] = value ?? false;
});
},
),
),
TableRow(
children: [
Center(
child: TextButton(
onPressed: () {
setState(() {
for (var point in widget.pilePoints) {
point.isSelected = !point.isSelected;
}
});
},
child: const Text('选择'))),
const Center(child: Text('ID')),
const Center(child: Text('X')),
const Center(child: Text('Y')),
],
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0),
child: Text(widget.pilePoints[index].id.toString()),
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0),
child: GestureDetector(
onTap: () => _editPilePoint(context, index, 'x'),
child: Text(widget.pilePoints[index].x.toString()),
),
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0),
child: GestureDetector(
onTap: () => _editPilePoint(context, index, 'y'),
child: Text(widget.pilePoints[index].y.toString()),
),
...List<TableRow>.generate(
widget.pilePoints.length,
(index) => TableRow(
children: [
_buildTableCell(
Checkbox(
value: widget.pilePoints[index].isSelected,
onChanged: (bool? value) {
setState(() {
widget.pilePoints[index].isSelected =
value ?? false;
});
},
),
),
_buildTableCell(
Text(widget.pilePoints[index].id.toString()),
),
_buildTableCell(
GestureDetector(
onTap: () => _editPilePoint(context, index, 'x'),
child: Text(widget.pilePoints[index].x.toString()),
),
),
_buildTableCell(
GestureDetector(
onTap: () => _editPilePoint(context, index, 'y'),
child: Text(widget.pilePoints[index].y.toString()),
),
),
],
),
),
],
),
),
],
),
),
);
}
@ -132,7 +131,7 @@ class PilePointTableState extends State<PilePointTable> {
context: context,
builder: (context) {
return AlertDialog(
title:const Text('编辑桩点'),
title: const Text('编辑桩点'),
content: TextField(
controller: controller,
keyboardType: TextInputType.number,
@ -151,17 +150,27 @@ class PilePointTableState extends State<PilePointTable> {
});
Navigator.of(context).pop();
},
child:const Text('保存'),
child: const Text('保存'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child:const Text('取消'),
child: const Text('取消'),
),
],
);
},
);
}
Widget _buildTableCell(Widget child) {
return TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0),
child: child,
),
);
}
}

View File

@ -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,79 +41,213 @@ class DrawDirection extends CustomPainter {
linePointOffset = linePointOffset + pos;
centerOffset = controller.centerOffset.value + pos;
}
log("-----矩阵中心$centerOffset,$centerXY");
dev.log("-----矩阵中心$centerOffset,$centerXY");
path.moveTo(centerOffset.dx, centerOffset.dy);
path.lineTo(linePointOffset.dx, linePointOffset.dy);
canvas.drawPath(path, paint);
paint.style = PaintingStyle.fill;
canvas.drawCircle(linePointOffset, 10, paint);
// canvas.translate(centerOffset.dx, centerOffset.dy);
// canvas.rotate(controller.angle.value);
// canvas.translate(-centerOffset.dx, -centerOffset.dy);
// double deLength = 100;
// double angle = atan2((linePointOffset.dy - centerOffset.dy),
// (linePointOffset.dx - centerOffset.dx));
// // dev.log("-----角度$angle,${controller.angle.value}");
// canvas.drawCircle(linePointOffset, 10, paint);
// var dx1 = (deLength * cos(angle + pi / 2)) + centerOffset.dx;
// var dy1 = (deLength) * sin(angle + pi / 2) + centerOffset.dy;
// canvas.drawCircle(Offset(dx1, dy1), 10, paint);
// dx1 = (deLength * cos(angle + pi)) + centerOffset.dx;
// dy1 = (deLength) * sin(angle + pi) + centerOffset.dy;
// canvas.drawCircle(Offset(dx1, dy1), 10, paint);
// dx1 = (deLength * cos(angle + pi / 2 * 3)) + centerOffset.dx;
// dy1 = (deLength) * sin(angle + pi / 2 * 3) + centerOffset.dy;
// canvas.drawCircle(Offset(dx1, dy1), 10, paint);
paint
// ..color = Colors.grey.withOpacity(.4)
.style = PaintingStyle.stroke;
if (controller.isUp.value && controller.angle.value != 0) {
double unit =
mapController.plottingScale.value / mapController.pixel2MeterRatio;
List<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);
canvas.drawCircle(
downPoint, .3 / mapController.pixel2MeterRatio, paint);
bool isUpPointInRect = upPoint.dx >= minX &&
upPoint.dx <= maxX &&
upPoint.dy >= minY &&
upPoint.dy <= maxY;
bool isDownPointInRect = downPoint.dx >= minX &&
downPoint.dx <= maxX &&
downPoint.dy >= minY &&
downPoint.dy <= maxY;
if (controller.isPlum.value) {
if ((j % 2 == p % 2) == centerEven) {
paint.style = PaintingStyle.fill;
} else {
paint.style = PaintingStyle.stroke;
}
if (isDownPointInRect && j > 0) {
canvas.drawCircle(
downPoint, .3 / mapController.pixel2MeterRatio, paint);
if ((j % 2 == p % 2) == centerEven) {
Offset xy1 = mapController.screen2xy0(downPoint);
controller.plumList.add(xy1);
}
}
// Offset xy = mapController.screen2xy0(upPoint);
// Offset xy1 = mapController.screen2xy0(downPoint);
controller.plumList.add(upPoint);
controller.plumList.add(downPoint);
if (isUpPointInRect) {
canvas.drawCircle(
upPoint, .3 / mapController.pixel2MeterRatio, paint);
if ((j % 2 == p % 2) != centerEven) {
Offset xy = mapController.screen2xy0(upPoint);
controller.plumList.add(xy);
}
}
continue;
}
if (isUpPointInRect) {
// TextPainter textPainter = TextPainter(
// text: TextSpan(
// text: '$p,$j',
// style: TextStyle(color: Colors.blue, fontSize: 16)),
// textDirection: TextDirection.ltr,
// );
// textPainter.layout();
// textPainter.paint(canvas, upPoint);
canvas.drawCircle(
upPoint, .3 / mapController.pixel2MeterRatio, paint);
Offset xy = mapController.screen2xy0(upPoint);
controller.plumList.add(xy);
}
if (isDownPointInRect && j > 0) {
// TextPainter textPainter = TextPainter(
// text: TextSpan(
// text: '$p,$j',
// style: TextStyle(color: Colors.blue, fontSize: 16)),
// textDirection: TextDirection.ltr,
// );
// textPainter.layout();
// textPainter.paint(canvas, downPoint);
canvas.drawCircle(
downPoint, .3 / mapController.pixel2MeterRatio, paint);
Offset xy1 = mapController.screen2xy0(downPoint);
controller.plumList.add(xy1);
}
}
}
dev.log("controller.plumList:${controller.plumList.length}");
}
}
getRect(List<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;
}

View File

@ -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(
// size: Size(scenceMapController.diagonal,
// scenceMapController.diagonal),
foregroundPainter:
DrawDirection(controller, scOffset, isDarkMode, isInit),
// child:
buttons[controller.currentDir.value.index] =
controller.linePointOffset.value - controller.transOff;
if (controller.checkValue.value == "checkPile") {
buttons = [
Offset.zero,
Offset.zero,
Offset.zero,
Offset.zero
];
}
List<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),
// 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(
children: [
Obx(() => AbsorbPointer(
absorbing: controller.isGenerate.value
? true
: false, //CenterLayout GestureDetector
// child: const ScenceMapView(
// children: [],
// ),
child:const TaskPage(), //
// PassTrack(
// date: '',
// )
)),
center,
back,
const PileGenerateCard1()
],
return Scaffold(
appBar: AppBar(
title: const Text('任务页面'),
actions: [
ElevatedButton(
child: const Text("桩点坐标"),
onPressed: () => {
controller.checkValue.value = "checkPile",
}),
const SizedBox(
width: 10,
),
ElevatedButton(
child: const Text("生成"),
onPressed: () => {
controller.checkValue.value = "checkDirection",
}),
UnconstrainedBox(
child: IconButton(
onPressed: () {
int index = controller.currentDir.value.index;
// controller.distancesOffset[index] =
// controller.linePointOffset.value - controller.transOff;
if (index + 1 == dirList.length) {
index = -1;
}
controller.currentDir.value = dirList[index + 1];
// controller.direction.value +=
// controller.currentDir.value.angle + 3.14 / 2;
controller.updateDistances(controller.direction.value);
controller.linePointOffset.value =
controller.distancesOffset[index + 1];
controller.updateCount++;
},
icon: Obx(() {
int index = controller.currentDir.value.index;
return Transform.rotate(
angle: dirList[index].angle,
child: const Icon(Icons.arrow_back),
);
}),
),
),
UnconstrainedBox(
child: SizedBox(
height: 30,
child: Builder(
builder: (context) => Obx(
() => InkWell(
child: Icon(
Icons.list,
size: 35,
color: appcontroller.isDarkMode.value
? Colors.white70
: const Color.fromARGB(200, 29, 28, 28),
),
onTap: () {
controller.showList.value =
!controller.showList.value;
}),
),
),
),
),
],
),
body: Stack(
children: [
Obx(() {
controller.isGenerate.value;
return AbsorbPointer(
absorbing: controller.isGenerate.value
? true
: false, //CenterLayout GestureDetector
child: const TaskPage(), //
);
}),
center,
back,
Obx(() {
if (controller.showList.value) {
return Positioned(
right: 0,
top: 0,
width: size.width * 0.4,
height: size.height,
child: PilePointTable(
pilePoints: taskcontroller.currentask.value.list,
onUpdate: (updatedPilePoints) =>
updatePoints(updatedPilePoints),
),
);
} else {
return const Text("");
}
})
// const PileGenerateCard1()
],
));
}
Widget buildPositionedButton(
Offset position, double rotationAngle, VoidCallback press) {
Color color = Colors.black;
return Positioned(
left: position.dx,
top: position.dy,
child: IconButton(
onPressed: press,
icon: Transform.rotate(
angle: rotationAngle,
child: Icon(
Icons.arrow_back,
color: color,
),
),
),
);
}
}
centerPointDialog(context, PlumDataController controller) {
double titleTextWidth = 90;
double inputLength = 120;
FocusNode xFocus = FocusNode();
FocusNode yFocus = FocusNode();
FocusNode directionFocus = FocusNode();
FocusNode pileSpaceFocus = FocusNode();
// FocusNode pileWidthFocus = FocusNode();
DeviceType deviceType = getDeviceType(context);
double fontSize = 16;
if (deviceType == DeviceType.mobile) {
fontSize = 16;
} else {
fontSize = 20;
}
showDialog(
context: context,
builder: (context) {
final size = MediaQuery.of(context).size;
double centerPointX = controller.centerXY.value.dx;
double centerPointY = controller.centerXY.value.dy;
return AlertDialog(
title: const Text("设置"),
contentPadding: const EdgeInsets.symmetric(horizontal: 3),
actionsPadding: const EdgeInsets.only(bottom: 5),
actions: [
TextButton(
child: const Text('取消'),
onPressed: () {
controller.isGenerate.value = false;
controller.isSave.value = false;
Navigator.of(context).pop();
//
},
),
TextButton(
child: const Text('确定'),
onPressed: () {
//
controller.isGenerate.value = false;
controller.isSave.value = true;
controller.centerXY.value = Offset(centerPointX, centerPointY);
Navigator.of(context).pop();
},
),
],
content: SizedBox(
height: size.height * 0.45,
width: size.width * 0.5,
child: SingleChildScrollView(
child: AlignWrapWidget(
children: [
Row(children: [
FixedWidthTextWidget(width: titleTextWidth, text: "X:"),
inputText(
inputLength: inputLength,
value: centerPointX.toString(),
fontsize: fontSize,
focusNode: yFocus,
onChanged: (value) => value.isNotEmpty
? centerPointY =
(double.parse(value) * 1000).round() / 1000
: '')
]),
Row(children: [
FixedWidthTextWidget(width: titleTextWidth, text: "Y:"),
inputText(
inputLength: inputLength,
value: centerPointY.toString(),
fontsize: fontSize,
focusNode: xFocus,
onChanged: (value) => value.isNotEmpty
? centerPointX =
(double.parse(value) * 1000).round() / 1000
: '')
]),
Row(children: [
FixedWidthTextWidget(width: titleTextWidth, text: "方向(°):"),
inputText(
inputLength: inputLength,
value: controller.direction.toString(),
fontsize: fontSize,
focusNode: directionFocus,
keyboardType: 0,
onChanged: (value) {
if (value.isNotEmpty) {
controller.direction.value = double.parse(value);
// bug
controller.angle.value =
controller.direction.value * pi / 180;
}
})
]),
Row(
children: [
FixedWidthTextWidget(
width: titleTextWidth + 10, text: "夯点间距(m):"),
inputText(
inputLength: inputLength - 10,
fontsize: fontSize,
value: controller.space.toString(),
focusNode: pileSpaceFocus,
onChanged: (value) => {
value.isNotEmpty
? controller.space.value = double.parse(value)
: '',
})
],
),
Row(children: [
FixedWidthTextWidget(
width: titleTextWidth + 10, text: "是否为梅花桩:"),
Obx(() {
bool c = controller.isPlum.value;
return Switch(
onChanged: (val) {
controller.isPlum.value = val;
},
value: c,
);
})
]),
// Row(children: [
// FixedWidthTextWidget(
// width: titleTextWidth + 10, text: "宽度(m):"),
// inputText(
// inputLength: inputLength - 10,
// fontsize: fontSize,
// value: controller.pileWidth.toString(),
// focusNode: pileWidthFocus,
// onChanged: (value) => {
// value.isNotEmpty
// ? controller.pileWidth.value =
// double.parse(value)
// : '',
// })
// ]),
Row(children: [
const Icon(
Icons.tips_and_updates_outlined,
color: Colors.red,
),
Text(
controller.isPileId.value
? '选中桩点:${controller.checkName.value}'
: ' 未选中桩点',
style: TextStyle(
color: !controller.isPileId.value
? Colors.red
: Colors.black),
)
]),
],
)),
),
);
});
}
updatePoints(List<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);
// }
// }
}

View File

@ -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(
onUpdate: (Offset center, double scale, double rotation) {
log("center:$center scale:$scale rotation:$rotation");
},
forGroundPainter: appcontroller.currentIndex.value == 1
? BorderPainter(controller)
: null,
onUpdatePilePoint: (RecordEntity? selectedPilePoint, double scale,
double rotation) {
log(
"selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation");
},
children: const [],
),
// ),
if (pilecontroller.isPileCardVisible.value)
const PileGenerateCard(),
],
));
return ScenceMapView(
onUpdate: (Offset center, double scale, double rotation) {
log("center:$center scale:$scale rotation:$rotation");
},
forGroundPainter: appcontroller.currentIndex.value == 1
? BorderPainter(pscontroller)
: null,
onUpdatePilePoint:
(RecordEntity? selectedPilePoint, double scale, double rotation) {
log("selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation");
},
children: const [],
);
}
}
//
class StepDialogManager {
final BuildContext context;
final List<String> _stepTexts = [
'点击屏幕即可确定桩点中心。',
'这是步骤 2 的提示对话框。',
'这是步骤 3 的提示对话框。',
'点击方向设置按钮和输入宽度值可设置桩点范围。',
'手指在屏幕上拖动可确定桩点范围'
];
class TaskManagePage extends GetView<TaskController> {
const TaskManagePage({super.key});
StepDialogManager(this.context);
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return OrientationBuilder(builder: ((context, orientation) {
return Stack(
children: [
SizedBox(
height: size.height * 0.8,
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: Obx(() {
controller.updateCount;
List<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("新增"),
),
],
))
],
);
}));
}
void showStepDialog(int step) {
addDialog(context) {
//
TaskItem addTask = TaskItem(
list: [],
name: " ",
id: 0,
utc: 0,
originLabel: "本地",
workTotal: 0,
centerPileInfo: CenterPileInfo(
x: 0,
y: 0,
));
TextEditingController taskController =
TextEditingController(text: addTask.name.toString());
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('步骤提示'),
content: Text(_stepTexts[step]),
title: const Text("新增任务"),
content: SizedBox(
height: 100,
child: Column(
children: [
TextField(
keyboardType: TextInputType.emailAddress,
controller: taskController,
decoration: const InputDecoration(
hintText: '任务名称',
prefixText: '任务名称:',
border: InputBorder.none,
labelStyle: TextStyle(
fontSize: 16, color: Color.fromARGB(164, 75, 73, 73)),
),
)
],
),
),
actions: <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("确定"),
),
],
);

View File

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

View File

@ -2,38 +2,70 @@ import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:cpnav/models/pilePoint/coord_trans.dart';
import 'package:cpnav/pages/setting/setting_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import '../main.dart';
import 'user/loginprefs.dart';
LoginPrefs loginPrefs = LoginPrefs();
SettingController settingController = Get.put(SettingController());
GetServices services = settingController.services;
class BaseService {
//client实例
final _client = http.Client();
final String token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc1IiOjAsInJvbGVJZHMiOlsiMSIsIjI0Il0sInVzZXJuYW1lIjoiYWRtaW4iLCJ1c2VySWQiOjEsIlBWIjo1LCJvcmciOiJhIiwiaWF0IjoxNzMwNzg3MDE3LCJleHAiOjE3MzIwODMwMTd9.hhWpQAqv160E6tNi5ymyHigzRzZTM4CfwSsraomvJWM";
// String baseUrl = "http://192.168.1.154:8001";//
String token = "";
// String baseUrl = "http://192.168.1.154:8001"; //
String baseUrl = "http://v5.rdc.pub"; //线
String loginstatus = "登录失效";
Duration timeout = const Duration(seconds: 10);
//GET请求
getClient(String url, [bool useBaseUrl = true]) async {
checkExpire();
if (token == "") {
token = loginPrefs.getToken();
}
try {
Uri fullUrl =Uri.parse(useBaseUrl ? (baseUrl + url) : url);
http.Response response = await _client
.get(fullUrl, headers: {
Uri fullUrl = Uri.parse(useBaseUrl ? (baseUrl + url) : url);
// log("请求地址: $fullUrl \n token: $token");
http.Response response = await _client.get(fullUrl, headers: {
HttpHeaders.contentTypeHeader: "application/json",
HttpHeaders.authorizationHeader: token,
});
}).timeout(timeout);
var res = json.decode(response.body);
if (res['message'].contains(loginstatus)) {
loginPrefs.clearLogin();
return;
}
return res;
if (res['code'] == 1000) {
return res;
} else {
log(res);
String msg = res['message'].toString();
if (res['code'] == 404) {
msg = "当前接口不存在:$msg";
}
scaffoldMessengerKey.currentState?.showSnackBar(
SnackBar(
content: Text('发生错误: $msg'),
duration: const Duration(seconds: 5),
backgroundColor: Colors.red,
),
);
return {};
}
} catch (e) {
scaffoldMessengerKey.currentState?.showSnackBar(
SnackBar(
content: Text('发生错误: ${e.toString()}'),
duration: const Duration(seconds: 5),
backgroundColor: Colors.red,
),
);
log(e.toString());
return {};
}
@ -41,14 +73,21 @@ class BaseService {
//POST请求
postClient(String url, body) async {
checkExpire();
if (token == "") {
token = loginPrefs.getToken();
}
try {
var data = json.encode(body);
http.Response response = await _client.post(Uri.parse(baseUrl + url),
headers: {
HttpHeaders.contentTypeHeader: "application/json",
HttpHeaders.authorizationHeader: token,
},
body: data);
http.Response response = await _client
.post(Uri.parse(baseUrl + url),
headers: {
HttpHeaders.contentTypeHeader: "application/json",
HttpHeaders.authorizationHeader: token,
},
body: data)
.timeout(timeout);
var res = json.decode(response.body);
if (res['message'].contains(loginstatus)) {
loginPrefs.clearLogin();
@ -60,78 +99,114 @@ class BaseService {
return {};
}
}
checkExpire() {
int old = loginPrefs.getRefreshExpire();
int now = DateTime.now().millisecond;
if (now - old <= 2000) {
//2s
refreshToken();
}
}
refreshToken() async {
String refreshToken = loginPrefs.getRefreshToken();
if (refreshToken == "") {
token = "";
return;
}
try {
Uri fullUrl = Uri.parse(
"$baseUrl/admin/base/open/refreshToken?refreshToken=$refreshToken");
http.Response response = await _client.get(fullUrl).timeout(timeout);
var res = json.decode(response.body);
if (res['code'] == 1000 && res["data"] != null) {
token = res["data"]["token"];
loginPrefs.saveExpire(res["data"]["expire"]);
loginPrefs.saveToken(token);
loginPrefs.saveRefreshToken(res["data"]["refreshToken"]);
loginPrefs.saveRefreshExpire(res["data"]["refreshExpire"]);
}
} catch (e) {
log("refreshToken error: $e");
}
}
}
class GetServices {
BaseService service = BaseService();
// String projCode = 'CJGKJEBYYB';
// int tid = 109;
String projType;
String projCode;
GetServices({this.projCode = "", this.projType = ""});
// int tid = 0;
// String projType = "";
// String projCode = "";
// String org_code = "a";
// int tid = 1000;
// String projType = "pile_cm";
// 线
Future getSideLine() async {
getSideLine(projCode, projType) async {
try {
Map res = await service.getClient(
Map? res = await service.getClient(
'/api/comm/side_line/list?proj_code=$projCode&proj_type=$projType');
return res['data'];
if (res != null && res['data'] != null) {
return res['data'];
}
} catch (e) {
return {};
return null;
}
return null;
}
// ---
Future getDeviceBind() async {
Future getDeviceBind(projType, projCode) async {
Map res = await service.getClient(
// '/api/sys/device_bind/list?proj_type=$projType&proj_code=$projCode');
// if (res['code'] == 1000) {
// return res['data'];
// } else {
// return [];
// }
'/api/sys/device_bind/list?proj_type=$projType&proj_code=$projCode');
if (res['code'] == 1000) {
if (res['data'] != null) {
return res['data'];
} else {
return [];
}
return [];
}
//
getproject() async {
Map res = await service
.getClient('/api/sys/project/list?org_code=a&proj_type=$projType');
return res['data'];
getproject(org_code, projType) async {
Map res = await service.getClient(
'/api/sys/project/list?org_code=$org_code&proj_type=$projType');
if (res['data'] != null) {
return res['data'];
}
return [];
}
//
// getRcordData(int page, int size, String date,
// [String sort = "desc", String order = "tp_id"]) async {
// Map res = await service.getClient(
// "/api/$projType/record/page?page=$page&size=$size&org_code=a&proj_code=$projCode&date=$date&sort=$sort&order=$order");
// return res['data'];
// }
getRcordData(projType, org_code, projCode, int page, int size, String date,
[String sort = "desc", String order = "tp_id"]) async {
Map res = await service.getClient(
"/api/$projType/record/page?page=$page&size=$size&org_code=$org_code&proj_code=$projCode&date=$date&sort=$sort&order=$order");
return res['data'];
}
//
// getRcordData(int page, int size, String date,
// [String sort = "desc", String order = "pile_id"]) async {
// Map res = await service.getClient(
// "/api/$projType/record/page?page=$page&size=$size&org_code=a&proj_code=$projCode&tid=$tid&date=$date&sort=$sort&order=$order");
// "/api/$projType/record/page?page=$page&size=$size&org_code=$org_code&proj_code=$projCode&tid=$tid&date=$date&sort=$sort&order=$order");
// return res['data'];
// }
// getRcordList(String date, String? dateEnd) async {
// dateEnd ??= date;
// Map res = await service.getClient(
// "/api/$projType/record/list?org_code=a&proj_code=$projCode&tid=$tid&date=$date&dateEnd=$dateEnd");
// "/api/$projType/record/list?org_code=$org_code&proj_code=$projCode&tid=$tid&date=$date&dateEnd=$dateEnd");
// return res['data'];
// }
// getRcordList(String date, [String? dateEnd]) async {
// dateEnd ??= date;
// Map res = await service.getClient(
// "/api/$projType/record/list?org_code=a&proj_code=$projCode&date=$date&dateEnd=$dateEnd");
// "/api/$projType/record/list?org_code=$org_code&proj_code=$projCode&date=$date&dateEnd=$dateEnd");
// if (res['code'] == 1000) {
// return res['data'];
// } else {
@ -140,21 +215,25 @@ class GetServices {
// }
//
getworkDateData() async {
getworkDateData(
String org_code, String projCode, String projType, int tid) async {
Map res = await service.getClient(
"/api/$projType/record/work_date?org_code=a&proj_code=$projCode");
if (res['code'] == 1000) {
return res['data'] ?? [];
} else {
return [];
"/api/$projType/record/work_date?org_code=$org_code&proj_code=$projCode&tid=$tid");
if (res['data'] != null) {
return res['data'];
}
return [];
}
//
getProcessData(int pileId) async {
getProcessData(int pileId, String projCode, String projType) async {
Map res = await service.getClient(
"/api/$projType/process/list?pile_id=$pileId&proj_code=$projCode");
return res['data'];
"/api/$projType/process/list?tpId=$pileId&proj_code=$projCode");
if (res['data'] != null) {
return res['data'];
}
return [];
}
//
@ -173,15 +252,21 @@ class GetServices {
//
getPerson() async {
Map res = await service.getClient("/admin/base/comm/person");
return res['data'];
Map? res = await service.getClient("/admin/base/comm/person");
if (res != null && res['data'] != null) {
return res['data'];
}
return res;
}
//
getCaptcha() async {
Map res =
await service.getClient("/admin/base/open/captcha?height=40&width=150");
return res['data'];
if (res['data'] != null) {
return res['data'];
}
return {};
}
getAccountLogin(String captchaId, String password, String username,
@ -195,40 +280,54 @@ class GetServices {
return res;
}
getRtuLast() async {
getRtuLast(String projType, String projCode) async {
Map res = await service.getClient(
"/api/t2n/rtu/rtu_last?proj_type=$projType&proj_code=$projCode");
return res['data'];
if (res['data'] != null) {
return res['data'];
}
return [];
}
getCoordTrans() async {
getCoordTrans(String projType, String projCode) async {
Map res = await service.getClient(
"/api/comm/coord_trans/list?proj_type=$projType&proj_code=$projCode");
return res['data'];
if (res['data'] != null) {
return res['data'];
}
return {};
}
//
getRcordData(int page, int size, String date,
[String sort = "desc", String order = "pile_id", int? tid]) async {
Map res = await service.getClient(
"/api/$projType/record/page?page=$page&size=$size&org_code=a&proj_code=$projCode&tid=$tid&date=$date&sort=$sort&order=$order");
return res['data'];
}
// //
// getRcordData(int page, int size, String date,
// [String sort = "desc", String order = "pile_id", int? tid]) async {
// Map res = await service.getClient(
// "/api/$projType/record/page?page=$page&size=$size&org_code=$org_code&proj_code=$projCode&tid=$tid&date=$date&sort=$sort&order=$order");
// if (res['data'] != null) {
// return res['data'];
// }
// return [];
// }
getRcordList(String date, [String? dateEnd, int? tid]) async {
getRcordList(String org_code, String projCode, String projType, String date,
[String? dateEnd, int? tid]) async {
dateEnd ??= date;
Map res = await service.getClient(
"/api/$projType/record/list?org_code=a&proj_code=$projCode&date=$date&dateEnd=$dateEnd"); //&tid=1000
return res['data'];
Map? res = await service.getClient(
"/api/$projType/record/list?org_code=$org_code&proj_code=$projCode&date=$date&dateEnd=$dateEnd"); //&tid=1000
if (res != null && res['data'] != null) {
return res['data'];
}
return [];
}
plumAdd(List<PointXY> list) async {
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'];

View File

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

View File

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

View File

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

View File

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