customer_service_webview.dart 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import 'package:flutter/material.dart';
  2. import 'package:webview_flutter/webview_flutter.dart';
  3. import '../../../core/config/app_config.dart';
  4. import '../../../core/l10n/app_localizations.dart';
  5. /// 七陌 H5 客服 WebView 页面
  6. class CustomerServiceWebView extends StatefulWidget {
  7. final String userId;
  8. final String userName;
  9. const CustomerServiceWebView({
  10. Key? key,
  11. required this.userId,
  12. required this.userName,
  13. }) : super(key: key);
  14. @override
  15. State<CustomerServiceWebView> createState() => _CustomerServiceWebViewState();
  16. }
  17. class _CustomerServiceWebViewState extends State<CustomerServiceWebView> {
  18. late WebViewController _webViewController;
  19. @override
  20. void initState() {
  21. super.initState();
  22. _initializeWebViewController();
  23. }
  24. void _initializeWebViewController() {
  25. _webViewController = WebViewController()
  26. ..setJavaScriptMode(JavaScriptMode.unrestricted)
  27. ..addJavaScriptChannel(
  28. 'flutterChannel',
  29. onMessageReceived: (JavaScriptMessage message) {
  30. _handleJavaScriptMessage(message.message);
  31. },
  32. )
  33. ..setNavigationDelegate(
  34. NavigationDelegate(
  35. onPageFinished: (_) {
  36. // 页面加载完成,注入JS接口
  37. _injectJavaScriptInterface();
  38. },
  39. ),
  40. )
  41. // 加载部署在自有服务器上的 HTML,通过 URL 参数传递用户信息
  42. // 该 HTML 处理七陌 SDK 初始化,避免跨域问题
  43. ..loadRequest(
  44. Uri.parse(
  45. '${AppConfig.customerServiceHost}${AppConfig.customerServiceChatPath}'
  46. '?userId=${Uri.encodeComponent(widget.userId)}'
  47. '&userName=${Uri.encodeComponent(widget.userName)}',
  48. ),
  49. );
  50. }
  51. /// 注入JavaScript接口供HTML调用
  52. void _injectJavaScriptInterface() {
  53. _webViewController.runJavaScript(
  54. '''
  55. window.flutterChannel = {
  56. postMessage: function(message) {
  57. flutterChannel.postMessage(message);
  58. }
  59. };
  60. '''
  61. );
  62. }
  63. /// 处理来自JavaScript的消息
  64. void _handleJavaScriptMessage(String message) {
  65. if (message == 'close' && mounted) {
  66. Navigator.of(context).pop();
  67. }
  68. }
  69. @override
  70. Widget build(BuildContext context) {
  71. return Container(
  72. decoration: BoxDecoration(
  73. color: Colors.white,
  74. borderRadius: const BorderRadius.only(
  75. topLeft: Radius.circular(16),
  76. topRight: Radius.circular(16),
  77. ),
  78. ),
  79. child: Column(
  80. children: [
  81. // 顶部栏:退出按钮(左)+ 拖拽指示条(中)
  82. SizedBox(
  83. height: 48,
  84. width: double.infinity,
  85. child: Stack(
  86. children: [
  87. // 拖拽指示条居中
  88. Center(
  89. child: Container(
  90. width: 36,
  91. height: 4,
  92. decoration: BoxDecoration(
  93. color: Colors.grey.withAlpha(80),
  94. borderRadius: BorderRadius.circular(2),
  95. ),
  96. ),
  97. ),
  98. // 退出按钮左对齐
  99. Align(
  100. alignment: Alignment.centerLeft,
  101. child: TextButton(
  102. onPressed: () => Navigator.of(context).pop(),
  103. child: Text(
  104. AppLocalizations.of(context)!.customerServiceLeave,
  105. style: const TextStyle(color: Colors.grey, fontSize: 15),
  106. ),
  107. ),
  108. ),
  109. ],
  110. ),
  111. ),
  112. // WebView 内容区
  113. Expanded(
  114. child: WebViewWidget(controller: _webViewController),
  115. ),
  116. ],
  117. ),
  118. );
  119. }
  120. }