hi-client/lib/app/model/business/kr_outbounds_list.dart
speakeloudest 325a63d35f
Some checks failed
Build Windows / 编译 libcore (Windows) (20.15.1) (push) Successful in 20m34s
Build Windows / build (push) Has been cancelled
feat: 完成国家配置
2025-11-19 01:06:48 -08:00

152 lines
4.7 KiB
Dart
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import '../response/kr_node_group_list.dart';
import 'kr_group_outbound_list.dart';
import '../response/kr_node_list.dart';
import 'kr_outbound_item.dart';
import 'package:flutter/foundation.dart';
/// 表示出站项列表的模型类
class KrOutboundsList {
/// 服务器分组
final List<KRGroupOutboundList> groupOutboundList = []; // 存储服务器分组的列表
/// 国家分组,包含所有国家
final List<KRCountryOutboundList> countryOutboundList = []; // 存储国家分组的列表
/// 全部列表
final List<KROutboundItem> allList = []; // 存储国家分组的列表
// 配置json
final List<Map<String,dynamic>> configJsonList = [];
/// 标签列表
final Map<String,KROutboundItem> keyList = {}; // 存储国家分组的列表
/// 处理出站项并将其分组
/// [list] 是要处理的出站项列表
void processOutboundItems(List<KrNodeListItem> list,List<KRNodeGroupListItem> groupList) {
final Map<String, List<KROutboundItem>> tagGroups = {};
final Map<String, List<KROutboundItem>> countryGroups = {};
// 用于追踪已使用的标签
final Map<String, int> tagCounter = {};
for (var element in list) {
// 生成唯一标签
var baseName = element.name;
if (tagCounter.containsKey(baseName)) {
tagCounter[baseName] = tagCounter[baseName]! + 1;
element.name = "${baseName}_${tagCounter[baseName]}";
} else {
tagCounter[baseName] = 0;
}
final KROutboundItem item = KROutboundItem(element);
// 🔍 调试日志:验证 country 字段传递
if (kDebugMode) {
print('🗺️ 构建节点: name="${element.name}", tag="${item.tag}", country="${item.country}"');
}
if (kDebugMode) {
print(' - element.country: "${element.country}"');
}
if (kDebugMode) {
print(' - item.country: "${item.country}"');
}
if (kDebugMode) {
print(' - country.isEmpty: ${item.country.isEmpty}');
}
// 检查节点配置是否有效(必须包含 type 字段)
if (item.config.isEmpty || !item.config.containsKey('type')) {
if (kDebugMode) {
print('⚠️ 跳过无效节点: ${element.name},配置为空或缺少 type 字段');
}
continue; // 跳过无效节点
}
allList.add(item);
// 根据标签分组出站项
for (var tag in element.tags) {
tagGroups.putIfAbsent(tag, () => []);
tagGroups[tag]?.add(item);
}
// 根据国家分组出站项
countryGroups.putIfAbsent(element.country, () => []);
countryGroups[element.country]?.add(item);
configJsonList.add(item.config);
keyList[item.tag] = item;
if (kDebugMode) {
print('✅ keyList["${item.tag}"] 已设置country="${item.country}"');
}
}
// 生成国家自动选择虚拟节点
_generateCountryAutoNodes(countryGroups);
// 将标签分组转换为 KRGroupOutboundList 并添加到 groupOutboundList
for (var tag in tagGroups.keys) {
final item = KRGroupOutboundList(
tag: tag, outboundList: tagGroups[tag]!);
for (var group in groupList) {
if (item.tag == group.name) {
item.icon = group.icon;
break;
}
}
groupOutboundList.add(item); // 添加标签分组到列表
}
// 将国家分组转换为 KRCountryOutboundList 并添加到 countryOutboundList
for (var country in countryGroups.keys) {
countryOutboundList.add(KRCountryOutboundList(
country: country,
outboundList: countryGroups[country]!)); // 添加国家分组到列表
}
}
/// 生成国家自动选择虚拟节点
void _generateCountryAutoNodes(Map<String, List<KROutboundItem>> countryGroups) {
for (var entry in countryGroups.entries) {
final country = entry.key;
final nodes = entry.value;
final autoTag = '${country}-auto';
if (kDebugMode) {
print('🤖 生成国家自动选择节点: $autoTag, 包含 ${nodes.length} 个节点');
}
// 构建 urltest 配置
final urltestConfig = {
'type': 'urltest',
'tag': autoTag,
'outbounds': nodes.map((node) => node.tag).toList(),
'url': 'https://www.google.com/generate_204',
'interval': '10m',
'tolerance': 50,
"interrupt_exist_connections": true,
};
// 创建虚拟节点
final virtualNode = KROutboundItem.fromVirtual(autoTag, country, urltestConfig);
// 添加到各个列表
allList.add(virtualNode);
keyList[autoTag] = virtualNode;
// configJsonList.add(urltestConfig);
if (kDebugMode) {
print('✅ 生成虚拟节点: $autoTag, 配置: ${urltestConfig.toString()}');
}
}
}
}