import 'package:get/get.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:flutter/foundation.dart' show kIsWeb; import 'dart:io' show Platform; import 'package:kaer_with_panels/app/services/api_service/api.dart'; import 'package:kaer_with_panels/app/services/api_service/kr_web_api.dart'; import 'package:kaer_with_panels/app/localization/app_translations.dart'; import 'package:kaer_with_panels/app/utils/kr_log_util.dart'; /// WebView 控制器 /// 用于管理 WebView 的状态和行为 class KRWebViewController extends GetxController { // 页面加载状态 final RxBool kr_isLoading = true.obs; // 页面标题 final RxString kr_title = ''.obs; // WebView 控制器 late final WebViewController kr_webViewController; // 默认URL static const String kr_defaultUrl = ''; final String kr_url = Get.arguments['url'] as String; // Web API 实例 final KRWebApi _kr_webApi = KRWebApi(); // 内容类型 final RxBool kr_isHtml = false.obs; final RxBool kr_isMarkdown = false.obs; final RxString kr_content = ''.obs; @override void onInit() { super.onInit(); // 根据 URL 类型决定初始化方式 if (kr_url.contains(Api.kr_getSiteTos) || kr_url.contains(Api.kr_getSitePrivacy)) { // 用户协议和隐私政策页面,直接获取文本内容 if (kr_url.contains(Api.kr_getSiteTos)) { kr_title.value = AppTranslations.kr_login.termsOfService; } else { kr_title.value = AppTranslations.kr_login.privacyPolicy; } kr_getWebText(); } else { // 其他页面,初始化 WebView kr_initWebView(); } } /// 初始化 WebView void kr_initWebView() { kr_webViewController = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setNavigationDelegate( NavigationDelegate( onNavigationRequest: (NavigationRequest request) async { // 只在移动平台处理支付应用跳转 if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) { KRLogUtil.kr_i('处理支付链接: ${request.url}', tag: 'WebViewController'); // 处理支付链接 if (await kr_handleUrlLaunch(request.url)) { return NavigationDecision.prevent; } } return NavigationDecision.navigate; }, onPageStarted: kr_handlePageStarted, onPageFinished: kr_handlePageFinished, ), ); // 检查是否是用户协议或隐私政策 if (kr_url.contains(Api.kr_getSiteTos) || kr_url.contains(Api.kr_getSitePrivacy)) { kr_getWebText(); } else { kr_webViewController.loadRequest(Uri.parse(kr_url)); } } /// 获取网页文本内容并加载到 WebView Future kr_getWebText() async { try { final response = await _kr_webApi.kr_getWebText(kr_url); response.fold( (error) async { KRLogUtil.kr_e('获取网页内容失败: $error', tag: 'WebViewController'); // 如果获取失败,直接设置错误内容 kr_content.value = 'Failed to load, please try again later'; kr_isLoading.value = false; }, (content) async { KRLogUtil.kr_i('获取到内容: $content', tag: 'WebViewController'); // 判断内容类型,优先判断 Markdown kr_isMarkdown.value = content.contains('**') || content.contains('*') || content.contains('#') || content.contains('- ') || content.contains('['); kr_isHtml.value = !kr_isMarkdown.value && content.contains('<') && content.contains('>'); KRLogUtil.kr_i('内容类型 - Markdown: ${kr_isMarkdown.value}, HTML: ${kr_isHtml.value}', tag: 'WebViewController'); if (kr_isMarkdown.value) { // 如果是 Markdown 内容,直接使用 kr_content.value = content; } else if (kr_isHtml.value) { // 如果是 HTML 内容,直接使用 kr_content.value = content; } else { // 如果是普通文本,直接使用 kr_content.value = content; } kr_isLoading.value = false; }, ); } catch (e) { KRLogUtil.kr_e('获取网页内容出错: $e', tag: 'WebViewController'); kr_content.value = 'Loading error, please try again later'; kr_isLoading.value = false; } } /// 处理页面开始加载事件 void kr_handlePageStarted(String url) { kr_isLoading.value = true; } /// 处理页面加载完成事件 void kr_handlePageFinished(String url) async { kr_isLoading.value = false; await kr_updateTitle(); } /// 更新页面标题 Future kr_updateTitle() async { final String? kr_pageTitle = await kr_webViewController.getTitle(); kr_title.value = kr_pageTitle ?? ''; } /// 重新加载页面 Future kr_reloadPage() async { await kr_webViewController.reload(); } /// 加载新的URL Future kr_loadUrl(String url) async { await kr_webViewController.loadRequest(Uri.parse(url)); } /// 处理URL启动 Future kr_handleUrlLaunch(String url) async { try { KRLogUtil.kr_i('正在处理URL跳转: $url', tag: 'WebViewController'); final uri = Uri.parse(url); // 处理支付应用和外部链接 if (uri.scheme == 'alipays' || uri.scheme == 'alipay' || uri.scheme == 'weixin' || uri.scheme == 'wx') { KRLogUtil.kr_i('检测到支付应用scheme: ${uri.scheme}', tag: 'WebViewController'); // 尝试打开支付应用 if (await canLaunchUrl(uri)) { return await launchUrl( uri, mode: LaunchMode.externalApplication, ); } // 如果支付应用无法打开,尝试使用外部浏览器打开 final httpUri = Uri.parse('https://${uri.host}${uri.path}?${uri.query}'); KRLogUtil.kr_i('尝试使用浏览器打开: $httpUri', tag: 'WebViewController'); if (await canLaunchUrl(httpUri)) { return await launchUrl( httpUri, mode: LaunchMode.externalApplication, ); } KRLogUtil.kr_e('无法启动URL: $url', tag: 'WebViewController'); } return false; } catch (e) { KRLogUtil.kr_e('URL跳转错误: $e', tag: 'WebViewController'); return false; } } }