import 'dart:convert'; import 'dart:math'; import 'package:ef/base/getx/getx.dart'; import 'package:ef/ef.dart'; import 'package:flutter/services.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:vbvs_app/controller/setting/language/language_controller.dart'; import 'package:vbvs_app/language/AppLanguage.dart'; part 'city.g.dart'; @JsonSerializable() class CityModel { int? id; // 城市id String? value; // 显示值(国家/省份/城市名称) String? label; // 标签(通常与value相同) String? country; // 国家名称 String? province; // 省份名称 String? city; // 城市名称 String? UTC; // 时区 List? children; @JsonKey(ignore: true) String? keyword = ""; @JsonKey(ignore: true) Color? color = Color(0xFFFFFFFF); CityModel({ this.id, this.value, this.label, this.country, this.province, this.city, this.UTC, this.children, }); // 从JSON反序列化时的异常处理 factory CityModel.fromJson(Map json) { try { return _$CityModelFromJson(json); } catch (e) { print('Error parsing CityModel: $e'); return CityModel(); // 返回空的CityModel } } // 序列化为JSON时的异常处理 Map toJson() => _$CityModelToJson(this); // 获取显示名称(根据层级显示) String get displayName { if (city != null && city!.isNotEmpty) { // 三级:国家-省份-城市 return '${country ?? ''}-${province ?? ''}-${city ?? value ?? ''}'; } else if (province != null && province!.isNotEmpty) { // 二级:国家-省份 return '${country ?? ''}-${province ?? value ?? ''}'; } else { // 一级:国家 return country ?? value ?? ''; } } } class CityModelController extends GetControllerEx { List cityList = []; LanguageController languageController = Get.find(); RxInt tmp = 1.obs; RxBool isLoading = false.obs; List? searchResults = []; // 新增:搜索结果列表 CityModelController() { attr = GetModel(CityModel()).obs; } // 加载城市数据并赋值给cityList Future loadAndSetCityData() async { try { isLoading.value = true; ef.log("开始加载城市数据..."); final data = await _loadCityData(); cityList = data; ef.log("城市数据加载完成,共${cityList.length}个国家"); if (cityList.isNotEmpty) { // 打印前几个国家用于调试 for (var i = 0; i < min(3, cityList.length); i++) { final country = cityList[i]; ef.log( "国家: ${country.value}, 省份数量: ${country.children?.length ?? 0}"); } } update(); } catch (e) { ef.log("加载城市数据失败:$e"); } finally { isLoading.value = false; } } // 内部加载方法 Future> _loadCityData() async { try { // 获取当前语言代码 String currentLanguageCode = AppLanguage().getCurrentLanguageCode(); // 根据当前语言代码构建文件名 final String fileName = 'assets/city/city_$currentLanguageCode.json'; // 读取对应语言的JSON文件 final String jsonString = await rootBundle.loadString(fileName); // 解析JSON数据并转换为 CityModel 列表 final List jsonList = jsonDecode(jsonString); // 将 Map 转换为 CityModel return jsonList.map((json) => CityModel.fromJson(json)).toList(); } catch (e) { ef.log("_loadCityData 失败:$e"); return []; } } // 根据ID查找城市(支持国家、省份、城市所有层级) CityModel? findCityById(String id) { if (cityList.isEmpty) { ef.log("cityList为空,无法查找城市,请先调用 loadAndSetCityData()"); return null; } final int? targetId = int.tryParse(id); if (targetId == null) { ef.log("ID格式错误:$id"); return null; } ef.log("开始查找ID为 $targetId 的城市数据..."); // 遍历三级结构 for (var country in cityList) { // 检查国家 if (country.id == targetId) { ef.log("找到匹配的国家: ${country.value}"); return CityModel( id: country.id, value: country.value, label: country.label, country: country.value, province: null, city: null, UTC: country.UTC, ); } // 检查省份 for (var province in country.children ?? []) { if (province.id == targetId) { ef.log("找到匹配的省份: ${province.value}, 国家: ${country.value}"); return CityModel( id: province.id, value: province.value, label: province.label, country: country.value, province: province.value, city: null, UTC: province.UTC, ); } // 检查城市 for (var city in province.children ?? []) { if (city.id == targetId) { ef.log( "找到匹配的城市: ${city.value}, 省份: ${province.value}, 国家: ${country.value}"); return CityModel( id: city.id, value: city.value, label: city.label, country: country.value, province: province.value, city: city.value, UTC: city.UTC, ); } } } } ef.log("未找到ID为 $targetId 的城市数据"); return null; } // 根据名称查找城市 CityModel? findCityByName( String countryName, String provinceName, String cityName) { if (cityList.isEmpty) { ef.log("cityList为空,无法查找城市"); return null; } for (var country in cityList) { if (country.value == countryName) { for (var province in country.children ?? []) { if (province.value == provinceName) { for (var city in province.children ?? []) { if (city.value == cityName) { return city; } } } } } } return null; } // 检查是否已加载数据 bool get isDataLoaded => cityList.isNotEmpty; // void searchCities(String keyword) { // model.keyword = keyword; // searchResults?.clear(); // if (keyword.isEmpty) { // return; // } // final keywordLower = keyword.toLowerCase(); // // 遍历所有城市数据 // for (var country in cityList) { // final countryName = country.value ?? country.country ?? ''; // for (var province in country.children ?? []) { // final provinceName = province.value ?? province.province ?? ''; // for (var city in province.children ?? []) { // final cityName = city.value ?? city.city ?? ''; // final displayName = '$countryName-$provinceName-$cityName'; // // 模糊匹配 // if (countryName.toLowerCase().contains(keywordLower) || // provinceName.toLowerCase().contains(keywordLower) || // cityName.toLowerCase().contains(keywordLower) || // displayName.toLowerCase().contains(keywordLower)) { // searchResults?.add(displayName); // } // } // } // } // } void searchCities(String keyword) { model.keyword = keyword; searchResults?.clear(); if (keyword.isEmpty) { return; } final keywordLower = keyword.toLowerCase(); for (var country in cityList) { final countryName = country.value ?? country.country ?? ''; // 如果该国家没有 children(一级结构) if (country.children == null || country.children!.isEmpty) { final name = countryName; if (name.toLowerCase().contains(keywordLower)) { searchResults?.add(name); } continue; } // 二层循环:省份或城市 for (var province in country.children!) { final provinceName = province.value ?? province.province ?? ''; final level2Name = '$countryName-$provinceName'; // 省本身是否匹配(适用于 国家→省 二级结构) if (province.children == null || province.children!.isEmpty) { if (countryName.toLowerCase().contains(keywordLower) || provinceName.toLowerCase().contains(keywordLower) || level2Name.toLowerCase().contains(keywordLower)) { searchResults?.add(level2Name); } continue; } // 有第三级城市 → 遍历城市 for (var city in province.children!) { final cityName = city.value ?? city.city ?? ''; final level3Name = '$countryName-$provinceName-$cityName'; if (countryName.toLowerCase().contains(keywordLower) || provinceName.toLowerCase().contains(keywordLower) || cityName.toLowerCase().contains(keywordLower) || level3Name.toLowerCase().contains(keywordLower)) { searchResults?.add(level3Name); } } } } } // 根据显示名称获取对应的 CityModel // CityModel? getCityByDisplayName(String displayName) { // final parts = displayName.split('-'); // if (parts.length != 3) return null; // final countryName = parts[0]; // final provinceName = parts[1]; // final cityName = parts[2]; // for (var country in cityList) { // if ((country.value ?? country.country ?? '') == countryName) { // for (var province in country.children ?? []) { // if ((province.value ?? province.province ?? '') == provinceName) { // for (var city in province.children ?? []) { // if ((city.value ?? city.city ?? '') == cityName) { // return city; // } // } // } // } // } // } // return null; // } CityModel? getCityByDisplayName(String displayName) { final parts = displayName.split('-'); if (parts.isEmpty) return null; final countryName = parts[0]; final provinceName = parts.length >= 2 ? parts[1] : null; final cityName = parts.length >= 3 ? parts[2] : null; for (var country in cityList) { final cName = country.value ?? country.country ?? ''; if (cName != countryName) continue; // 一级结构:直接 return 国家 if (provinceName == null) { return country; } // 如果没有 children,就不可能有省或市 if (country.children == null || country.children!.isEmpty) { return null; } // 二级匹配:省或城市 for (var province in country.children!) { final pName = province.value ?? province.province ?? ''; if (pName != provinceName) continue; // 二级结构:国家-省 if (cityName == null) { return province; } // 有城市才继续 if (province.children == null || province.children!.isEmpty) { return null; } // 三级结构:国家-省-市 for (var city in province.children!) { final ciName = city.value ?? city.city ?? ''; if (ciName == cityName) { return city; } } } } return null; } }