优化路径规划和 退出登录逻辑
This commit is contained in:
@@ -64,6 +64,7 @@ const String kSavedWorkStatus = 'saved_work_status'; // 作业状态(idle/work
|
||||
const String kSavedIsStartWork = 'saved_is_start_work'; // 是否开始作业
|
||||
const String kSavedIsStopWork = 'saved_is_stop_work'; // 是否点击过停止
|
||||
const String kSavedTPMode = "saved_tp_mode";
|
||||
const String kSavedCurrentRobotMode = "kSavedCurrentRobotMode";
|
||||
|
||||
// 保持 PlotData 类不变
|
||||
class PlotData {
|
||||
@@ -97,6 +98,8 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
bool isreceiveFirstCompletePoint = false;
|
||||
Offset _videoPopupPos = const Offset(0, 100); // 弹窗初始位置
|
||||
final GlobalKey _mapRepaintKey = GlobalKey();
|
||||
// 用于存储当前页面的 Toast OverlayEntry
|
||||
List<OverlayEntry> _toastEntries = [];
|
||||
|
||||
final MapController _mapController = MapController();
|
||||
// 初始化轨迹管理器(泛型指定为LatLng)
|
||||
@@ -237,7 +240,22 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
await LocationUtils.clearCache(LocationUtils.kSavedMarkedPoints);
|
||||
await LocationUtils.clearCache(LocationUtils.kSavedObstacleHoles);
|
||||
await LocationUtils.clearCache(LocationUtils.kSavedIsWorkAreaCompleted);
|
||||
debugPrint('本地存储的绘制数据已清空');
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove(kSavedWorkStatus);
|
||||
await prefs.remove(kSavedTPMode);
|
||||
await prefs.remove(kSavedCurrentRobotMode); // 机器人模式
|
||||
await prefs.remove("kSavedTypedPathList"); // 生成的路径
|
||||
await prefs.remove(kSavedIsStartWork);
|
||||
await prefs.remove(kSavedIsStopWork);
|
||||
await prefs.remove(kSavedGcjPathPoints); // 路径点
|
||||
await prefs.remove(kSavedGcjOuterPoints); // 外边框
|
||||
await prefs.remove(kSavedMarkedPoints); // 打点
|
||||
await prefs.remove(kSavedObstacleHoles); // 障碍物
|
||||
await prefs.remove(kSavedIsWorkAreaCompleted);
|
||||
await prefs.remove(kSavedIsWorkPanelOpen);
|
||||
await prefs.remove(kSavedWorkMode);
|
||||
await prefs.remove(kSavedStartWorkList);
|
||||
await prefs.remove(kSavedSelectedPlot);
|
||||
} catch (e) {
|
||||
debugPrint('清空本地数据失败:$e');
|
||||
}
|
||||
@@ -256,6 +274,22 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
_traceManager.setMode(TPMode.values.firstWhere((e) => e.toString() == modeStr));
|
||||
}
|
||||
|
||||
final robotModeStr = prefs.getString(kSavedCurrentRobotMode);
|
||||
if (robotModeStr != null) {
|
||||
_currentRobotMode = RobotMode.values.firstWhere((e) => e.toString() == robotModeStr, orElse: () => RobotMode.point);
|
||||
}
|
||||
|
||||
// 读取 生成完成的路径 typedPathList
|
||||
final typedPathString = prefs.getString("kSavedTypedPathList");
|
||||
if (typedPathString != null) {
|
||||
final List<dynamic> typedPathJson = jsonDecode(typedPathString);
|
||||
setState(() {
|
||||
typedPathList = typedPathJson.map((p) {
|
||||
return work_area_model.DeviceAddPathPointModel(latitude: p['lat'], longitude: p['lng']);
|
||||
}).toList();
|
||||
});
|
||||
}
|
||||
|
||||
// 2. 恢复是否开始作业
|
||||
isStartWork = prefs.getBool(kSavedIsStartWork) ?? false;
|
||||
|
||||
@@ -280,7 +314,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
final markedJson = prefs.getString(kSavedMarkedPoints);
|
||||
if (markedJson != null) {
|
||||
final List<dynamic> markedList = jsonDecode(markedJson);
|
||||
_markedPoints = markedList.map((item) => LatLng(double.parse(item['lat'].toString()), double.parse(item['lng'].toString()))).toList().toList();
|
||||
_markedPoints = markedList.map((item) => LatLng(double.parse(item['lat'].toString()), double.parse(item['lng'].toString()))).toList();
|
||||
}
|
||||
|
||||
// 加载障碍物数据
|
||||
@@ -298,11 +332,6 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
|
||||
// 1. 恢复作业面板状态
|
||||
_isWorkPanelOpen = prefs.getBool(kSavedIsWorkPanelOpen) ?? false;
|
||||
// if (isStartWork && !isStopWork) {
|
||||
// _isWorkPanelOpen = true;
|
||||
// } else {
|
||||
// _isWorkPanelOpen = false;
|
||||
// }
|
||||
|
||||
// 2. 恢复作业模式
|
||||
workMode = prefs.getString(kSavedWorkMode) ?? "弓字模式";
|
||||
@@ -325,6 +354,19 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
);
|
||||
}
|
||||
|
||||
// ==================== ✅ 核心修复 ====================
|
||||
// 1. 从缓存恢复后,强制让 _markedPoints 同步给外边框(解决不显示)
|
||||
if (_markedPoints.isNotEmpty && gcjOuterPoints.isEmpty) {
|
||||
gcjOuterPoints = List.from(_markedPoints);
|
||||
}
|
||||
|
||||
// 2. 关键:同步机器人模式坐标(保存时边框不丢失)
|
||||
if (_currentRobotMode == RobotMode.point) {
|
||||
_robotModeWgsPoints = _markedPoints.map((p) {
|
||||
return gcj02ToWgs84(p.latitude, p.longitude);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
// 移动地图到绘制内容中心
|
||||
@@ -363,6 +405,9 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
}).toList();
|
||||
prefs.setString(kSavedObstacleHoles, jsonEncode(obstacleList));
|
||||
|
||||
final typedPath = typedPathList.map((point) => {'lat': point.latitude, 'lng': point.longitude}).toList();
|
||||
prefs.setString("kSavedTypedPathList", jsonEncode(typedPath));
|
||||
|
||||
// 保存作业区域完成状态
|
||||
prefs.setBool(kSavedIsWorkAreaCompleted, _isWorkAreaCompleted);
|
||||
|
||||
@@ -384,6 +429,8 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
// 保存当前模式到本地缓存
|
||||
prefs.setString(kSavedTPMode, _traceManager.getMode().toString());
|
||||
|
||||
prefs.setString(kSavedCurrentRobotMode, _currentRobotMode.toString());
|
||||
|
||||
// 4. 保存选中地块
|
||||
if (_selectedPlot != null) {
|
||||
final plotMap = {
|
||||
@@ -469,12 +516,14 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
if (isStartWork && !isStopWork) {
|
||||
if (headingStatus == 0) {
|
||||
if (!_showHeadingWarn) {
|
||||
setState(() {
|
||||
_showHeadingWarn = true;
|
||||
});
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_showHeadingWarn = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (_showHeadingWarn) {
|
||||
if (_showHeadingWarn && mounted) {
|
||||
setState(() {
|
||||
_showHeadingWarn = false;
|
||||
});
|
||||
@@ -486,13 +535,13 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
// ==============================================
|
||||
String mode = controlMode?.toString() ?? "";
|
||||
if (mode != "3") {
|
||||
if (!_showControlModeWarn) {
|
||||
if (!_showControlModeWarn && mounted) {
|
||||
setState(() {
|
||||
_showControlModeWarn = true;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (_showControlModeWarn) {
|
||||
if (_showControlModeWarn && mounted) {
|
||||
setState(() {
|
||||
_showControlModeWarn = false;
|
||||
});
|
||||
@@ -500,7 +549,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
}
|
||||
} else {
|
||||
// 未作业 → 自动隐藏所有警告
|
||||
if (_showHeadingWarn || _showControlModeWarn) {
|
||||
if ((_showHeadingWarn || _showControlModeWarn) && mounted) {
|
||||
setState(() {
|
||||
_showHeadingWarn = false;
|
||||
_showControlModeWarn = false;
|
||||
@@ -560,7 +609,9 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
} else {
|
||||
// 截图失败时,允许空图片保存(可根据业务调整为强制失败)
|
||||
_savePlotData(plotName, null);
|
||||
ToastUtils.showWarn(context, '地块保存成功,但地图截图生成失败!');
|
||||
_showPageToast(message: "地块保存成功,但地图截图生成失败!", type: ToastType.warn);
|
||||
|
||||
//ToastUtils.showWarn(context, '地块保存成功,但地图截图生成失败!');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('地块保存成功,但地图截图生成失败!'), backgroundColor: Colors.amber));
|
||||
}
|
||||
}
|
||||
@@ -621,7 +672,9 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
// 1. 获取用户ID
|
||||
final userId = context.read<AppUserCubit>().state.user?.userId ?? "";
|
||||
if (userId.isEmpty) {
|
||||
ToastUtils.showError(context, '用户ID为空,无法保存!');
|
||||
_showPageToast(message: "用户ID为空,无法保存!", type: ToastType.error);
|
||||
|
||||
//ToastUtils.showError(context, '用户ID为空,无法保存!');
|
||||
return;
|
||||
}
|
||||
debugPrint("===打印生成的路径开始 ");
|
||||
@@ -629,10 +682,20 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
debugPrint(typedPathList[i].toString());
|
||||
}
|
||||
debugPrint("===打印生成的路径结束");
|
||||
debugPrint("$_robotModeWgsPoints $gcjOuterPoints $_currentRobotMode _robotModeWgsPointsgcjOuterPoints ");
|
||||
// 2. 构造 SavePath 数据 (严格对应你的 JS 结构)
|
||||
final Map<String, dynamic> savePath = {
|
||||
//'img': imgBase64 ?? '', // 截图的 Base64 字符串
|
||||
'name': plotName, // 地块名称
|
||||
'outer':
|
||||
// 核心修改:根据机器人模式选择不同的坐标源
|
||||
(_currentRobotMode == RobotMode.robot ? _robotModeWgsPoints : gcjOuterPoints).map((point) {
|
||||
final wgs84 = _currentRobotMode == RobotMode.robot
|
||||
? point // Robot模式直接使用原始WGS84坐标
|
||||
: gcj02ToWgs84(point.latitude, point.longitude); // Point模式转换
|
||||
|
||||
return {'lng': wgs84.longitude, 'lat': wgs84.latitude};
|
||||
}).toList(),
|
||||
'path': _currentWorkMode == WorkMode.custom
|
||||
? [] // 自定义模式 path 为空数组
|
||||
: typedPathList
|
||||
@@ -645,18 +708,9 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
)
|
||||
.toList(),
|
||||
|
||||
'outer':
|
||||
// 核心修改:根据机器人模式选择不同的坐标源
|
||||
(_currentRobotMode == RobotMode.robot ? _robotModeWgsPoints : gcjOuterPoints).map((point) {
|
||||
final wgs84 = _currentRobotMode == RobotMode.robot
|
||||
? point // Robot模式直接使用原始WGS84坐标
|
||||
: gcj02ToWgs84(point.latitude, point.longitude); // Point模式转换
|
||||
|
||||
return {'lng': wgs84.longitude, 'lat': wgs84.latitude};
|
||||
}).toList(),
|
||||
|
||||
'planModel': _currentWorkMode == WorkMode.bow ? 0 : 2, // 作业模式值
|
||||
};
|
||||
debugPrint("$savePath savePath");
|
||||
|
||||
// 3. 构造 workRecord (包裹一层)
|
||||
final Map<String, dynamic> workRecord = {
|
||||
@@ -690,11 +744,11 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
),
|
||||
);
|
||||
|
||||
//_debugPrintMultipartRequest(request);
|
||||
|
||||
// 7. 发送请求
|
||||
try {
|
||||
ToastUtils.showLoading(context, '正在保存地块「$plotName」...');
|
||||
_showPageToast(message: "正在保存地块「$plotName」...", type: ToastType.loading);
|
||||
|
||||
//ToastUtils.showLoading(context, '正在保存地块「$plotName」...');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('正在保存地块...'), backgroundColor: Colors.blue));
|
||||
|
||||
final http.StreamedResponse response = await request.send();
|
||||
@@ -702,7 +756,9 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
debugPrint('保存地块响应体: $responseBody');
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
ToastUtils.showSuccess(context, '地块「$plotName」保存成功!');
|
||||
_showPageToast(message: "地块「$plotName」保存成功!", type: ToastType.success);
|
||||
|
||||
//ToastUtils.showSuccess(context, '地块「$plotName」保存成功!');
|
||||
_clearLocalData();
|
||||
//ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('地块「$plotName」保存成功!'), backgroundColor: Colors.green));
|
||||
// 保存成功
|
||||
@@ -711,6 +767,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
gcjPathPoints.clear(); // 清空路径
|
||||
gcjOuterPoints.clear(); // 清空外边界
|
||||
_robotModeWgsPoints.clear();
|
||||
_obstacleHoles.clear();
|
||||
|
||||
_isPanelOpen = false; // 关闭操作面板
|
||||
_isWorkAreaCompleted = false; // 重置作业区域完成状态
|
||||
@@ -720,7 +777,9 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('保存失败: $e');
|
||||
ToastUtils.showError(context, '保存失败: ${e.toString()}');
|
||||
_showPageToast(message: "保存失败: ${e.toString()}", type: ToastType.error);
|
||||
|
||||
//ToastUtils.showError(context, '保存失败: ${e.toString()}');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('保存失败: ${e.toString()}'), backgroundColor: Colors.red));
|
||||
}
|
||||
}
|
||||
@@ -739,17 +798,21 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
// 1. 作业区域模式
|
||||
if (_currentAreaMode == AreaMode.work) {
|
||||
if (_markedPoints.isNotEmpty) {
|
||||
_robotModeWgsPoints.removeLast();
|
||||
_markedPoints.removeLast();
|
||||
// 单独判断,单独删除
|
||||
if (_robotModeWgsPoints.isNotEmpty) {
|
||||
_robotModeWgsPoints.removeLast();
|
||||
}
|
||||
if (_markedPoints.isNotEmpty) {
|
||||
_markedPoints.removeLast();
|
||||
}
|
||||
|
||||
// 作业点撤回后,若路径已生成,重新生成路径(保持同步)
|
||||
if (_isWorkAreaCompleted && _markedPoints.length >= 3) {
|
||||
_generatePath(showTips: false);
|
||||
}
|
||||
ToastUtils.showInfo(context, '已撤回作业区域最后一个点,剩余${_markedPoints.length}个点');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('已撤回作业区域最后一个点,剩余${_markedPoints.length}个点')));
|
||||
_showPageToast(message: "已撤回作业区域最后一个点,剩余${_markedPoints.length}个点", type: ToastType.info);
|
||||
} else {
|
||||
ToastUtils.showInfo(context, '暂无作业区域点可撤回');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('暂无作业区域点可撤回')));
|
||||
_showPageToast(message: "暂无作业区域点可撤回", type: ToastType.info);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -757,15 +820,19 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
// 2. 空洞模式(完成后优先撤回已完成的空洞)
|
||||
if (_currentAreaMode == AreaMode.obstacle) {
|
||||
if (_currentObstaclePoints.isNotEmpty) {
|
||||
_currentObstaclePoints.removeLast();
|
||||
_robotModeObsWgsPoints.removeLast();
|
||||
// 单独判断,单独删除
|
||||
if (_currentObstaclePoints.isNotEmpty) {
|
||||
_currentObstaclePoints.removeLast();
|
||||
}
|
||||
if (_robotModeObsWgsPoints.isNotEmpty) {
|
||||
_robotModeObsWgsPoints.removeLast();
|
||||
}
|
||||
|
||||
if (_currentObstaclePoints.isEmpty) {
|
||||
_isObstacleEditing = false;
|
||||
}
|
||||
ToastUtils.showInfo(context, '已撤回当前空洞最后一个点,剩余${_currentObstaclePoints.length}个点');
|
||||
|
||||
//ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('已撤回当前空洞最后1个点,剩余${_currentObstaclePoints.length}个点')));
|
||||
return; // 撤完点就结束,不执行后面的逻辑
|
||||
_showPageToast(message: "已撤回当前空洞最后一个点,剩余${_currentObstaclePoints.length}个点", type: ToastType.info);
|
||||
return;
|
||||
}
|
||||
|
||||
// 第二步:当前空洞无点可撤 → 再撤回「上一个完整空洞」
|
||||
@@ -775,15 +842,12 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
if (_isWorkAreaCompleted) {
|
||||
_generatePath(showTips: false);
|
||||
}
|
||||
ToastUtils.showInfo(context, '已撤回上一个完整空洞,剩余${_obstacleHoles.length}个空洞');
|
||||
|
||||
//ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('已撤回上一个完整空洞,剩余${_obstacleHoles.length}个空洞')));
|
||||
_showPageToast(message: "已撤回上一个完整空洞,剩余${_obstacleHoles.length}个空洞", type: ToastType.info);
|
||||
return;
|
||||
}
|
||||
|
||||
// 第三步:无任何可撤内容
|
||||
ToastUtils.showInfo(context, '暂无空洞可撤回');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('暂无空洞可撤回')));
|
||||
_showPageToast(message: "暂无空洞可撤回", type: ToastType.info);
|
||||
}
|
||||
});
|
||||
_saveDataToLocal();
|
||||
@@ -795,7 +859,9 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
// 1. 作业区域模式:清空作业点 + 重置路径
|
||||
if (_currentAreaMode == AreaMode.work) {
|
||||
if (_markedPoints.isEmpty) {
|
||||
ToastUtils.showInfo(context, '暂无作业区域点可删除');
|
||||
_showPageToast(message: "暂无作业区域点可删除", type: ToastType.info);
|
||||
|
||||
//ToastUtils.showInfo(context, '暂无作业区域点可删除');
|
||||
|
||||
//ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('暂无作业区域点可删除')));
|
||||
return;
|
||||
@@ -804,17 +870,21 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
gcjPathPoints.clear();
|
||||
gcjOuterPoints.clear();
|
||||
_robotModeWgsPoints.clear();
|
||||
_obstacleHoles.clear();
|
||||
_isWorkAreaCompleted = false;
|
||||
_saveBoxOpen = false;
|
||||
typedPathList.clear();
|
||||
ToastUtils.showSuccess(context, '已清空所有作业区域点和路径');
|
||||
_showPageToast(message: "已清空所有作业区域点和路径", type: ToastType.success);
|
||||
//ToastUtils.showSuccess(context, '已清空所有作业区域点和路径');
|
||||
|
||||
//ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('已清空所有作业区域点和路径')));
|
||||
}
|
||||
// 2. 空洞模式:清空所有空洞 + 恢复UI + 重新生成路径
|
||||
else if (_currentAreaMode == AreaMode.obstacle) {
|
||||
if (_obstacleHoles.isEmpty && _currentObstaclePoints.isEmpty) {
|
||||
ToastUtils.showInfo(context, '暂无障碍物可删除');
|
||||
_showPageToast(message: "暂无障碍物可删除", type: ToastType.info);
|
||||
|
||||
//ToastUtils.showInfo(context, '暂无障碍物可删除');
|
||||
return;
|
||||
}
|
||||
_obstacleHoles.clear();
|
||||
@@ -825,7 +895,8 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
if (_isWorkAreaCompleted) {
|
||||
_generatePath(showTips: false);
|
||||
}
|
||||
ToastUtils.showSuccess(context, '已清空所有障碍物');
|
||||
_showPageToast(message: "已清空所有障碍物", type: ToastType.success);
|
||||
//ToastUtils.showSuccess(context, '已清空所有障碍物');
|
||||
}
|
||||
});
|
||||
_saveDataToLocal();
|
||||
@@ -844,100 +915,82 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
|
||||
// ========== 新增:页面刷新初始化方法 ==========
|
||||
Future<void> _handleRefresh() async {
|
||||
debugPrint("点击刷新");
|
||||
// 防止重复刷新
|
||||
_cancelAllToast(); // 👇 加这行
|
||||
if (_isRefreshing) return;
|
||||
// 🔥 修复1:保存当前有效的地图中心和缩放级别(而非定位坐标)
|
||||
|
||||
final savedZoom = _mapController.camera?.zoom ?? 17.0;
|
||||
setState(() {
|
||||
_isRefreshing = true; // 标记开始刷新
|
||||
_isRefreshing = true;
|
||||
});
|
||||
debugPrint("点击刷新111");
|
||||
|
||||
try {
|
||||
if (_currentLatLng != null && _isValidLatLng(_currentLatLng!.latitude, _currentLatLng!.longitude)) {
|
||||
_mapController.move(_currentLatLng!, 18);
|
||||
debugPrint("点击刷新333");
|
||||
}
|
||||
debugPrint("点击刷新2222");
|
||||
// 2. 重置所有页面状态(恢复初始值)
|
||||
|
||||
setState(() {
|
||||
_traceManager.setMode(TPMode.LOCATION);
|
||||
isreceiveFirstCompletePoint = false;
|
||||
|
||||
// 2. 清空打点和轨迹数据
|
||||
// 清空所有绘制数据
|
||||
_markedPoints.clear();
|
||||
gcjPathPoints.clear();
|
||||
_robotModeObsWgsPoints.clear();
|
||||
gcjOuterPoints.clear();
|
||||
_robotModeWgsPoints.clear();
|
||||
_obstacleHoles.clear();
|
||||
|
||||
// 3. 重置作业区域状态
|
||||
// 重置作业区域状态
|
||||
_isWorkAreaCompleted = false;
|
||||
_saveBoxOpen = false;
|
||||
_showControlModeWarn = false;
|
||||
_showHeadingWarn = false;
|
||||
|
||||
// 4. 重置面板状态
|
||||
_isPanelOpen = false;
|
||||
_directionBoxOpen = false;
|
||||
_isListBoxOpen = false;
|
||||
_isWorkPanelOpen = false;
|
||||
// ==============================================
|
||||
// 🔥 核心修复:强制关闭所有弹窗/面板/警告
|
||||
// ==============================================
|
||||
_showControlModeWarn = false; // 关闭远程模式警告
|
||||
_showHeadingWarn = false; // 关闭航向警告
|
||||
_isPanelOpen = false; // 关闭底部操作面板
|
||||
_directionBoxOpen = false; // 关闭航线方向面板
|
||||
_isListBoxOpen = false; // 关闭地块列表面板
|
||||
_isWorkPanelOpen = false; // 关闭作业面板
|
||||
_isVideoDialogOpen = false; // 关闭视频弹窗
|
||||
_isObstacleEditing = false; // 退出障碍物编辑
|
||||
_selectedPlot = null; // 清空选中地块
|
||||
|
||||
// 5. 重置障碍物数据
|
||||
_obstacleHoles.clear();
|
||||
_currentObstaclePoints.clear();
|
||||
_isObstacleEditing = false;
|
||||
|
||||
// 6. 重置选中状态
|
||||
_selectedPlot = null;
|
||||
|
||||
// 7. 重置作业模式
|
||||
// 重置模式
|
||||
_currentRobotMode = RobotMode.robot;
|
||||
_currentAreaMode = AreaMode.work;
|
||||
_currentWorkMode = WorkMode.bow;
|
||||
|
||||
// 8. 重置作业参数
|
||||
// 重置参数
|
||||
_workDistance = 0.0;
|
||||
_angle = 0.0;
|
||||
|
||||
// 9. 重置地图与定位状态(关键修复)
|
||||
// 重置定位
|
||||
_currentLatLng = null;
|
||||
_currentWgsLatLng = null;
|
||||
_mapCenter = _getDefaultValidCenter(); // 仅用兜底坐标初始化地图中心
|
||||
_mapCenter = _getDefaultValidCenter();
|
||||
|
||||
// 10. 重置作业状态
|
||||
// 重置作业状态
|
||||
isDjMapShow = false;
|
||||
_workStatus = WorkStatus.idle;
|
||||
isStartWork = false;
|
||||
isStopWork = false;
|
||||
});
|
||||
_clearLocalData();
|
||||
|
||||
// 4. 重置轨迹管理器
|
||||
_clearLocalData();
|
||||
_traceManager.reset();
|
||||
|
||||
// 5. 重新加载作业记录(保持数据最新)
|
||||
// final userId = context.read<AppUserCubit>().state.user?.userId ?? "";
|
||||
// if (userId.isNotEmpty) {
|
||||
// await context.read<DevicesCubit>().loadWorkRecords(userId);
|
||||
// }
|
||||
|
||||
// 刷新成功提示
|
||||
if (mounted) {
|
||||
ToastUtils.showSuccess(context, '页面已刷新完成');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('页面已刷新完成'), backgroundColor: Colors.green, duration: Duration(seconds: 2)));
|
||||
_showPageToast(message: "页面已刷新完成", type: ToastType.success);
|
||||
//ToastUtils.showSuccess(context, '页面已刷新完成');
|
||||
}
|
||||
} catch (e) {
|
||||
// 错误处理
|
||||
if (mounted) {
|
||||
ToastUtils.showError(context, '刷新失败:${e.toString().substring(0, 50)}');
|
||||
//ScaffoldMessenger.of(
|
||||
// context,
|
||||
//).showSnackBar(SnackBar(content: Text('刷新失败:${e.toString().substring(0, 50)}'), backgroundColor: Colors.red, duration: Duration(seconds: 3)));
|
||||
_showPageToast(message: "刷新失败:${e.toString().substring(0, 50)}", type: ToastType.error);
|
||||
//ToastUtils.showError(context, '刷新失败:${e.toString().substring(0, 50)}');
|
||||
}
|
||||
} finally {
|
||||
// 标记刷新结束
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isRefreshing = false;
|
||||
@@ -955,7 +1008,8 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
// ========== 障碍物模式:完成当前障碍物绘制 ==========
|
||||
void _completeObstacle() {
|
||||
if (_currentObstaclePoints.length < 3) {
|
||||
ToastUtils.showError(context, '障碍物区域至少需要3个打点!');
|
||||
_showPageToast(message: "障碍物区域至少需要3个打点!", type: ToastType.error);
|
||||
//ToastUtils.showError(context, '障碍物区域至少需要3个打点!');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -972,15 +1026,16 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
_isObstacleEditing = false; // 退出编辑状态
|
||||
});
|
||||
_saveDataToLocal();
|
||||
|
||||
ToastUtils.showSuccess(context, '已添加第${_obstacleHoles.length}个障碍物区域');
|
||||
_showPageToast(message: "已添加第${_obstacleHoles.length}个障碍物区域", type: ToastType.success);
|
||||
//ToastUtils.showSuccess(context, '已添加第${_obstacleHoles.length}个障碍物区域');
|
||||
}
|
||||
|
||||
// ========== 核心方法:打点逻辑 ==========
|
||||
void _addMarkedPoint() {
|
||||
_traceManager.reset();
|
||||
if (_currentAreaMode == AreaMode.work && _isWorkAreaCompleted) {
|
||||
ToastUtils.showError(context, '作业区域已完成,无法继续添加打点!');
|
||||
_showPageToast(message: "作业区域已完成,无法继续添加打点!", type: ToastType.error);
|
||||
//ToastUtils.showError(context, '作业区域已完成,无法继续添加打点!');
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
@@ -996,7 +1051,8 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
}
|
||||
} else {
|
||||
if (_currentLatLng == null || !_isValidLatLng(_currentLatLng!.latitude, _currentLatLng!.longitude)) {
|
||||
ToastUtils.showError(context, '设备坐标无效,无法添加打点!');
|
||||
_showPageToast(message: "设备坐标无效,无法添加打点!", type: ToastType.error);
|
||||
//ToastUtils.showError(context, '设备坐标无效,无法添加打点!');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1030,6 +1086,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
_mapController.dispose();
|
||||
_pathPlanningSub?.cancel(); // 🔥 取消订阅
|
||||
_saveDataToLocal(); // 🔥 页面销毁时保存最终状态
|
||||
_cancelAllToast(); // 退出页面 → 关闭所有本页面的Toast
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -1140,6 +1197,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
|
||||
List<dynamic> outerList = [];
|
||||
final rawOuter = parsedJson['outer'];
|
||||
debugPrint("$rawOuter rawOuterrawOuterrawOuter");
|
||||
if (rawOuter is String) {
|
||||
try {
|
||||
outerList = jsonDecode(rawOuter) as List;
|
||||
@@ -1275,8 +1333,6 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
tracePoint = _traceManager.getTracePoint();
|
||||
gctracePoint = batchWgs84ToGcj02(tracePoint!);
|
||||
|
||||
debugPrint("$gctracePoint gctracePoint");
|
||||
|
||||
//_currentLatLng = gcjPoint; // ✅ 状态变量在setState内更新
|
||||
if (_isValidLatLng(gcjPoint.latitude, gcjPoint.longitude)) {
|
||||
_currentLatLng = gcjPoint;
|
||||
@@ -1569,7 +1625,8 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
_traceManager.reset();
|
||||
|
||||
if (startWorkList.isEmpty) {
|
||||
ToastUtils.showInfo(context, '作业列表为空,请重新选择路径');
|
||||
_showPageToast(message: "作业列表为空,请重新选择路径", type: ToastType.info);
|
||||
//ToastUtils.showInfo(context, '作业列表为空,请重新选择路径');
|
||||
return;
|
||||
}
|
||||
_traceManager.setMode(TPMode.NAVIGATION);
|
||||
@@ -1601,7 +1658,8 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
|
||||
///context.read<DevicesCubit>().updateAppState(AppState.routePlanning);
|
||||
// 可选:显示作业提示
|
||||
ToastUtils.showSuccess(context, '作业已开始');
|
||||
_showPageToast(message: "作业已开始", type: ToastType.success);
|
||||
//ToastUtils.showSuccess(context, '作业已开始');
|
||||
_saveDataToLocal();
|
||||
//ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('作业已开始'), backgroundColor: Colors.green));
|
||||
}
|
||||
@@ -1618,21 +1676,23 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
}
|
||||
|
||||
void _stopWork() async {
|
||||
setState(() {
|
||||
isStartWork = false; // 🔥 关键:停止作业标志
|
||||
_workStatus = WorkStatus.idle;
|
||||
_showHeadingWarn = false;
|
||||
_showControlModeWarn = false;
|
||||
isStopWork = true; //已经点击过停止
|
||||
isreceiveFirstCompletePoint = false;
|
||||
});
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
isStartWork = false; // 🔥 关键:停止作业标志
|
||||
_workStatus = WorkStatus.idle;
|
||||
_showHeadingWarn = false;
|
||||
_showControlModeWarn = false;
|
||||
isStopWork = true; //已经点击过停止
|
||||
isreceiveFirstCompletePoint = false;
|
||||
});
|
||||
}
|
||||
|
||||
//context.read<DevicesCubit>().updateAppState(AppState.none);
|
||||
await context.read<DevicesCubit>().stopRoutePlanning();
|
||||
_traceManager.reset();
|
||||
_saveDataToLocal(); // 🔥 保存暂停状态
|
||||
|
||||
ToastUtils.showError(context, '作业已停止');
|
||||
_showPageToast(message: "作业已停止", type: ToastType.error);
|
||||
_traceManager.setMode(TPMode.LOCATION);
|
||||
}
|
||||
|
||||
/// 继续作业
|
||||
@@ -1975,68 +2035,57 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
|
||||
if (_currentWorkMode == WorkMode.custom) {
|
||||
setState(() {
|
||||
_saveBoxOpen = true; // 显示保存按钮
|
||||
_isWorkAreaCompleted = true; // 标记为完成,允许保存
|
||||
gcjPathPoints = List.from(_markedPoints); // outer直接使用打点坐标
|
||||
_saveBoxOpen = true;
|
||||
_isWorkAreaCompleted = true;
|
||||
gcjPathPoints = List.from(_markedPoints);
|
||||
gcjOuterPoints = List.from(_markedPoints);
|
||||
typedPathList = []; // 路径列表置空
|
||||
typedPathList = [];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 校验必要条件
|
||||
if (_currentAreaMode == AreaMode.work && _markedPoints.isEmpty) {
|
||||
if (showTips) {
|
||||
ToastUtils.showError(context, '请先添加作业区域打点!');
|
||||
_showPageToast(message: '请先添加作业区域打点!', type: ToastType.error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (_currentAreaMode == AreaMode.work && _markedPoints.length < 3) {
|
||||
if (showTips) {
|
||||
ToastUtils.showError(context, '作业区域至少需要3个打点才能生成路径!');
|
||||
_showPageToast(message: '作业区域至少需要3个打点才能生成路径!', type: ToastType.error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (_currentWorkMode == null) {
|
||||
if (showTips) {
|
||||
ToastUtils.showError(context, '请先选择作业模式!');
|
||||
_showPageToast(message: '请先选择作业模式!', type: ToastType.error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 2. 转换页面数据为 generatePath 所需的参数格式
|
||||
// 2.1 参考点(区分Robot/Point模式)
|
||||
LatLng firstPointWgs; // 最终传给接口的WGS84格式参考点
|
||||
LatLng firstPointWgs;
|
||||
if (_currentRobotMode == RobotMode.robot && _robotModeWgsPoints.isNotEmpty) {
|
||||
// Robot模式:直接使用原始WGS84坐标(无需转换)
|
||||
firstPointWgs = _robotModeWgsPoints.first;
|
||||
} else if (_currentRobotMode == RobotMode.point && _markedPoints.isNotEmpty) {
|
||||
// Point模式:先取十字准星的GCJ02坐标 → 转换为WGS84
|
||||
LatLng firstPointGcj = _markedPoints.first;
|
||||
firstPointWgs = gcj02ToWgs84(firstPointGcj.latitude, firstPointGcj.longitude);
|
||||
} else {
|
||||
if (showTips) {
|
||||
ToastUtils.showError(context, '参考点坐标为空,请先添加作业区域打点!');
|
||||
_showPageToast(message: '参考点坐标为空,请先添加作业区域打点!', type: ToastType.error);
|
||||
}
|
||||
return; // 终止方法执行,避免后续错误
|
||||
return;
|
||||
}
|
||||
|
||||
// 参考点使用转换后的WGS84坐标
|
||||
final referencePoint = work_area_model.ReferencePoint(lat: firstPointWgs.latitude, lon: firstPointWgs.longitude);
|
||||
|
||||
// 2.2 航向角
|
||||
final heading = _angle == -1 ? -1 : _angle.toInt();
|
||||
|
||||
// 2.3 外边界(作业区域)- 核心区分Robot/Point模式
|
||||
List<work_area_model.Position> outerPositions = [];
|
||||
if (_currentRobotMode == RobotMode.robot && _robotModeWgsPoints.isNotEmpty) {
|
||||
// Robot模式:直接使用原始WGS84坐标,跳过GCJ02→WGS84转换
|
||||
outerPositions = _robotModeWgsPoints.map((latLng) {
|
||||
return work_area_model.Position(lat: latLng.latitude, lon: latLng.longitude);
|
||||
}).toList();
|
||||
} else if (_currentRobotMode == RobotMode.point && _markedPoints.isNotEmpty) {
|
||||
// Point模式:十字准星的GCJ02坐标 → 转换为WGS84
|
||||
outerPositions = _markedPoints.map((latLng) {
|
||||
final wgs84Point = gcj02ToWgs84(latLng.latitude, latLng.longitude);
|
||||
return work_area_model.Position(lat: wgs84Point.latitude, lon: wgs84Point.longitude);
|
||||
@@ -2050,17 +2099,14 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
}).toList();
|
||||
|
||||
final outerBoundary = work_area_model.OuterBoundary(position: outerPositions, sideWidth: _workDistance);
|
||||
|
||||
work_area_model.HoleBoundary? holeBoundary;
|
||||
|
||||
if (_obstacleHoles.isNotEmpty) {
|
||||
// 1. 构造二维 Position 数组
|
||||
List<List<work_area_model.Position>> positionList = [];
|
||||
|
||||
if (_currentRobotMode == RobotMode.robot && _robotModeObsWgsPoints.isNotEmpty) {
|
||||
for (var holePoints in _obstacleWgsHoles) {
|
||||
List<work_area_model.Position> innerPositionList = [];
|
||||
|
||||
innerPositionList = holePoints.map((latLng) {
|
||||
return work_area_model.Position(lat: latLng.latitude, lon: latLng.longitude);
|
||||
}).toList();
|
||||
@@ -2069,8 +2115,6 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
} else if (_currentRobotMode == RobotMode.point && _obstacleHoles.isNotEmpty) {
|
||||
for (var holePoints in _obstacleHoles) {
|
||||
List<work_area_model.Position> innerPositionList = [];
|
||||
|
||||
// Point模式:GCJ02→WGS84转换
|
||||
innerPositionList = holePoints.map((latLng) {
|
||||
final wgs84Point = gcj02ToWgs84(latLng.latitude, latLng.longitude);
|
||||
return work_area_model.Position(lat: wgs84Point.latitude, lon: wgs84Point.longitude);
|
||||
@@ -2079,70 +2123,39 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
}
|
||||
}
|
||||
|
||||
//for (var holePoints in _obstacleHoles) {
|
||||
// List<work_area_model.Position> innerPositionList = [];
|
||||
|
||||
// if (_currentRobotMode == RobotMode.robot && _robotModeObsWgsPoints.isNotEmpty) {
|
||||
// // Robot模式:使用障碍物原始WGS84坐标
|
||||
// innerPositionList = holePoints.map((latLng) {
|
||||
// return work_area_model.Position(lat: latLng.latitude, lon: latLng.longitude);
|
||||
// }).toList();
|
||||
// } else {
|
||||
// // Point模式:GCJ02→WGS84转换
|
||||
// innerPositionList = holePoints.map((latLng) {
|
||||
// final wgs84Point = gcj02ToWgs84(latLng.latitude, latLng.longitude);
|
||||
// return work_area_model.Position(lat: wgs84Point.latitude, lon: wgs84Point.longitude);
|
||||
// }).toList();
|
||||
// }
|
||||
// positionList.add(innerPositionList);
|
||||
//}
|
||||
|
||||
// 2. 创建 HoleBoundary 对象(无外层 Map)
|
||||
holeBoundary = work_area_model.HoleBoundary(position: positionList, sideWidth: 0.0);
|
||||
}
|
||||
|
||||
// 🔥 第二步:构造符合方法参数要求的 Map<String, HoleBoundary>
|
||||
// 用一个临时 Map 来满足类型要求,后续在 Cubit 中取值即可
|
||||
Map<String, work_area_model.HoleBoundary> holes = {};
|
||||
if (holeBoundary != null) {
|
||||
holes = {'tempKey': holeBoundary}; // 键名任意,仅为满足类型要求
|
||||
holes = {'tempKey': holeBoundary};
|
||||
}
|
||||
final workType = _currentWorkMode == WorkMode.bow ? 0 : 2;
|
||||
print('==================================================');
|
||||
print('✅ generatePath 完整参数结构:');
|
||||
print('reference: ${formatPrettyJson(referencePoint)}');
|
||||
print('heading: $heading');
|
||||
print('outer: ${formatPrettyJson(outerBoundary)}');
|
||||
print('holes: ${formatPrettyJson(holes)}');
|
||||
print('workType: $workType');
|
||||
print('==================================================');
|
||||
// 3. 调用 Cubit 的 generatePath 方法(传入holes参数)
|
||||
|
||||
await context.read<DevicesCubit>().generatePath(
|
||||
reference: referencePoint,
|
||||
heading: heading,
|
||||
outer: outerBoundary,
|
||||
holes: holes.isNotEmpty ? holes : {}, // 无障碍物时传空对象
|
||||
holes: holes.isNotEmpty ? holes : {},
|
||||
workType: workType,
|
||||
);
|
||||
|
||||
// 4. 处理生成结果(原有逻辑不变)
|
||||
final cubitState = context.read<DevicesCubit>().state;
|
||||
|
||||
if (cubitState.errorMessage != null) {
|
||||
if (showTips) {
|
||||
ToastUtils.showError(context, '路径生成失败:${cubitState.errorMessage}');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('路径生成失败:${cubitState.errorMessage}'), backgroundColor: Colors.red));
|
||||
_showPageToast(message: '路径生成失败:${cubitState.errorMessage}', type: ToastType.error);
|
||||
}
|
||||
} else if (cubitState.generatedPath != null) {
|
||||
if (showTips) {
|
||||
ToastUtils.showSuccess(context, '路径生成成功!');
|
||||
_showPageToast(message: '路径生成成功!', type: ToastType.success);
|
||||
}
|
||||
if (cubitState.generatedPath is List) {
|
||||
setState(() {
|
||||
_isWorkAreaCompleted = true;
|
||||
_saveBoxOpen = true;
|
||||
_currentObstaclePoints.clear(); // 清空当前绘制的障碍物点
|
||||
_robotModeObsWgsPoints.clear(); // 清空Robot模式下的障碍物WGS84坐标
|
||||
_currentObstaclePoints.clear();
|
||||
_robotModeObsWgsPoints.clear();
|
||||
final pathList = cubitState.generatedPath as List;
|
||||
typedPathList = pathList.whereType<work_area_model.DeviceAddPathPointModel>().toList();
|
||||
gcjPathPoints = typedPathList.map((point) {
|
||||
@@ -2151,8 +2164,6 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
final gcjPoint = wgs84ToGcj02(wgs84Lat, wgs84Lon);
|
||||
return LatLng(gcjPoint.latitude, gcjPoint.longitude);
|
||||
}).toList();
|
||||
// 外边界保持原有逻辑
|
||||
//gcjOuterPoints = List.from(_markedPoints);
|
||||
});
|
||||
_saveDataToLocal();
|
||||
moveMapToPointsCenter(gcjPathPoints);
|
||||
@@ -2161,11 +2172,63 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
} catch (e) {
|
||||
debugPrint('路径生成异常:$e');
|
||||
if (showTips) {
|
||||
ToastUtils.showError(context, '路径生成异常:${e.toString().substring(0, 50)}');
|
||||
_showPageToast(message: '路径生成异常:${e.toString().substring(0, 50)}', type: ToastType.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _cancelAllToast() {
|
||||
for (final entry in _toastEntries) {
|
||||
if (entry.mounted) {
|
||||
entry.remove();
|
||||
}
|
||||
}
|
||||
_toastEntries.clear();
|
||||
}
|
||||
|
||||
// 只在当前页面显示安全 Toast,退出自动消失
|
||||
void _showPageToast({required String message, required ToastType type}) {
|
||||
_cancelAllToast();
|
||||
|
||||
OverlayEntry entry = OverlayEntry(
|
||||
builder: (context) => SafeArea(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 30),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
decoration: BoxDecoration(color: _getToastColor(type), borderRadius: BorderRadius.circular(8)),
|
||||
child: Text(message, style: const TextStyle(color: Colors.white, fontSize: 14)),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
_toastEntries.add(entry);
|
||||
Overlay.of(context)?.insert(entry);
|
||||
|
||||
// 2秒后自动关闭
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
if (entry.mounted) entry.remove();
|
||||
_toastEntries.remove(entry);
|
||||
});
|
||||
}
|
||||
|
||||
Color _getToastColor(ToastType type) {
|
||||
switch (type) {
|
||||
case ToastType.success:
|
||||
return Colors.green;
|
||||
case ToastType.error:
|
||||
return Colors.red;
|
||||
case ToastType.warn:
|
||||
return Colors.orange;
|
||||
case ToastType.info:
|
||||
return Colors.blue;
|
||||
case ToastType.loading:
|
||||
return Colors.black87;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenHeight = MediaQuery.of(context).size.height;
|
||||
@@ -2208,11 +2271,14 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
//有停止信号
|
||||
if (isFinishWork) {
|
||||
_workStatus = WorkStatus.idle;
|
||||
ToastUtils.showError(context, '作业已停止');
|
||||
|
||||
_showPageToast(message: "作业已停止", type: ToastType.error);
|
||||
//ToastUtils.showError(context, '作业已停止');
|
||||
// 👇 延迟 1 秒钟再执行 reset(不会阻塞UI,安全)
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
if (mounted) {
|
||||
_traceManager.reset();
|
||||
_traceManager.setMode(TPMode.LOCATION);
|
||||
}
|
||||
});
|
||||
isStopWork = true;
|
||||
|
||||
Reference in New Issue
Block a user