import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:qhd_prevention/customWidget/BaiDuMap/BaiduMapWebView.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/services/location_service.dart'; import 'package:qhd_prevention/tools/tools.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'package:geolocator/geolocator.dart'; class MapPage extends StatefulWidget { final String gson; const MapPage({super.key, required this.gson}); @override State createState() => _MapPageState(); } class _MapPageState extends State { late final WebViewController _controller; bool _isLoading = true; String? _errorMessage; double? _longitude; double? _latitude; List _gsonList = []; late Map mapData = {}; @override void initState() { super.initState(); _initLocation(); } /// 获取定位(并初始化 WebView 控制器) Future _initLocation() async { setState(() { _isLoading = true; _errorMessage = null; }); try { final LocationResult loc = await LocationService.getCurrentLocation( timeout: const Duration(seconds: 10), ); // 解析 gson try { final parsed = jsonDecode(widget.gson); if (parsed is List) { _gsonList = parsed; } else { _gsonList = []; } } catch (e) { debugPrint('解析 gson 失败: $e'); _gsonList = []; } if (!mounted) return; setState(() { _longitude = loc.longitudeAsDouble; _latitude = loc.latitudeAsDouble; }); // 初始化 WebViewController 并加载本地页面 _controller = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) // 注册 JS 通道 'JS' —— 对应 HTML 中的 window.JS.postMessage(...) ..addJavaScriptChannel('JS', onMessageReceived: (dynamic message) { // message 是动态对象,不在签名中引用具体类型以避免 "Undefined class" 问题 String payload; try { payload = message.message ?? message.toString(); } catch (e) { payload = message.toString(); } _onJsMessage(payload); }) // 也保留一个备用通道 'Flutter' ..addJavaScriptChannel('Flutter', onMessageReceived: (dynamic message) { String payload; try { payload = message.message ?? message.toString(); } catch (e) { payload = message.toString(); } _onJsMessage(payload); }) ..setNavigationDelegate( NavigationDelegate( onPageFinished: (String url) async { debugPrint('网页加载完成: $url'); await _injectLocationParams(); }, onWebResourceError: (err) { debugPrint('Web resource error: ${err.description}'); }, ), ); // 加载本地 assets 中的 HTML // await _controller.loadFlutterAsset('assets/map/test_baidu_map.html'); await _controller.loadRequest(Uri.parse('http://47.92.102.56:7811/file/fluteightmap/index.html')); setState(() { _isLoading = false; }); } catch (e, st) { debugPrint('获取位置或初始化失败: $e\n$st'); if (!mounted) return; setState(() { _errorMessage = '获取位置失败: ${e.toString()}'; _isLoading = false; }); } } /// 注入参数并调用页面初始化函数 window.initWithData(...) Future _injectLocationParams() async { if (_longitude == null || _latitude == null) { debugPrint('位置尚未准备好,跳过注入'); return; } final params = { 'longitude': _longitude, 'latitude': _latitude, 'GSON': _gsonList, 't': DateTime.now().millisecondsSinceEpoch, }; final jsonParams = jsonEncode(params); try { await _controller.runJavaScript(''' (function(){ try { if (typeof window.initWithData === 'function') { window.initWithData($jsonParams); } else if (typeof window.initMap === 'function') { window.initMap($jsonParams); } else { console.error('initWithData / initMap function not found'); } } catch(e) { console.error('call initWithData error', e); } })(); '''); debugPrint('已注入地图初始化参数'); } catch (e) { debugPrint('注入位置参数失败: $e'); } } /// 处理来自 Web 的消息(字符串或 JSON) void _onJsMessage(String message) { debugPrint('收到来自 Web 的消息: $message'); if (message.isEmpty) return; try { Map data = jsonDecode(message); if (FormUtils.hasValue(data, 'ok') && data['ok'] == true) { }else{ if (FormUtils.hasValue(data, 'type') && data['type'] == 'converted') { setState(() { mapData = data; }); }else{ ToastUtil.showNormal(context, '当前选择点位不在区域中'); setState(() { mapData = {}; }); } } } catch (_) { setState(() { mapData = {}; }); ToastUtil.showNormal(context, '当前选择点位不在区域中'); } } @override Widget build(BuildContext context) { return Scaffold( appBar: MyAppbar(title: '地图选择', actions: [ if (mapData.isNotEmpty) TextButton(onPressed: (){ Navigator.of(context).pop((mapData)); }, child: Text('确定', style: TextStyle(color: Colors.white, fontSize: 17),)) ],), body: SafeArea( child: BaiduMapWebView( controller: _isLoading || _errorMessage != null ? null : _controller, isLoading: _isLoading, errorMessage: _errorMessage, onRetry: _initLocation, ),), ); } }