Files
tuiche/lib/controller/weather/weather_controller.dart
2025-07-01 11:49:39 +08:00

185 lines
5.9 KiB
Dart

import 'dart:async';
import 'package:EasyDartModule/EasyDartModule.dart';
import 'package:ef/ef.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/common/util/CommonVariables.dart';
import 'package:vbvs_app/controller/setting/language/language_controller.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();
await _getCurrentLocation();
_weatherTimer = Timer.periodic(Duration(seconds: 5), (timer) {
_getCurrentWeather(); // 每 5 秒更新一次天气
});
_locationTimer = Timer.periodic(Duration(minutes: 10), (timer) {
_getCurrentLocation(); // 每 10 分钟更新一次位置
});
}
@override
void onClose() {
_weatherTimer?.cancel(); // 取消天气更新定时器
_locationTimer?.cancel(); // 取消位置更新定时器
super.onClose();
}
// 获取当前位置并存储到 model
Future<void> _getCurrentLocation() async {
try {
Position position = await determinePosition();
if (position == null) {
throw Exception("获取位置失败");
}
String? language = "zh_CN";
if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code;
}
List<Placemark> placemarks = [];
// placemarks = await placemarkFromCoordinates(position.latitude, position.longitude,
// localeIdentifier: language);
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('位置服务未启用');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
return Future.error('位置权限被拒绝');
}
}
if (permission == LocationPermission.deniedForever) {
return Future.error('位置权限被永久拒绝');
}
return await Geolocator.getCurrentPosition();
}
// 获取天气信息
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 (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!);
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;
}
}
}