// import 'dart:async'; // import 'package:EasyDartModule/EasyDartModule.dart'; // import 'package:ef/ef.dart'; // import 'package:flutter/material.dart'; // import 'package:geocoding/geocoding.dart'; // import 'package:geolocator/geolocator.dart'; // import 'package:json_annotation/json_annotation.dart'; // import 'package:path/path.dart'; // import 'package:vbvs_app/common/color/ServiceConstant.dart'; // import 'package:vbvs_app/common/color/appConstants.dart'; // import 'package:vbvs_app/common/util/CommonVariables.dart'; // import 'package:vbvs_app/common/util/MyUtils.dart'; // import 'package:vbvs_app/common/util/requestWithLog.dart'; // import 'package:vbvs_app/controller/setting/language/language_controller.dart'; // import 'package:vbvs_app/controller/user_info_controller.dart'; // import 'package:vbvs_app/enum/APPPackageType.dart'; // import 'package:vbvs_app/pages/common/selectDialog.dart'; // import 'package:weather/weather.dart'; // part 'weather_controller.g.dart'; // @JsonSerializable() // class WeatherModel { // double? longitude; // 经度 // double? latitude; // 纬度 // String? weather_info = ''; // 天气 // int? current_temperature; // 温度 // int? min_temperature; // 最低温度 // int? max_temperature; // 最高温度 // String? wind_direction; // 风向 // int? wind_speed; // 风速等级 // String? cityName; // 城市名 // String? weatherIcon; // 天气图标 // String? weatherIconurl; // 天气图标url // WeatherModel(); // static WeatherModel fromJson(Map json) => // _$WeatherModelFromJson(json); // Map toJson() => _$WeatherModelToJson(this); // } // class WeatherModelController extends GetControllerEx { // LanguageController languageController = Get.find(); // WeatherModelController() { // attr = GetModel(WeatherModel()).obs; // weatherFactory = WeatherFactory(CommonVariables.weather_apiKey, // language: Language.CHINESE_SIMPLIFIED); // } // Timer? _weatherTimer; // Timer? _locationTimer; // late WeatherFactory weatherFactory; // @override // Future onInit() async { // super.onInit(); // try { // await getCurrentLocation(); // _weatherTimer = Timer.periodic(Duration(minutes: 10), (timer) { // getCurrentWeather(); // 每 60 秒更新一次天气 // }); // _locationTimer = Timer.periodic(Duration(minutes: 10), (timer) { // getCurrentLocation(); // 每 10 分钟更新一次位置 // }); // } catch (e) { // ef.log("[天气和定位请求失败]"); // } // } // @override // void onClose() { // _weatherTimer?.cancel(); // 取消天气更新定时器 // _locationTimer?.cancel(); // 取消位置更新定时器 // super.onClose(); // } // // 获取当前位置并存储到 model // Future getCurrentLocation() async { // try { // UserInfoController userInfoController = Get.find(); // if (userInfoController.model.login == null || // userInfoController.model.login != 1) { // return; // } // Position position = await determinePosition(); // if (position == null) { // throw Exception("获取位置失败"); // } // String? language = "zh_CN"; // if (AppConstants().ent_type == APPPackageType.MHT.code) { // if (mhLanguageController.selectLanguage != null) { // language = mhLanguageController.selectLanguage.value!.language_code; // } // } else { // if (languageController.selectLanguage != null) { // language = languageController.selectLanguage.value!.language_code; // } // } // List placemarks = []; // // placemarks = await placemarkFromCoordinates(position.latitude, position.longitude, // // localeIdentifier: language); // placemarks = await placemarkFromCoordinates( // position.latitude, // position.longitude, // ); // if (placemarks.isNotEmpty) { // // model.cityName = placemarks[0].locality ?? "未知数据".tr; // model.latitude = position.latitude; // model.longitude = position.longitude; // } // // 调用获取天气方法 // // getCurrentWeather(); // } catch (e) { // print(e); // EasyDartModule.logger.error("获取位置失败: $e"); // } // } // // 获取当前位置 // // Future determinePosition() async { // // bool serviceEnabled; // // LocationPermission permission; // // serviceEnabled = await Geolocator.isLocationServiceEnabled(); // // if (!serviceEnabled) { // // return Future.error('位置服务未启用'); // // } // // try { // // showPermissionInfoDialog( // // Get.context!, CommonVariables().locationpermissionInfo); // // } catch (e) { // // ef.log("$e"); // // } // // try { // // // 2️⃣ 检查权限(系统弹窗)—— 此时你的提示框仍然显示 // // permission = await Geolocator.checkPermission(); // // if (permission == LocationPermission.denied) { // // permission = await Geolocator.requestPermission(); // // } // // } finally { // // // 3️⃣ 无论如何都关闭你的提示弹窗 // // Navigator.of(Get.context!, rootNavigator: true).pop(); // // } // // if (permission == LocationPermission.denied) { // // return Future.error('位置权限被拒绝'); // // } // // if (permission == LocationPermission.deniedForever) { // // return Future.error('位置权限被永久拒绝'); // // } // // return await Geolocator.getCurrentPosition( // // forceAndroidLocationManager: true, // // locationSettings: const LocationSettings( // // accuracy: LocationAccuracy.best, // // distanceFilter: 1000, // 设置最小距离过滤 // // timeLimit: Duration(seconds: 10), // 设置获取位置的最大等待时间 // // ), // // ); // // } // Future determinePosition({int retryCount = 1}) async { // bool serviceEnabled; // LocationPermission permission; // int attempt = 0; // bool dialogShown = false; // // 检查定位服务是否启用 // serviceEnabled = await Geolocator.isLocationServiceEnabled(); // if (!serviceEnabled) { // return Future.error('位置服务未启用'); // } // try { // // 弹出自定义提示 // // 检查和请求位置权限 // permission = await Geolocator.checkPermission(); // if (permission == LocationPermission.denied) { // showPermissionInfoDialog( // Get.context!, CommonVariables().locationpermissionInfo); // dialogShown = true; // await Future.delayed(const Duration(milliseconds: 300)); // // 系统权限弹窗 // permission = await Geolocator.requestPermission(); // } // } catch (e) { // ef.log("申请位置权限出错: $e"); // rethrow; // } finally { // if (dialogShown) { // if (Get.isDialogOpen ?? false) { // Get.back(); // 关闭弹窗 // } // } // } // // 如果权限被拒绝,直接返回错误 // if (permission == LocationPermission.denied) { // return Future.error('位置权限被拒绝'); // } // // 如果权限被永久拒绝,直接返回错误 // if (permission == LocationPermission.deniedForever) { // return Future.error('位置权限被永久拒绝'); // } // // 开始获取位置,最多重试 retryCount 次 // while (attempt < retryCount) { // attempt++; // try { // // 设置定位精度 // LocationAccuracy accuracy = attempt == 1 // ? LocationAccuracy.medium // 初次尝试用中等精度 // : LocationAccuracy.best; // 如果第一次失败,尝试高精度定位 // return await Geolocator.getCurrentPosition( // forceAndroidLocationManager: true, // locationSettings: LocationSettings( // accuracy: accuracy, // distanceFilter: 1000, // timeLimit: Duration(seconds: 10), // ), // ); // } catch (e) { // if (attempt >= retryCount) { // return Future.error('获取位置失败: $e'); // } // await Future.delayed(Duration(seconds: 2)); // 重试前等待 // } // } // return Future.error('获取位置失败,已重试 $retryCount 次'); // } // // 获取天气信息 // // Future getCurrentWeather() async { // // await getCurrentLocation(); // // if (model.latitude == null || model.longitude == null) { // // EasyDartModule.logger.error("获取天气失败:位置数据获取失败"); // // return; // 如果位置数据没有获取到,则不更新天气 // // } // // try { // // weatherFactory.language = Language.CHINESE_SIMPLIFIED; // // String? language = "zh_CN"; // // if (AppConstants().ent_type == APPPackageType.MHT.code) { // // if (mhLanguageController.selectLanguage != null) { // // language = mhLanguageController.selectLanguage.value!.language_code; // // } // // } else { // // if (languageController.selectLanguage != null) { // // language = languageController.selectLanguage.value!.language_code; // // } // // } // // if (language == "zh_CN") { // // weatherFactory.language = Language.CHINESE_SIMPLIFIED; // // } else { // // weatherFactory.language = Language.ENGLISH; // // } // // // Weather weather = await weatherFactory.currentWeatherByLocation( // // // model.latitude!, model.longitude!); // // String location = "${model.longitude},${model.latitude}"; // // String serviceAddress = ServiceConstant.service_address; // // String serviceName = ServiceConstant.server_service; // // String serviceApi = ServiceConstant.weather_url; // // String queryUrl = // // "${serviceAddress}${serviceName}${serviceApi}?location=$location"; // // await requestWithLog( // // logTitle: "获取天气信息", // // method: MyHttpMethod.get, // // queryUrl: queryUrl, // // onSuccess: (res) { // // print(res.data); // // model.weather_info = res.data["info"]; // // model.current_temperature = int.parse(res.data["temp"]); // // if (res.data['icon'] != null) { // // model.weatherIconurl = "${res.data['icon']}"; // // } // // model.cityName = res.data["city"]; // // }, // // onFailure: (res) { // // print(res.data); // // }); // // updateAll(); // 更新 UI // // } catch (e) { // // EasyDartModule.logger.error("获取天气失败: $e"); // // print('获取天气失败: $e'); // // } // // } // Future getCurrentWeather({int retryCount = 1}) async { // int attempt = 0; // bool success = false; // while (attempt < retryCount && success == false) { // attempt++; // try { // // 先尝试获取定位 // await getCurrentLocation(); // if (model.latitude == null || model.longitude == null) { // EasyDartModule.logger.error("获取天气失败: 位置数据获取失败 (第$attempt次)"); // if (attempt >= retryCount) return; // 重试到上限退出 // await Future.delayed(Duration(seconds: 2)); // 延时再试 // continue; // } // // 设置语言 // String? language = "zh_CN"; // if (AppConstants().ent_type == APPPackageType.MHT.code) { // if (mhLanguageController.selectLanguage != null) { // language = mhLanguageController.selectLanguage.value!.language_code; // } // } else { // if (languageController.selectLanguage != null) { // language = languageController.selectLanguage.value!.language_code; // } // } // weatherFactory.language = (language == "zh_CN") // ? Language.CHINESE_SIMPLIFIED // : Language.ENGLISH; // // 拼接天气请求地址 // String location = "${model.longitude},${model.latitude}"; // String serviceAddress = ServiceConstant.service_address; // String serviceName = ServiceConstant.server_service; // String serviceApi = ServiceConstant.weather_url; // String queryUrl = // "$serviceAddress$serviceName$serviceApi?location=$location"; // await requestWithLog( // logTitle: "获取天气信息 (第$attempt次)", // method: MyHttpMethod.get, // queryUrl: queryUrl, // onSuccess: (res) { // try { // print(res.data); // model.weather_info = res.data["info"]; // model.current_temperature = int.parse(res.data["temp"]); // if (res.data['icon'] != null) { // model.weatherIconurl = "${res.data['icon']}"; // } // model.cityName = res.data["city"]; // success = true; // } catch (e) { // EasyDartModule.logger.error("天气数据解析失败: $e"); // } // }, // onFailure: (res) { // EasyDartModule.logger.error("获取天气接口失败: ${res.data}"); // }, // ); // if (success) { // updateAll(); // 更新 UI // return; // ✅ 成功了直接返回 // } // } catch (e) { // EasyDartModule.logger.error("获取天气异常 (第$attempt次): $e"); // } // // 如果还没成功,延迟后重试 // if (attempt < retryCount) { // await Future.delayed(Duration(seconds: 2)); // } // } // EasyDartModule.logger.error("获取天气失败: 已重试 $retryCount 次仍然失败"); // } // // 获取 5 天天气预报 // Future> getWeatherForecast( // double latitude, double longitude) async { // try { // return await weatherFactory.fiveDayForecastByLocation( // latitude, longitude); // } catch (e) { // print('获取天气预报失败: $e'); // rethrow; // } // } // } import 'dart:async'; import 'package:EasyDartModule/EasyDartModule.dart'; import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:geocoding/geocoding.dart'; import 'package:geolocator/geolocator.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:path/path.dart'; import 'package:vbvs_app/common/color/ServiceConstant.dart'; import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/util/CommonVariables.dart'; import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/controller/setting/language/language_controller.dart'; import 'package:vbvs_app/controller/user_info_controller.dart'; import 'package:vbvs_app/enum/APPPackageType.dart'; import 'package:vbvs_app/pages/common/selectDialog.dart'; import 'package:weather/weather.dart'; part 'weather_controller.g.dart'; @JsonSerializable() class WeatherModel { double? longitude; // 经度 double? latitude; // 纬度 String? weather_info = ''; // 天气 int? current_temperature; // 温度 int? min_temperature; // 最低温度 int? max_temperature; // 最高温度 String? wind_direction; // 风向 int? wind_speed; // 风速等级 String? cityName; // 城市名 String? weatherIcon; // 天气图标 String? weatherIconurl; // 天气图标url WeatherModel(); static WeatherModel fromJson(Map json) => _$WeatherModelFromJson(json); Map toJson() => _$WeatherModelToJson(this); } class WeatherModelController extends GetControllerEx { LanguageController languageController = Get.find(); WeatherModelController() { attr = GetModel(WeatherModel()).obs; weatherFactory = WeatherFactory(CommonVariables.weather_apiKey, language: Language.CHINESE_SIMPLIFIED); } Timer? _weatherTimer; Timer? _locationTimer; // 添加状态变量来跟踪权限请求状态 bool _isRequestingPermission = false; bool _hasShownPermissionDialog = false; late WeatherFactory weatherFactory; @override Future onInit() async { super.onInit(); //去掉天气 // try { // await getCurrentLocation(); // _weatherTimer = Timer.periodic(Duration(minutes: 10), (timer) { // getCurrentWeather(); // 每 60 秒更新一次天气 // }); // _locationTimer = Timer.periodic(Duration(minutes: 10), (timer) { // getCurrentLocation(); // 每 10 分钟更新一次位置 // }); // } catch (e) { // ef.log("[天气和定位请求失败]"); // } } @override void onClose() { _weatherTimer?.cancel(); // 取消天气更新定时器 _locationTimer?.cancel(); // 取消位置更新定时器 super.onClose(); } // 获取当前位置并存储到 model Future getCurrentLocation() async { try { UserInfoController userInfoController = Get.find(); if (userInfoController.model.login == null || userInfoController.model.login != 1) { return; } Position position = await determinePosition(); if (position == null) { throw Exception("获取位置失败"); } String? language = "zh_CN"; if (AppConstants().ent_type == APPPackageType.MHT.code) { if (mhLanguageController.selectLanguage != null) { language = mhLanguageController.selectLanguage.value!.language_code; } } else { if (languageController.selectLanguage != null) { language = languageController.selectLanguage.value!.language_code; } } List placemarks = []; // placemarks = await placemarkFromCoordinates(position.latitude, position.longitude, // localeIdentifier: language); placemarks = await placemarkFromCoordinates( position.latitude, position.longitude, ); if (placemarks.isNotEmpty) { // model.cityName = placemarks[0].locality ?? "未知数据".tr; model.latitude = position.latitude; model.longitude = position.longitude; } // 调用获取天气方法 // getCurrentWeather(); } catch (e) { print(e); EasyDartModule.logger.error("获取位置失败: $e"); } } // 获取当前位置 Future determinePosition({int retryCount = 1}) async { bool serviceEnabled; LocationPermission permission; int attempt = 0; bool dialogShown = false; Completer? dialogCompleter; // 检查定位服务是否启用 serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { return Future.error('位置服务未启用'); } // 检查当前权限状态 permission = await Geolocator.checkPermission(); // 如果权限已经被授予,直接获取位置 if (permission == LocationPermission.always || permission == LocationPermission.whileInUse) { return await _getPositionWithRetry(retryCount); } // 如果权限被永久拒绝,直接返回错误 if (permission == LocationPermission.deniedForever) { return Future.error('位置权限被永久拒绝'); } // 如果正在请求权限,避免重复请求 if (_isRequestingPermission) { return Future.error('权限请求正在进行中'); } // 权限被拒绝或未请求过,需要请求权限 try { _isRequestingPermission = true; if (!_hasShownPermissionDialog) { showPermissionInfoDialog( Get.context!, CommonVariables().locationpermissionInfo, ); _hasShownPermissionDialog = true; } // 等待系统弹窗结果(期间自定义弹窗仍显示在屏幕上) permission = await Geolocator.requestPermission(); // 系统弹窗关闭后继续执行,关闭自定义弹窗 if (_hasShownPermissionDialog) { Get.back(); } } catch (e) { ef.log("申请位置权限出错: $e"); rethrow; } finally { _isRequestingPermission = false; } // 检查请求后的权限状态 if (permission == LocationPermission.denied) { return Future.error('位置权限被拒绝'); } if (permission == LocationPermission.deniedForever) { return Future.error('位置权限被永久拒绝'); } // 权限已授予,获取位置 return await _getPositionWithRetry(retryCount); } // 提取获取位置的重复代码到单独的方法 Future _getPositionWithRetry(int retryCount) async { int attempt = 0; while (attempt < retryCount) { attempt++; try { // 设置定位精度 LocationAccuracy accuracy = attempt == 1 ? LocationAccuracy.medium // 初次尝试用中等精度 : LocationAccuracy.best; // 如果第一次失败,尝试高精度定位 return await Geolocator.getCurrentPosition( forceAndroidLocationManager: true, locationSettings: LocationSettings( accuracy: accuracy, distanceFilter: 1000, timeLimit: Duration(seconds: 10), ), ); } catch (e) { if (attempt >= retryCount) { return Future.error('获取位置失败: $e'); } await Future.delayed(Duration(seconds: 2)); // 重试前等待 } } return Future.error('获取位置失败,已重试 $retryCount 次'); } // 获取天气信息 Future getCurrentWeather({int retryCount = 1}) async { int attempt = 0; bool success = false; while (attempt < retryCount && success == false) { attempt++; try { // 先尝试获取定位 await getCurrentLocation(); if (model.latitude == null || model.longitude == null) { EasyDartModule.logger.error("获取天气失败: 位置数据获取失败 (第$attempt次)"); if (attempt >= retryCount) return; // 重试到上限退出 await Future.delayed(Duration(seconds: 2)); // 延时再试 continue; } // 设置语言 String? language = "zh_CN"; if (AppConstants().ent_type == APPPackageType.MHT.code) { if (mhLanguageController.selectLanguage != null) { language = mhLanguageController.selectLanguage.value!.language_code; } } else { if (languageController.selectLanguage != null) { language = languageController.selectLanguage.value!.language_code; } } weatherFactory.language = (language == "zh_CN") ? Language.CHINESE_SIMPLIFIED : Language.ENGLISH; // 拼接天气请求地址 String location = "${model.longitude},${model.latitude}"; String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.weather_url; String queryUrl = "$serviceAddress$serviceName$serviceApi?location=$location"; await requestWithLog( logTitle: "获取天气信息 (第$attempt次)", method: MyHttpMethod.get, queryUrl: queryUrl, onSuccess: (res) { try { print(res.data); model.weather_info = res.data["info"]; model.current_temperature = int.parse(res.data["temp"]); if (res.data['icon'] != null) { model.weatherIconurl = "${res.data['icon']}"; } model.cityName = res.data["city"]; success = true; } catch (e) { EasyDartModule.logger.error("天气数据解析失败: $e"); } }, onFailure: (res) { EasyDartModule.logger.error("获取天气接口失败: ${res.data}"); }, ); if (success) { updateAll(); // 更新 UI return; // ✅ 成功了直接返回 } } catch (e) { EasyDartModule.logger.error("获取天气异常 (第$attempt次): $e"); } // 如果还没成功,延迟后重试 if (attempt < retryCount) { await Future.delayed(Duration(seconds: 2)); } } EasyDartModule.logger.error("获取天气失败: 已重试 $retryCount 次仍然失败"); } // 获取 5 天天气预报 Future> getWeatherForecast( double latitude, double longitude) async { try { return await weatherFactory.fiveDayForecastByLocation( latitude, longitude); } catch (e) { print('获取天气预报失败: $e'); rethrow; } } // 重置权限状态(可选,用于测试或特定场景) void resetPermissionState() { _isRequestingPermission = false; _hasShownPermissionDialog = false; } }