diff --git a/lib/app/modules/kr_crisp_chat/controllers/kr_crisp_controller.dart b/lib/app/modules/kr_crisp_chat/controllers/kr_crisp_controller.dart index 365e914..f7b5871 100755 --- a/lib/app/modules/kr_crisp_chat/controllers/kr_crisp_controller.dart +++ b/lib/app/modules/kr_crisp_chat/controllers/kr_crisp_controller.dart @@ -10,8 +10,6 @@ import 'package:flutter/foundation.dart'; // 移动平台使用原生 SDK import 'package:crisp_chat/crisp_chat.dart' as native_crisp; -// 桌面平台使用 WebView SDK -import 'package:crisp_sdk/crisp_sdk.dart' as webview_crisp; /// 🔧 P15 重构: Crisp 聊天控制器 /// - 移动平台 (Android/iOS): 使用 crisp_chat 原生 SDK,解决 WebView 黑屏问题 @@ -20,11 +18,6 @@ class KRCrispController extends GetxController { // ========== 移动平台 (原生 SDK) ========== native_crisp.CrispConfig? _nativeConfig; - // ========== 桌面平台 (WebView SDK) ========== - webview_crisp.CrispController? crispController; - Completer? _kr_initializationCompleter; - bool _kr_isDisposed = false; - // ========== 共享状态 ========== final RxBool kr_isLoading = true.obs; final RxBool kr_isInitialized = false.obs; @@ -35,10 +28,9 @@ class KRCrispController extends GetxController { @override void onInit() { super.onInit(); + debugPrint('🐛 [KRCrispController] onInit triggered (Hash: ${hashCode})'); if (_isMobilePlatform) { _kr_prepareMobileConfig(); - } else { - _kr_prepareDesktopInitialization(); } } @@ -69,11 +61,26 @@ class KRCrispController extends GetxController { nickName: identifier, ), ); + + // 🔧 P15-Optim: 尝试在初始化时就设置 Session,而不是打开时 + final currentLanguage = KRLanguageUtils.getCurrentLanguageCode(); + native_crisp.FlutterCrispChat.setSessionString( + key: 'platform', + value: Platform.isAndroid ? 'android' : 'ios', + ); + native_crisp.FlutterCrispChat.setSessionString( + key: 'language', + value: currentLanguage, + ); + native_crisp.FlutterCrispChat.setSessionString( + key: 'device_id', + value: deviceId, + ); kr_isInitialized.value = true; if (kDebugMode) { - print('[P15-Mobile] Crisp 原生 SDK 配置已准备'); + print('[P15-Mobile] Crisp 原生 SDK 配置及Session已预设'); } } catch (e) { if (kDebugMode) { @@ -89,7 +96,9 @@ class KRCrispController extends GetxController { if (kDebugMode) { print('[P15-Mobile] Crisp 配置未准备好'); } - return; + // 尝试重新准备 + _kr_prepareMobileConfig(); + if (_nativeConfig == null) return; } try { @@ -99,23 +108,6 @@ class KRCrispController extends GetxController { await native_crisp.FlutterCrispChat.openCrispChat(config: _nativeConfig!); - // 设置会话数据 - final currentLanguage = KRLanguageUtils.getCurrentLanguageCode(); - final deviceId = KRDeviceInfoService().deviceId ?? 'unknown'; - - native_crisp.FlutterCrispChat.setSessionString( - key: 'platform', - value: Platform.isAndroid ? 'android' : 'ios', - ); - native_crisp.FlutterCrispChat.setSessionString( - key: 'language', - value: currentLanguage, - ); - native_crisp.FlutterCrispChat.setSessionString( - key: 'device_id', - value: deviceId, - ); - if (kDebugMode) { print('[P15-Mobile] Crisp 聊天界面已打开'); } @@ -126,172 +118,19 @@ class KRCrispController extends GetxController { } } - // ========================================== - // 桌面平台方法 (macOS/Windows - WebView SDK) - // ========================================== - - /// 准备桌面平台初始化 - Future _kr_prepareDesktopInitialization() async { - if (_kr_isDisposed) return; - - _kr_initializationCompleter = Completer(); - - try { - kr_isLoading.value = true; - await kr_initializeDesktopCrisp(); - if (!_kr_isDisposed) { - kr_isInitialized.value = true; - } - } catch (e) { - if (kDebugMode) { - print('[P15-Desktop] 初始化 Crisp 时出错: $e'); - } - if (!_kr_isDisposed) { - kr_isInitialized.value = false; - } - } finally { - if (!_kr_isDisposed) { - kr_isLoading.value = false; - } - _kr_initializationCompleter?.complete(); - } - } - - /// 初始化桌面平台 Crisp (WebView) - Future kr_initializeDesktopCrisp() async { - if (_kr_isDisposed) return; - - try { - final appData = KRAppRunData(); - final currentLanguage = KRLanguageUtils.getCurrentLanguageCode(); - final userEmail = appData.kr_account.value ?? ''; - final deviceId = KRDeviceInfoService().deviceId ?? 'unknown'; - final identifier = userEmail.isNotEmpty ? userEmail : deviceId; - - String locale = _getLocaleForCrisp(currentLanguage); - - if (_kr_isDisposed) return; - - // 初始化 WebView Crisp 控制器 - crispController = webview_crisp.CrispController( - websiteId: AppConfig.getInstance().kr_website_id, - locale: locale, - ); - - if (_kr_isDisposed) { - crispController = null; - return; - } - - // 设置用户信息 - crispController?.register( - user: webview_crisp.CrispUser( - email: identifier, - nickname: identifier, - ), - ); - - if (_kr_isDisposed) { - crispController = null; - return; - } - - // 设置会话数据 - crispController?.setSessionData({ - 'platform': Platform.isWindows ? 'windows' : 'macos', - 'language': currentLanguage, - 'app_version': '1.0.0', - 'device_id': deviceId, - }); - - if (kDebugMode) { - print('[P15-Desktop] Crisp WebView 初始化完成'); - } - } catch (e) { - if (kDebugMode) { - print('[P15-Desktop] 初始化 Crisp 时出错: $e'); - } - crispController = null; - rethrow; - } - } - - /// 根据应用语言代码获取 Crisp locale - String _getLocaleForCrisp(String languageCode) { - switch (languageCode) { - case 'zh_CN': - case 'zh': - return 'zh'; - case 'zh_TW': - case 'zhHant': - return 'zh-tw'; - case 'es': - return 'es'; - case 'ja': - return 'ja'; - case 'ru': - return 'ru'; - case 'et': - return 'et'; - case 'en': - default: - return 'en'; - } - } - // ========================================== // 生命周期管理 // ========================================== @override void onClose() { - _kr_isDisposed = true; - if (_isMobilePlatform) { // 移动平台:原生 SDK 无需手动清理 if (kDebugMode) { print('[P15-Mobile] onClose - 原生 SDK 无需手动清理'); } - } else { - // 桌面平台:清理 WebView 资源 - _kr_cleanupDesktopResources(); } super.onClose(); } - - /// 清理桌面平台资源 - Future _kr_cleanupDesktopResources() async { - try { - if (_kr_initializationCompleter != null && - !_kr_initializationCompleter!.isCompleted) { - try { - await _kr_initializationCompleter!.future.timeout( - const Duration(milliseconds: 500), - onTimeout: () { - if (!_kr_initializationCompleter!.isCompleted) { - _kr_initializationCompleter!.complete(); - } - }, - ); - } catch (e) { - // 忽略超时错误 - } - } - - if (kr_isInitialized.value || kr_isLoading.value) { - crispController = null; - kr_isInitialized.value = false; - kr_isLoading.value = false; - - if (kDebugMode) { - print('[P15-Desktop] Crisp WebView 资源已清理'); - } - } - } catch (e) { - if (kDebugMode) { - print('[P15-Desktop] 清理资源时出错: $e'); - } - } - } } diff --git a/lib/app/modules/kr_crisp_chat/views/kr_crisp_view.dart b/lib/app/modules/kr_crisp_chat/views/kr_crisp_view.dart index a6c1081..8bff128 100755 --- a/lib/app/modules/kr_crisp_chat/views/kr_crisp_view.dart +++ b/lib/app/modules/kr_crisp_chat/views/kr_crisp_view.dart @@ -8,12 +8,9 @@ import 'package:kaer_with_panels/app/localization/app_translations.dart'; import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart'; import '../../../widgets/kr_simple_loading.dart'; -// 桌面平台使用 WebView SDK -import 'package:crisp_sdk/crisp_sdk.dart' as webview_crisp; - /// 🔧 P15 重构: Crisp 客服聊天视图 /// - 移动平台 (Android/iOS): 打开原生聊天界面后自动返回 -/// - 桌面平台 (macOS/Windows): 在页面内嵌入 WebView +/// - 桌面平台 (macOS/Windows/Linux): 直接跳转外部浏览器,不进入此页面 class KRCrispView extends GetView { const KRCrispView({Key? key}) : super(key: key); @@ -58,30 +55,11 @@ class KRCrispView extends GetView { return Container( color: Theme.of(context).scaffoldBackgroundColor, child: Obx(() { - // ========== 移动平台 ========== - if (_isMobilePlatform) { - if (!controller.kr_isInitialized.value) { - return _kr_buildErrorView(context); - } - // 显示加载中界面,同时原生聊天界面在后台启动 - return _kr_buildLoadingView(context, '正在加载客服'); + if (!controller.kr_isInitialized.value) { + return _kr_buildErrorView(context); } - - // ========== 桌面平台 ========== - if (controller.kr_isLoading.value) { - return _kr_buildLoadingView(context, '正在初始化客服系统'); - } - - if (controller.kr_isInitialized.value && controller.crispController != null) { - // 桌面平台:嵌入 WebView - return webview_crisp.CrispView( - crispController: controller.crispController!, - clearCache: true, - onSessionIdReceived: _kr_onSessionIdReceived, - ); - } - - return _kr_buildErrorView(context); + // 显示加载中界面,同时原生聊天界面在后台启动 + return _kr_buildLoadingView(context, '正在加载客服'); }), ); } @@ -158,7 +136,7 @@ class KRCrispView extends GetView { if (_isMobilePlatform) { _kr_openNativeCrispChat(context); } else { - controller.kr_initializeDesktopCrisp(); + Get.back(); // 桌面端不应进入此页面,直接返回 } }, child: Text('common.retry'.tr), @@ -168,8 +146,4 @@ class KRCrispView extends GetView { ); } - /// 处理会话 ID 接收事件 (桌面平台) - void _kr_onSessionIdReceived(String sessionId) { - debugPrint('[P15-Desktop] Crisp 会话 ID: $sessionId'); - } } diff --git a/lib/app/utils/kr_common_util.dart b/lib/app/utils/kr_common_util.dart index 7f2caea..bfc6ced 100755 --- a/lib/app/utils/kr_common_util.dart +++ b/lib/app/utils/kr_common_util.dart @@ -14,7 +14,8 @@ class KRCommonUtil { /// 预热客服(提前初始化控制器) static void kr_warmUpCustomerService() { - if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS) { + // 桌面端全部使用外部浏览器打开,无需预热 + if (Platform.isAndroid || Platform.isIOS) { if (!Get.isRegistered()) { Get.put(KRCrispController(), permanent: true); debugPrint('客服系统预热中(持久模式)...'); @@ -38,8 +39,8 @@ class KRCommonUtil { return; } - // 🔧 Windows 端直接跳转外部浏览器 - if (Platform.isWindows) { + // 🔧 桌面端(Windows/macOS/Linux)直接跳转外部浏览器 + if (Platform.isWindows || Platform.isMacOS || Platform.isLinux) { _kr_isOpeningCustomerService = true; // 显示加载提示 @@ -96,15 +97,6 @@ class KRCommonUtil { return; } - // macOS/桌面平台:跳转内置页面 (WebView 实现) - _kr_isOpeningCustomerService = true; - - Get.toNamed(Routes.KR_CRISP); - - // 延迟重置状态 - Future.delayed(const Duration(seconds: 2), () { - _kr_isOpeningCustomerService = false; - }); } /// 提示 meesage: 提示内容, toastPosition: 提示显示的位置, timeout: 显示时间(毫秒) diff --git a/pubspec.yaml b/pubspec.yaml index 49ce515..ff2aba6 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -74,7 +74,6 @@ dependencies: url_launcher: ^6.3.1 flutter_inappwebview: ^6.1.5 # 最新稳定版本 crisp_chat: ^2.4.3 # 🔧 P15: 移动平台使用原生 SDK,解决 WebView 黑屏问题 - crisp_sdk: ^1.1.0 # 🔧 P15: 桌面平台继续使用 WebView 实现 protocol_handler_windows: ^0.2.0 share_plus: ^7.2.2