fix: 1.修复域名切换失败; 2.动态域名添加核心白名单,3.修复windows字体

This commit is contained in:
2026-01-09 17:50:21 -08:00
parent 12eb8348d3
commit 9b5e370f0b
4 changed files with 150 additions and 109 deletions
@@ -85,10 +85,10 @@ class KRSplashController extends GetxController {
print('🧹 清理域名检测状态...');
KRDomain.kr_resetDomainState();
// 🔧 P2优化:网站配置和设备登录在后台执行,不阻塞主流程
print('🌐 启动后台任务:网站配置加载...');
KRLogUtil.kr_i('🌐 后台任务:网站配置和设备登录', tag: 'SplashController');
_kr_initSiteConfig(); // 不等待完成,在后台执行
// 🔧 P2优化:网站配置不再后台执行,改为串行执行以确保域名验证完成
// print('🌐 启动后台任务:网站配置加载...');
// KRLogUtil.kr_i('🌐 后台任务:网站配置和设备登录', tag: 'SplashController');
// _kr_initSiteConfig(); // 移至 _kr_continueInitialization 中串行执行
// 🔧 关键修复:先初始化日志收集器,再开始主流程
if (kDebugMode) {
@@ -551,6 +551,14 @@ class KRSplashController extends GetxController {
}
// 网络检查完成后执行设备登录(始终支持)
// 🔧 关键修复:在设备登录前先初始化站点配置,确保域名可用
// 这样如果主域名不可用,initSiteConfig 会切换到备用域名
// 后续的设备登录就能使用正确的域名
_logStepTiming('开始站点配置初始化');
await _kr_initSiteConfig();
_logStepTiming('站点配置初始化完成');
_logStepTiming('开始设备登录检查');
// 5️⃣ 执行设备登录
final success = await KRAppRunData.getInstance().kr_checkAndPerformDeviceLogin();
@@ -569,7 +577,12 @@ class KRSplashController extends GetxController {
}
_logStepTiming('设备登录检查完成');
// 初始化配置
// 初始化配置 (注意:这里再次调用init会导致重复,但AppConfig内部有防重,
// 不过为了逻辑清晰,既然上面已经调用了_kr_initSiteConfig(获取了KRSiteConfig)
// 下面AppConfig().initConfig主要是做AppConfig层面的配置加载,可能包含重复的请求。
// 鉴于 AppConfig().initConfig 也会调用 API,为了保险起见,
// 我们可以让 AppConfig().initConfig 使用已经切换好的域名。)
_initLog.log('⚙️ 开始初始化应用配置(域名加载等)', tag: 'Continue');
KRLogUtil.kr_i('⚙️ 开始初始化应用配置...', tag: 'SplashController');
await AppConfig().initConfig(
+41 -31
View File
@@ -51,11 +51,15 @@ class KRSiteConfigService extends ChangeNotifier {
/// 初始化站点配置
Future<bool> initialize() async {
int retryCount = 0;
const int maxRetries = 5;
while (retryCount < maxRetries) {
try {
if (kDebugMode) {
print('🔧 KRSiteConfigService.initialize() 开始执行');
print('🔧 KRSiteConfigService.initialize() 开始执行 (尝试 ${retryCount + 1}/$maxRetries)');
}
KRLogUtil.kr_i('🔧 开始初始化网站配置', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🔧 开始初始化网站配置 (尝试 ${retryCount + 1}/$maxRetries)', tag: 'KRSiteConfigService');
// Debug 模式下使用固定地址
final baseUrl = AppConfig().baseUrl;
@@ -118,59 +122,65 @@ class KRSiteConfigService extends ChangeNotifier {
return true;
} else {
KRLogUtil.kr_e('❌ API返回错误 - ${responseData['msg']}', tag: 'KRSiteConfigService');
// API 返回业务错误,一般不重试,除非是特定错误码
return false;
}
} else {
KRLogUtil.kr_e('❌ HTTP错误 - ${response.statusCode}', tag: 'KRSiteConfigService');
return false;
// HTTP 错误(如 404, 500)通常也意味着该域名有问题,尝试切换
// 但这里为了稳妥,先只针对网络异常重试,如果需要也可以改为抛出异常进入 catch
throw DioException(
requestOptions: response.requestOptions,
response: response,
type: DioExceptionType.badResponse,
error: 'HTTP Error ${response.statusCode}',
);
}
} on DioException catch (e, stackTrace) {
if (kDebugMode) {
print('❌ Dio请求异常: ${e.type}');
}
if (kDebugMode) {
print('❌ 错误信息: ${e.message}');
KRLogUtil.kr_e('❌ Dio异常 - ${e.type}: ${e.message}', tag: 'KRSiteConfigService');
// 检查是否是可以重试的错误类型
if (e.type == DioExceptionType.connectionTimeout ||
e.type == DioExceptionType.receiveTimeout ||
e.type == DioExceptionType.sendTimeout ||
e.type == DioExceptionType.connectionError ||
e.type == DioExceptionType.unknown || // unknown 有时也是网络问题
e.type == DioExceptionType.badResponse) { // 503 等服务器错误也值得重试
KRLogUtil.kr_w('⚠️ 网络或服务器异常,尝试切换域名重试...', tag: 'KRSiteConfigService');
// 尝试切换到下一个域名
final switchSuccess = await KRDomain.kr_switchToNextDomain();
if (switchSuccess) {
retryCount++;
KRLogUtil.kr_i('✅ 域名切换成功,准备第 ${retryCount + 1} 次尝试', tag: 'KRSiteConfigService');
continue; // 重新进入循环
} else {
KRLogUtil.kr_e('❌ 域名切换失败,无法继续重试', tag: 'KRSiteConfigService');
return false;
}
if (kDebugMode) {
print('❌ 请求URL: ${e.requestOptions.uri}');
}
if (kDebugMode) {
print('❌ 连接超时: ${e.requestOptions.connectTimeout}');
}
if (kDebugMode) {
print('❌ 发送超时: ${e.requestOptions.sendTimeout}');
}
if (kDebugMode) {
print('❌ 接收超时: ${e.requestOptions.receiveTimeout}');
}
if (e.response != null) {
if (kDebugMode) {
print('❌ 响应状态码: ${e.response?.statusCode}');
}
if (kDebugMode) {
print('❌ 响应数据: ${e.response?.data}');
}
}
if (kDebugMode) {
print('📚 堆栈跟踪: $stackTrace');
}
KRLogUtil.kr_e('❌ Dio异常 - ${e.type}: ${e.message}', tag: 'KRSiteConfigService');
// 如果是不可重试的错误,直接返回失败
KRLogUtil.kr_e('📚 堆栈: $stackTrace', tag: 'KRSiteConfigService');
return false;
} catch (e, stackTrace) {
if (kDebugMode) {
print('❌ 未知异常: $e');
}
if (kDebugMode) {
print('📚 堆栈跟踪: $stackTrace');
}
KRLogUtil.kr_e('❌ 初始化失败 - $e', tag: 'KRSiteConfigService');
KRLogUtil.kr_e('📚 堆栈: $stackTrace', tag: 'KRSiteConfigService');
return false;
}
}
KRLogUtil.kr_e('❌ 达到最大重试次数 ($maxRetries),初始化失败', tag: 'KRSiteConfigService');
return false;
}
/// 打印配置信息
void _printConfigInfo() {
if (_siteConfig == null) return;
@@ -689,6 +689,23 @@ class KRSingBoxImp {
List<Map<String, dynamic>> _kr_buildHiddifyRules() {
final rules = <Map<String, dynamic>>[];
rules.add({"domains": "domain:api.hifast.biz", "outbound": "bypass"});
// 使用 domain:crisp.chat (这通常会匹配所有子域名)
rules.add({"domains": "domain:crisp.chat", "outbound": "bypass"});
// 某些 sing-box 版本可能需要显式包含 relay 域名
rules.add({"domains": "domain:client.relay.crisp.chat", "outbound": "bypass"});
// 🔧 新增:将动态域名列表加入到规则中 (直连)
// 使用 Set 去重,避免重复添加
final baseDomains = KRDomain.kr_baseDomains.toSet();
KRLogUtil.kr_i('🔄 将 ${baseDomains.length} 个动态域名加入直连规则: $baseDomains', tag: 'SingBox');
for (final domain in baseDomains) {
if (domain.isNotEmpty) {
// 检查是否已经存在(虽然Set去重了,但上面的硬编码可能重复)
// 简单起见直接添加,sing-box 通常能处理重复规则,或者规则越前优先级越高
rules.add({"domains": "domain:$domain", "outbound": "bypass"});
}
}
final nodeDomains = _kr_collectNodeDomains();
for (final d in nodeDomains) {
+1
View File
@@ -60,6 +60,7 @@ class _HICollapsibleItemWidgetState extends State<HICollapsibleItemWidget> {
text: linkText,
style: const TextStyle(
color: const Color(0xFFADFF5B), // 链接颜色
fontFamily: 'AlibabaPuHuiTi-Regular',
),
recognizer: TapGestureRecognizer()
..onTap = () async {