优化
This commit is contained in:
@@ -144,8 +144,7 @@ class CircQueue<T> {
|
||||
Future<bool> send(T item, {int timeoutMs = 0}) async {
|
||||
final start = DateTime.now().millisecondsSinceEpoch;
|
||||
while (!enter(item)) {
|
||||
if (timeoutMs > 0 &&
|
||||
DateTime.now().millisecondsSinceEpoch - start >= timeoutMs) {
|
||||
if (timeoutMs > 0 && DateTime.now().millisecondsSinceEpoch - start >= timeoutMs) {
|
||||
return false;
|
||||
}
|
||||
await Future.delayed(const Duration(milliseconds: 1));
|
||||
@@ -159,8 +158,7 @@ class CircQueue<T> {
|
||||
while (true) {
|
||||
final item = out();
|
||||
if (item != null) return item;
|
||||
if (timeoutMs > 0 &&
|
||||
DateTime.now().millisecondsSinceEpoch - start >= timeoutMs) {
|
||||
if (timeoutMs > 0 && DateTime.now().millisecondsSinceEpoch - start >= timeoutMs) {
|
||||
return null;
|
||||
}
|
||||
await Future.delayed(const Duration(milliseconds: 1));
|
||||
@@ -198,11 +196,7 @@ class TracePoint<T> {
|
||||
|
||||
/// 构造函数
|
||||
TracePoint({int queueCapacity = 5, int maxMemoryBytes = 1024 * 1024}) {
|
||||
_queue = CircQueue<T>(
|
||||
queueCapacity,
|
||||
deepCopy: true,
|
||||
maxMemoryBytes: maxMemoryBytes,
|
||||
);
|
||||
_queue = CircQueue<T>(queueCapacity, deepCopy: true, maxMemoryBytes: maxMemoryBytes);
|
||||
_lock = TryLock();
|
||||
reset();
|
||||
}
|
||||
@@ -225,9 +219,7 @@ class TracePoint<T> {
|
||||
void upsert(T point, [TPAction act = TPAction.UPDATE]) {
|
||||
switch (_mode) {
|
||||
case TPMode.NAVIGATION:
|
||||
act == TPAction.UPDATE
|
||||
? _updateCurrentPoint(point)
|
||||
: _addCompletePoint(point);
|
||||
act == TPAction.UPDATE ? _updateCurrentPoint(point) : _addCompletePoint(point);
|
||||
break;
|
||||
case TPMode.LOCATION:
|
||||
_updateCurrentPoint(point);
|
||||
@@ -262,9 +254,7 @@ class TracePoint<T> {
|
||||
switch (_mode) {
|
||||
case TPMode.NAVIGATION:
|
||||
if (_tracePoint.isEmpty) {
|
||||
print(
|
||||
'updateCurrentPoint: tracePoint is empty , wait first completed point, discard current point: $point',
|
||||
);
|
||||
print('updateCurrentPoint: tracePoint is empty , wait first completed point, discard current point: $point');
|
||||
} else {
|
||||
_tracePoint = _tracePoint.sublist(0, _completePointIndex);
|
||||
_tracePoint.add(point);
|
||||
@@ -328,8 +318,7 @@ class TracePoint<T> {
|
||||
return;
|
||||
}
|
||||
|
||||
final hasCurrentPoint =
|
||||
_tracePoint.isNotEmpty && _completePointIndex < _tracePoint.length;
|
||||
final hasCurrentPoint = _tracePoint.isNotEmpty && _completePointIndex < _tracePoint.length;
|
||||
|
||||
if (hasCurrentPoint) {
|
||||
_tracePoint = _tracePoint.sublist(0, _completePointIndex);
|
||||
|
||||
@@ -56,6 +56,13 @@ const String kSavedGcjOuterPoints = 'saved_gcj_outer_points';
|
||||
const String kSavedMarkedPoints = 'saved_marked_points';
|
||||
const String kSavedObstacleHoles = 'saved_obstacle_holes';
|
||||
const String kSavedIsWorkAreaCompleted = 'saved_is_work_area_completed';
|
||||
const String kSavedIsWorkPanelOpen = 'saved_is_work_panel_open';
|
||||
const String kSavedSelectedPlot = 'saved_selected_plot';
|
||||
const String kSavedStartWorkList = 'saved_start_work_list';
|
||||
const String kSavedWorkMode = 'saved_work_mode';
|
||||
const String kSavedWorkStatus = 'saved_work_status'; // 作业状态(idle/working/paused)
|
||||
const String kSavedIsStartWork = 'saved_is_start_work'; // 是否开始作业
|
||||
const String kSavedIsStopWork = 'saved_is_stop_work'; // 是否点击过停止
|
||||
|
||||
// 保持 PlotData 类不变
|
||||
class PlotData {
|
||||
@@ -86,6 +93,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
bool _isVideoDialogOpen = false; // 控制视频弹窗显示
|
||||
String _videoStreamUrl = "";
|
||||
bool isStopWork = false; //是否点击过停止
|
||||
bool isreceiveFirstCompletePoint = false;
|
||||
Offset _videoPopupPos = const Offset(0, 100); // 弹窗初始位置
|
||||
// 🔥 关键修复:添加截图全局Key
|
||||
final GlobalKey _mapRepaintKey = GlobalKey();
|
||||
@@ -243,6 +251,16 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
Future<void> _loadSavedData() async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final workStatusStr = prefs.getString(kSavedWorkStatus);
|
||||
if (workStatusStr != null) {
|
||||
_workStatus = WorkStatus.values.firstWhere((e) => e.toString() == workStatusStr, orElse: () => WorkStatus.idle);
|
||||
}
|
||||
|
||||
// 2. 恢复是否开始作业
|
||||
isStartWork = prefs.getBool(kSavedIsStartWork) ?? false;
|
||||
|
||||
// 3. 恢复是否点击过停止
|
||||
isStopWork = prefs.getBool(kSavedIsStopWork) ?? false;
|
||||
|
||||
// 加载路径点
|
||||
final pathJson = prefs.getString(kSavedGcjPathPoints);
|
||||
@@ -278,6 +296,31 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
_isWorkAreaCompleted = prefs.getBool(kSavedIsWorkAreaCompleted) ?? false;
|
||||
_saveBoxOpen = _isWorkAreaCompleted;
|
||||
|
||||
// ====================== 🔥 新增恢复逻辑 ======================
|
||||
// 1. 恢复作业面板状态
|
||||
_isWorkPanelOpen = prefs.getBool(kSavedIsWorkPanelOpen) ?? false;
|
||||
|
||||
// 2. 恢复作业模式
|
||||
workMode = prefs.getString(kSavedWorkMode) ?? "弓字模式";
|
||||
|
||||
// 3. 恢复作业列表
|
||||
final startWorkJson = prefs.getString(kSavedStartWorkList);
|
||||
if (startWorkJson != null) {
|
||||
startWorkList = jsonDecode(startWorkJson);
|
||||
}
|
||||
|
||||
// 4. 恢复选中地块
|
||||
final selectedPlotJson = prefs.getString(kSavedSelectedPlot);
|
||||
if (selectedPlotJson != null && selectedPlotJson.isNotEmpty) {
|
||||
final Map<String, dynamic> plotMap = jsonDecode(selectedPlotJson);
|
||||
_selectedPlot = PlotData(
|
||||
id: plotMap['id'] ?? '',
|
||||
plotName: plotMap['plotName'] ?? '',
|
||||
imageUrl: plotMap['imageUrl'] ?? '',
|
||||
jsonData: plotMap['jsonData'],
|
||||
);
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
// 移动地图到绘制内容中心
|
||||
@@ -318,6 +361,35 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
|
||||
// 保存作业区域完成状态
|
||||
prefs.setBool(kSavedIsWorkAreaCompleted, _isWorkAreaCompleted);
|
||||
|
||||
// 1. 保存作业面板显示状态
|
||||
prefs.setBool(kSavedIsWorkPanelOpen, _isWorkPanelOpen);
|
||||
|
||||
// 2. 保存作业模式
|
||||
prefs.setString(kSavedWorkMode, workMode);
|
||||
|
||||
// 3. 保存作业列表
|
||||
prefs.setString(kSavedStartWorkList, jsonEncode(startWorkList));
|
||||
prefs.setString(kSavedWorkStatus, _workStatus.toString());
|
||||
|
||||
// 2. 保存是否开始作业
|
||||
prefs.setBool(kSavedIsStartWork, isStartWork);
|
||||
|
||||
// 3. 保存是否点击过停止
|
||||
prefs.setBool(kSavedIsStopWork, isStopWork);
|
||||
|
||||
// 4. 保存选中地块
|
||||
if (_selectedPlot != null) {
|
||||
final plotMap = {
|
||||
'id': _selectedPlot!.id,
|
||||
'plotName': _selectedPlot!.plotName,
|
||||
'imageUrl': _selectedPlot!.imageUrl,
|
||||
'jsonData': _selectedPlot!.jsonData,
|
||||
};
|
||||
prefs.setString(kSavedSelectedPlot, jsonEncode(plotMap));
|
||||
} else {
|
||||
prefs.remove(kSavedSelectedPlot);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('保存本地数据失败:$e');
|
||||
}
|
||||
@@ -764,6 +836,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
// 2. 重置所有页面状态(恢复初始值)
|
||||
setState(() {
|
||||
_traceManager.setMode(TPMode.LOCATION);
|
||||
isreceiveFirstCompletePoint = false;
|
||||
|
||||
// 2. 清空打点和轨迹数据
|
||||
_markedPoints.clear();
|
||||
@@ -930,6 +1003,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
_traceManager.reset();
|
||||
_mapController.dispose();
|
||||
_pathPlanningSub?.cancel(); // 🔥 取消订阅
|
||||
_saveDataToLocal(); // 🔥 页面销毁时保存最终状态
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -1223,7 +1297,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
strokeWidth: 1.0, // 折线宽度
|
||||
isDotted: false, // 非虚线(Line模式)
|
||||
borderColor: Colors.white, // 可选:添加白色描边,提升辨识度
|
||||
borderStrokeWidth: 0.5,
|
||||
borderStrokeWidth: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -1457,9 +1531,9 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
for (int i = 0; i < gctracePoint!.length - 1; i++)
|
||||
Polyline(
|
||||
points: [gctracePoint![i], gctracePoint![i + 1]],
|
||||
color: Colors.blueAccent,
|
||||
color: Color(0xFF00C853),
|
||||
strokeWidth: 3,
|
||||
isDotted: true, // 虚线区分作业区域
|
||||
isDotted: false, // 虚线区分作业区域
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -1469,12 +1543,14 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
|
||||
/// 开始作业
|
||||
void _startWork() async {
|
||||
_traceManager.reset();
|
||||
isStopWork = false;
|
||||
_saveDataToLocal();
|
||||
if (startWorkList.isEmpty) {
|
||||
ToastUtils.showInfo(context, '作业列表为空,请重新选择路径');
|
||||
return;
|
||||
}
|
||||
_traceManager.setMode(TPMode.NAVIGATION);
|
||||
_traceManager.setMode(TPMode.LOCATION);
|
||||
|
||||
setState(() {
|
||||
isStartWork = true; // 🔥 关键:停止作业标志
|
||||
@@ -1520,6 +1596,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
isStartWork = false; // 🔥 关键:停止作业标志
|
||||
_workStatus = WorkStatus.paused;
|
||||
});
|
||||
_saveDataToLocal(); // 🔥 保存暂停状态
|
||||
context.read<DevicesCubit>().updateAppState(AppState.none);
|
||||
await context.read<DevicesCubit>().pauseRoutePlanning();
|
||||
}
|
||||
@@ -1531,7 +1608,10 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
_showHeadingWarn = false;
|
||||
_showControlModeWarn = false;
|
||||
isStopWork = true; //已经点击过停止
|
||||
isreceiveFirstCompletePoint = false;
|
||||
});
|
||||
_traceManager.reset();
|
||||
_saveDataToLocal(); // 🔥 保存暂停状态
|
||||
_traceManager.setMode(TPMode.LOCATION);
|
||||
context.read<DevicesCubit>().updateAppState(AppState.none);
|
||||
await context.read<DevicesCubit>().stopRoutePlanning();
|
||||
@@ -1544,6 +1624,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
setState(() {
|
||||
_workStatus = WorkStatus.working;
|
||||
});
|
||||
_saveDataToLocal(); // 🔥 保存暂停状态
|
||||
context.read<DevicesCubit>().updateAppState(AppState.routePlanning);
|
||||
await context.read<DevicesCubit>().resumeRoutePlanning();
|
||||
}
|
||||
@@ -1631,7 +1712,8 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
_showControlModeWarn = false;
|
||||
isStartWork = false;
|
||||
});
|
||||
if (isStopWork) return;
|
||||
_saveDataToLocal();
|
||||
if (isStopWork || !isStartWork) return;
|
||||
_stopWork();
|
||||
},
|
||||
icon: const Icon(Icons.close, color: Colors.grey, size: 20),
|
||||
@@ -2078,8 +2160,15 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
LatLng? targetLatLng;
|
||||
if (arriLatitude != null && arriLongitude != null) {
|
||||
targetLatLng = LatLng(arriLatitude, arriLongitude);
|
||||
debugPrint("${targetLatLng}收到完成点gctracePoint");
|
||||
_traceManager.upsert(targetLatLng, TPAction.ADD);
|
||||
if (__isValidLatLng(targetLatLng)) {
|
||||
debugPrint("${targetLatLng}收到完成点gctracePoint");
|
||||
if (!isreceiveFirstCompletePoint) {
|
||||
_traceManager.setMode(TPMode.NAVIGATION);
|
||||
isreceiveFirstCompletePoint = true;
|
||||
}
|
||||
|
||||
_traceManager.upsert(targetLatLng, TPAction.ADD);
|
||||
}
|
||||
}
|
||||
|
||||
double currentLat = 0.0;
|
||||
@@ -2092,8 +2181,9 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
if (isFinishWork) {
|
||||
_workStatus = WorkStatus.idle;
|
||||
ToastUtils.showError(context, '作业已停止');
|
||||
_traceManager.setMode(TPMode.LOCATION);
|
||||
_traceManager.reset();
|
||||
isStopWork = true;
|
||||
isreceiveFirstCompletePoint = false;
|
||||
}
|
||||
|
||||
if (state is DeviceStatusUpdated) {
|
||||
|
||||
Reference in New Issue
Block a user