Files
tuiche/lib/controller/weather/weather_controller.dart
2025-08-25 15:43:17 +08:00

260 lines
8.8 KiB
Dart
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<String, dynamic> json) =>
_$WeatherModelFromJson(json);
Map<String, dynamic> toJson() => _$WeatherModelToJson(this);
}
class WeatherModelController extends GetControllerEx<WeatherModel> {
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<void> 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<void> 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<Placemark> 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<Position> 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(
locationSettings: const LocationSettings(
accuracy: LocationAccuracy.low, // 使用高精度定位,但不依赖 Google Play
distanceFilter: 1000, // 设置最小距离过滤
timeLimit: Duration(seconds: 10), // 设置获取位置的最大等待时间
),
);
}
// 获取天气信息
Future<void> getCurrentWeather() async {
if (model.latitude == null || model.longitude == null) {
EasyDartModule.logger.error("获取天气失败:位置数据获取失败");
return; // 如果位置数据没有获取到,则不更新天气
}
// String? language = "zh_CN";
// if (languageController.selectLanguage != null) {
// language = languageController.selectLanguage.value!.language_code;
// }
List<Placemark> placemarks = [];
// placemarks = await placemarkFromCoordinates(model.latitude!, model.longitude!,
// localeIdentifier: language);
if (placemarks.isNotEmpty) {
model.cityName = placemarks[0].locality ?? "未知数据".tr;
}
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);
});
// model.weather_info = weather.weatherDescription;
// model.min_temperature = weather.tempMin?.celsius?.toInt();
// model.max_temperature = weather.tempMax?.celsius?.toInt();
// model.current_temperature = weather.temperature?.celsius?.toInt();
// model.wind_speed = weather.windSpeed?.toInt();
// model.weatherIcon = weather.weatherIcon;
// if (model.weatherIcon != null) {
// model.weatherIconurl =
// "https://openweathermap.org/img/w/${model.weatherIcon}.png";
// }
updateAll(); // 更新 UI
} catch (e) {
EasyDartModule.logger.error("获取天气失败: $e");
print('获取天气失败: $e');
}
}
// 获取 5 天天气预报
Future<List<Weather>> getWeatherForecast(
double latitude, double longitude) async {
try {
return await weatherFactory.fiveDayForecastByLocation(
latitude, longitude);
} catch (e) {
print('获取天气预报失败: $e');
rethrow;
}
}
}