feat: 1.调整项目初始化,不用等待site/config接口,仅在hi_user_info中调用;将site_config_service拆成loadDomain和获取配置,在splash中只做loadDomain
2. 优化接口拦截的解密日志 3. 调整获取订阅到kr_home,与源版一致 4. 修复闪连抖动问题,增加套餐有效期判断
This commit is contained in:
@@ -379,23 +379,15 @@ class KRAuthApi {
|
||||
|
||||
print('📤 原始请求数据: $data');
|
||||
|
||||
// 检查是否需要加密
|
||||
final siteConfigService = KRSiteConfigService();
|
||||
final needEncryption = siteConfigService.isDeviceSecurityEnabled();
|
||||
|
||||
print('🔒 是否需要加密: $needEncryption');
|
||||
KRLogUtil.kr_i('🔒 是否需要加密: $needEncryption', tag: 'KRAuthApi');
|
||||
|
||||
final needEncryption = true;
|
||||
String? requestBody;
|
||||
if (needEncryption) {
|
||||
// 加密请求数据
|
||||
print('🔐 加密请求数据...');
|
||||
final encrypted = KRAesUtil.encryptJson(data, AppConfig.kr_encryptionKey);
|
||||
requestBody = '{"data":"${encrypted['data']}","time":"${encrypted['time']}"}';
|
||||
print('🔐 加密后请求体: $requestBody');
|
||||
KRLogUtil.kr_i('🔐 加密后请求体', tag: 'KRAuthApi');
|
||||
// print('🔐 加密后请求体: $requestBody');
|
||||
// KRLogUtil.kr_i('🔐 加密后请求体', tag: 'KRAuthApi');
|
||||
} else {
|
||||
// 使用明文
|
||||
requestBody = jsonEncode(data);
|
||||
print('📝 明文请求体: $requestBody');
|
||||
}
|
||||
@@ -439,10 +431,10 @@ class KRAuthApi {
|
||||
),
|
||||
);
|
||||
|
||||
print('📥 响应状态码: ${response.statusCode}');
|
||||
print('📥 响应数据: ${response.data}');
|
||||
KRLogUtil.kr_i('📥 响应状态码: ${response.statusCode}', tag: 'KRAuthApi');
|
||||
KRLogUtil.kr_i('📥 响应数据: ${response.data}', tag: 'KRAuthApi');
|
||||
// print('📥 响应状态码: ${response.statusCode}');
|
||||
// print('📥 响应数据: ${response.data}');
|
||||
// KRLogUtil.kr_i('📥 响应状态码: ${response.statusCode}', tag: 'KRAuthApi');
|
||||
// KRLogUtil.kr_i('📥 响应数据: ${response.data}', tag: 'KRAuthApi');
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
Map<String, dynamic> responseData = response.data as Map<String, dynamic>;
|
||||
|
||||
@@ -28,28 +28,23 @@ class KRDeviceInfoService {
|
||||
/// 初始化设备信息
|
||||
Future<void> initialize() async {
|
||||
try {
|
||||
if (kDebugMode) {
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
print('📱 开始初始化设备信息服务');
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
}
|
||||
KRLogUtil.kr_i('📱 开始初始化设备信息', tag: 'KRDeviceInfoService');
|
||||
|
||||
_deviceId = await _getDeviceId();
|
||||
_deviceDetails = await _getDeviceDetails();
|
||||
|
||||
if (kDebugMode) {
|
||||
print('✅ 设备信息初始化成功');
|
||||
print('📱 设备ID: $_deviceId');
|
||||
print('📱 设备平台: ${getPlatformName()}');
|
||||
print('📱 设备型号: ${getDeviceModel()}');
|
||||
print('📱 系统版本: ${getOSVersion()}');
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
// print('✅ 设备信息初始化成功');
|
||||
// print('📱 设备ID: $_deviceId');
|
||||
// print('📱 设备平台: ${getPlatformName()}');
|
||||
// print('📱 设备型号: ${getDeviceModel()}');
|
||||
// print('📱 系统版本: ${getOSVersion()}');
|
||||
// print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
}
|
||||
|
||||
KRLogUtil.kr_i('✅ 设备信息初始化成功', tag: 'KRDeviceInfoService');
|
||||
KRLogUtil.kr_i('📱 设备ID - $_deviceId', tag: 'KRDeviceInfoService');
|
||||
KRLogUtil.kr_i('📱 设备详情 - $_deviceDetails', tag: 'KRDeviceInfoService');
|
||||
// KRLogUtil.kr_i('📱 设备ID - $_deviceId', tag: 'KRDeviceInfoService');
|
||||
// KRLogUtil.kr_i('📱 设备详情 - $_deviceDetails', tag: 'KRDeviceInfoService');
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print('❌ 设备信息初始化失败: $e');
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:dio/io.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
@@ -7,6 +8,7 @@ import '../common/app_config.dart';
|
||||
import '../utils/kr_log_util.dart';
|
||||
import '../utils/kr_http_adapter_util.dart';
|
||||
import 'singbox_imp/kr_sing_box_imp.dart';
|
||||
import 'api_service/kr_api.user.dart';
|
||||
|
||||
/// 网站配置服务
|
||||
class KRSiteConfigService extends ChangeNotifier {
|
||||
@@ -18,15 +20,6 @@ class KRSiteConfigService extends ChangeNotifier {
|
||||
_dio.options.sendTimeout = const Duration(seconds: 20);
|
||||
_dio.options.receiveTimeout = const Duration(seconds: 20);
|
||||
|
||||
// 🔧 关键修复:网站配置请求不使用代理
|
||||
// 原因:网站配置是应用启动的第一步,此时 SingBox 还未初始化
|
||||
// 必须直接连接服务器获取配置,避免循环依赖和初始化失败
|
||||
// 之前的代理配置会导致 DioExceptionType.unknown 错误
|
||||
KRLogUtil.kr_i(
|
||||
'🌐 网站配置服务:使用直连模式(不通过代理)',
|
||||
tag: 'KRSiteConfigService',
|
||||
);
|
||||
|
||||
// 🔧 关键修复:添加 SSL 证书验证跳过,强制直连
|
||||
_dio.httpClientAdapter = KRHttpAdapterUtil.createAdapter(
|
||||
useSingBoxProxy: false,
|
||||
@@ -49,190 +42,126 @@ class KRSiteConfigService extends ChangeNotifier {
|
||||
/// 是否已初始化
|
||||
bool get isInitialized => _isInitialized;
|
||||
|
||||
/// 初始化站点配置
|
||||
Future<bool> initialize() async {
|
||||
int retryCount = 0;
|
||||
const int maxRetries = 5;
|
||||
return await initializeDomains();
|
||||
}
|
||||
|
||||
while (retryCount < maxRetries) {
|
||||
try {
|
||||
if (kDebugMode) {
|
||||
print('🔧 KRSiteConfigService.initialize() 开始执行 (尝试 ${retryCount + 1}/$maxRetries)');
|
||||
}
|
||||
KRLogUtil.kr_i('🔧 开始初始化网站配置 (尝试 ${retryCount + 1}/$maxRetries)', tag: 'KRSiteConfigService');
|
||||
|
||||
// Debug 模式下使用固定地址
|
||||
final baseUrl = AppConfig().baseUrl;
|
||||
if (kDebugMode) {
|
||||
print('📍 baseUrl = $baseUrl');
|
||||
}
|
||||
final url = '$baseUrl/v1/common/site/config';
|
||||
if (kDebugMode) {
|
||||
print('📍 完整URL = $url');
|
||||
}
|
||||
|
||||
KRLogUtil.kr_i('📤 请求网站配置 - $url', tag: 'KRSiteConfigService');
|
||||
if (kDebugMode) {
|
||||
print('📤 准备发送 GET 请求到: $url');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
// 🔧 修正日志,显示真实的超时配置
|
||||
print('⏱️ 超时配置: connectTimeout=${_dio.options.connectTimeout}, sendTimeout=${_dio.options.sendTimeout}, receiveTimeout=${_dio.options.receiveTimeout}');
|
||||
}
|
||||
|
||||
if (kDebugMode) {
|
||||
print('⏳ 开始发送请求...');
|
||||
}
|
||||
final startTime = DateTime.now();
|
||||
final response = await _dio.get(url);
|
||||
final endTime = DateTime.now();
|
||||
final duration = endTime.difference(startTime).inMilliseconds;
|
||||
if (kDebugMode) {
|
||||
print('⏱️ 请求耗时: ${duration}ms');
|
||||
}
|
||||
|
||||
if (kDebugMode) {
|
||||
print('✅ 请求完成,状态码: ${response.statusCode}');
|
||||
}
|
||||
KRLogUtil.kr_i('📥 响应状态码 - ${response.statusCode}', tag: 'KRSiteConfigService');
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final responseData = response.data;
|
||||
if (kDebugMode) {
|
||||
print('📥 响应数据类型: ${responseData.runtimeType}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📥 响应数据: $responseData');
|
||||
}
|
||||
KRLogUtil.kr_i('📥 响应数据 - $responseData', tag: 'KRSiteConfigService');
|
||||
|
||||
if (responseData['code'] == 200) {
|
||||
_siteConfig = KRSiteConfig.fromJson(responseData['data']);
|
||||
_isInitialized = true;
|
||||
|
||||
final config = AppConfig.getInstance();
|
||||
config.kr_website_id = getCrispId();
|
||||
config.device_limit = getDeviceLimit();
|
||||
// 打印配置信息
|
||||
_printConfigInfo();
|
||||
|
||||
// 通知监听者配置已更新
|
||||
notifyListeners();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
KRLogUtil.kr_e('❌ API返回错误 - ${responseData['msg']}', tag: 'KRSiteConfigService');
|
||||
// API 返回业务错误,一般不重试,除非是特定错误码
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
KRLogUtil.kr_e('❌ HTTP错误 - ${response.statusCode}', tag: 'KRSiteConfigService');
|
||||
// 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}');
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是不可重试的错误,直接返回失败
|
||||
KRLogUtil.kr_e('📚 堆栈: $stackTrace', tag: 'KRSiteConfigService');
|
||||
return false;
|
||||
} catch (e, stackTrace) {
|
||||
if (kDebugMode) {
|
||||
print('❌ 未知异常: $e');
|
||||
}
|
||||
KRLogUtil.kr_e('❌ 初始化失败 - $e', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_e('📚 堆栈: $stackTrace', tag: 'KRSiteConfigService');
|
||||
return false;
|
||||
}
|
||||
Future<bool> initializeDomains() async {
|
||||
try {
|
||||
await KRDomain.kr_loadBaseDomain();
|
||||
_isInitialized = true;
|
||||
notifyListeners();
|
||||
return true;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> fetchSiteConfig() async {
|
||||
try {
|
||||
final result = await KRUserApi().kr_config();
|
||||
return await result.fold(
|
||||
(error) async {
|
||||
return false;
|
||||
},
|
||||
(cfg) async {
|
||||
try {
|
||||
if (cfg.kr_config.isNotEmpty) {
|
||||
final Map<String, dynamic> root = jsonDecode(cfg.kr_config);
|
||||
_siteConfig = KRSiteConfig.fromJson(root);
|
||||
AppConfig.getInstance().device_limit = getDeviceLimit();
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
} catch (_) {}
|
||||
return false;
|
||||
},
|
||||
);
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KRLogUtil.kr_e('❌ 达到最大重试次数 ($maxRetries),初始化失败', tag: 'KRSiteConfigService');
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 打印配置信息
|
||||
void _printConfigInfo() {
|
||||
if (_siteConfig == null) return;
|
||||
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('📊 网站配置信息:', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
|
||||
tag: 'KRSiteConfigService');
|
||||
|
||||
// 站点信息
|
||||
KRLogUtil.kr_i('🏠 站点名称: ${_siteConfig!.site.siteName}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('🏠 站点描述: ${_siteConfig!.site.siteDesc}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('🏠 站点域名: ${_siteConfig!.site.host}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('💬 Crisp ID: ${_siteConfig!.site.crispId}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('🏠 站点名称: ${_siteConfig!.site.siteName}',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('🏠 站点描述: ${_siteConfig!.site.siteDesc}',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('🏠 站点域名: ${_siteConfig!.site.host}',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('💬 Crisp ID: ${_siteConfig!.site.crispId}',
|
||||
tag: 'KRSiteConfigService');
|
||||
|
||||
// 注册相关
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('📝 注册配置:', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 开放注册: ${isRegisterEnabled() ? "是" : "否"}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 手机号注册: ${isMobileRegisterEnabled() ? "是" : "否"}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 邮箱注册: ${isEmailRegisterEnabled() ? "是" : "否"}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 设备登录: ${isDeviceLoginEnabled() ? "是" : "否"}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 开放注册: ${isRegisterEnabled() ? "是" : "否"}',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 手机号注册: ${isMobileRegisterEnabled() ? "是" : "否"}',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 邮箱注册: ${isEmailRegisterEnabled() ? "是" : "否"}',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 设备登录: ${isDeviceLoginEnabled() ? "是" : "否"}',
|
||||
tag: 'KRSiteConfigService');
|
||||
|
||||
// 验证相关
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('🔐 验证配置:', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 邮箱验证: ${isEmailVerificationEnabled() ? "是" : "否"}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 手机验证: ${isMobileVerificationEnabled() ? "是" : "否"}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 登录验证: ${isLoginVerificationEnabled() ? "是" : "否"}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 注册验证: ${isRegisterVerificationEnabled() ? "是" : "否"}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 重置密码验证: ${isResetPasswordVerificationEnabled() ? "是" : "否"}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 邮箱验证: ${isEmailVerificationEnabled() ? "是" : "否"}',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 手机验证: ${isMobileVerificationEnabled() ? "是" : "否"}',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 登录验证: ${isLoginVerificationEnabled() ? "是" : "否"}',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 注册验证: ${isRegisterVerificationEnabled() ? "是" : "否"}',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(
|
||||
' ✓ 重置密码验证: ${isResetPasswordVerificationEnabled() ? "是" : "否"}',
|
||||
tag: 'KRSiteConfigService');
|
||||
|
||||
// 邀请相关
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('🎁 邀请配置:', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 强制邀请码: ${isForcedInvite() ? "是" : "否"}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 推荐比例: ${_siteConfig!.invite.referralPercentage}%', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 强制邀请码: ${isForcedInvite() ? "是" : "否"}',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 推荐比例: ${_siteConfig!.invite.referralPercentage}%',
|
||||
tag: 'KRSiteConfigService');
|
||||
|
||||
// 货币相关
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('💰 货币配置:', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 货币单位: ${_siteConfig!.currency.currencyUnit}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 货币符号: ${_siteConfig!.currency.currencySymbol}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 货币单位: ${_siteConfig!.currency.currencyUnit}',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i(' ✓ 货币符号: ${_siteConfig!.currency.currencySymbol}',
|
||||
tag: 'KRSiteConfigService');
|
||||
|
||||
// OAuth 方法
|
||||
if (_siteConfig!.oauthMethods.isNotEmpty) {
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('🔑 OAuth 方法: ${_siteConfig!.oauthMethods.join(", ")}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('🔑 OAuth 方法: ${_siteConfig!.oauthMethods.join(", ")}',
|
||||
tag: 'KRSiteConfigService');
|
||||
}
|
||||
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
|
||||
tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('✅ 网站配置初始化成功', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
|
||||
tag: 'KRSiteConfigService');
|
||||
}
|
||||
|
||||
/// 是否开启手机号注册
|
||||
@@ -352,10 +281,12 @@ class KRSiteConfigService extends ChangeNotifier {
|
||||
return true;
|
||||
}
|
||||
|
||||
final allowedDomains = domainSuffixList.split(',').map((d) => d.trim()).toList();
|
||||
final allowedDomains =
|
||||
domainSuffixList.split(',').map((d) => d.trim()).toList();
|
||||
final emailDomain = email.split('@').last.toLowerCase();
|
||||
|
||||
return allowedDomains.any((domain) => emailDomain.endsWith(domain.toLowerCase()));
|
||||
return allowedDomains
|
||||
.any((domain) => emailDomain.endsWith(domain.toLowerCase()));
|
||||
}
|
||||
|
||||
/// 获取Crisp客服系统ID
|
||||
|
||||
Reference in New Issue
Block a user