Browse Source

fix 17858: 【体检系统】切换至体检系统无法正常工作的网络(非体检系统wifi,IDS-WIFI-5G),网络连接标识仍为可用状态

Melon 1 year ago
parent
commit
a3cb4bbad4

+ 13 - 0
lib/pages/admin/view.dart

@@ -4,6 +4,7 @@ import 'package:vitalapp/architecture/app_parameters.dart';
 import 'package:vitalapp/architecture/utils/prompt_box.dart';
 import 'package:vitalapp/components/appbar.dart';
 import 'package:vitalapp/rpc.dart';
+import 'package:wifi_iot/wifi_iot.dart';
 
 import 'blank_door.dart';
 import 'controller.dart';
@@ -41,6 +42,18 @@ class AdminPage extends GetView<AdminController> {
         padding: const EdgeInsets.symmetric(horizontal: 40),
         children: [
           const Text("欢迎补充", style: TextStyle(fontSize: 26)),
+          SizedBox(
+            height: 40,
+            child: FutureBuilder(
+              builder: (context, snapshot) {
+                if (snapshot.hasData) {
+                  return Text("WIFI: ${snapshot.data ?? "Unknow"}");
+                }
+                return Text("WIFI: Loading...");
+              },
+              future: WiFiForIoTPlugin.getSSID(),
+            ),
+          ),
           const SizedBox(height: 8),
           _buildIsLocalStation(),
           const SizedBox(height: 8),

+ 174 - 35
lib/pages/home/widgets/status_bar.dart

@@ -1,11 +1,16 @@
 import 'dart:async';
 
+import 'package:connectivity_plus/connectivity_plus.dart';
+import 'package:fis_common/http/options.dart';
+import 'package:fis_jsonrpc/http_pool.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:vitalapp/architecture/network_connectivity.dart';
 import 'package:vitalapp/global.dart';
 import 'package:vitalapp/pages/help/help_dialog.dart';
 import 'package:fis_common/logger/logger.dart';
+import 'package:vitalapp/rpc.dart';
+import 'package:wifi_iot/wifi_iot.dart';
 
 class HeaderStatusBar extends StatelessWidget {
   const HeaderStatusBar({super.key});
@@ -39,6 +44,7 @@ class _NetStatusWidget extends StatefulWidget {
 class _NetStatusWidgetState extends State<_NetStatusWidget> {
   Timer? _waitTimer;
   bool _isOnline = false;
+  bool _isServerConnectable = true;
 
   @override
   void initState() {
@@ -46,6 +52,9 @@ class _NetStatusWidgetState extends State<_NetStatusWidget> {
     _isOnline = kIsOnline;
     WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
       netChecker.onlineChangedEvent.addListener(_onlineChanged);
+      if (_isOnline) {
+        _checkServerConnectable();
+      }
     });
   }
 
@@ -55,18 +64,76 @@ class _NetStatusWidgetState extends State<_NetStatusWidget> {
     super.dispose();
   }
 
-  void _onlineChanged(_, e) {
-    if (_isOnline == e) {
-      return;
-    }
-    setState(() {
-      _isOnline = e;
-      if (e) {
-        _stopWaitNetRecover();
+  @override
+  Widget build(BuildContext context) {
+    return Tooltip(
+      triggerMode: TooltipTriggerMode.tap,
+      message: _buildTipsText(),
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: [
+          _buildIcon(),
+          _buildWifiName(),
+        ],
+      ),
+    );
+  }
+
+  String _buildTipsText() {
+    if (_isOnline) {
+      if (_isServerConnectable) {
+        return "网络已连接";
       } else {
-        _waitNetRecover();
+        return "无法连接服务器";
       }
-    });
+    } else {
+      if (_waitTimer == null) {
+        return "网络已断开";
+      } else {
+        return "网络等待中";
+      }
+    }
+  }
+
+  Widget _buildIcon() {
+    if (_isOnline) {
+      if (!_isServerConnectable) {
+        return Icon(Icons.wifi_off_outlined, size: 36, color: Colors.red);
+      }
+      if (netChecker.status == ConnectivityResult.wifi) {
+        return Icon(Icons.wifi, size: 36, color: Colors.green);
+      } else if (netChecker.status == ConnectivityResult.mobile) {
+        return _NetworkIcon4G();
+      }
+    }
+
+    if (_waitTimer == null) {
+      return Icon(Icons.wifi_off_outlined, size: 36, color: Colors.red);
+    } else {
+      return SizedBox(width: 36, height: 36, child: _NetWaitingWidget());
+    }
+  }
+
+  Widget _buildWifiName() {
+    if (netChecker.status != ConnectivityResult.wifi) {
+      return const SizedBox();
+    }
+    return _WifiNameWidget();
+  }
+
+  void _onlineChanged(_, e) {
+    if (_isOnline != e) {
+      setState(() {
+        _isOnline = e;
+      });
+    }
+
+    if (e) {
+      _stopWaitNetRecover();
+      _checkServerConnectable();
+    } else {
+      _waitNetRecover();
+    }
   }
 
   void _waitNetRecover() {
@@ -94,33 +161,34 @@ class _NetStatusWidgetState extends State<_NetStatusWidget> {
     }
   }
 
-  @override
-  Widget build(BuildContext context) {
-    if (_isOnline) {
-      return const Tooltip(
-        triggerMode: TooltipTriggerMode.tap,
-        message: "网络已连接",
-        child: Icon(Icons.wifi, size: 36, color: Colors.green),
+  Future<void> _checkServerConnectable() async {
+    final result = await _tryConnectRpcOnce();
+    setState(() {
+      _isServerConnectable = result;
+    });
+  }
+
+  /// 检验服务有效性
+  Future<bool> _tryConnectRpcOnce() async {
+    print("${netChecker.status} _tryConnectRpcOnce: ${DateTime.now()}");
+    try {
+      final reqJson =
+          '{"jsonrpc":"2.0","method":"VerifyAccountAsync","params":[{"UserName": "abc123"}],"id":1}';
+      var response = await jrpcHttpPool.getClient(
+        rpc.currentHostAddress,
+        // timeout: 1000, // 设置了但没生效
+        headers: {'content-type': "text/plain"},
+      ).post(
+        '/IVitalLoginService',
+        data: reqJson,
+        options: FHttpScopedOptions(timeout: 1000),
       );
-    } else {
-      if (_waitTimer == null) {
-        return const Tooltip(
-          triggerMode: TooltipTriggerMode.tap,
-          message: "网络已断开",
-          child: Icon(Icons.wifi_off_outlined, size: 36, color: Colors.red),
-        );
-      } else {
-        return Tooltip(
-          triggerMode: TooltipTriggerMode.tap,
-          message: "网络等待中",
-          child: SizedBox(
-            width: 36,
-            height: 36,
-            child: _NetWaitingWidget(),
-          ),
-        );
-      }
+      print(response);
+      return true;
+    } catch (e) {
+      print("Http unknown error:${e}");
     }
+    return false;
   }
 }
 
@@ -175,3 +243,74 @@ class _NetWaitingWidgetState extends State<_NetWaitingWidget> {
     );
   }
 }
+
+class _NetworkIcon4G extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return Expanded(
+      child: Column(
+        children: [
+          Transform.translate(
+            offset: Offset(-4, 10),
+            child: Text(
+              "4G",
+              style: TextStyle(
+                fontSize: 18,
+                color: Colors.white,
+              ),
+            ),
+          ),
+          Transform.translate(
+            offset: Offset(0, -6),
+            child: Transform.scale(
+              scaleX: 1.2,
+              child: Icon(
+                Icons.signal_cellular_alt_rounded,
+                size: 36,
+                color: Colors.green,
+              ),
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class _WifiNameWidget extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return FutureBuilder(
+      builder: (context, snapshot) {
+        if (snapshot.hasData &&
+            snapshot.data != null &&
+            snapshot.data!.isNotEmpty) {
+          return Container(
+            constraints: BoxConstraints(maxWidth: 120),
+            child: Text(
+              _breakWord(snapshot.data!),
+              style: TextStyle(
+                fontSize: 16,
+                color: Colors.white,
+              ),
+              overflow: TextOverflow.ellipsis,
+            ),
+          );
+        }
+        return const SizedBox();
+      },
+      future: WiFiForIoTPlugin.getSSID(),
+    );
+  }
+
+  /// 插入零宽空格
+  static String _breakWord(String word) {
+    if (word.isEmpty) return word;
+    String breakWord = ' ';
+    for (var element in word.runes) {
+      breakWord += String.fromCharCode(element);
+      breakWord += '\u200B';
+    }
+    return breakWord;
+  }
+}

+ 4 - 2
lib/pages/settings/server/controller.dart

@@ -1,3 +1,4 @@
+import 'package:fis_common/http/options.dart';
 import 'package:fis_jsonrpc/http_pool.dart';
 import 'package:flutter/foundation.dart';
 import 'package:get/get.dart';
@@ -160,12 +161,13 @@ class ServerSettingController extends FControllerBase {
     try {
       var response = await jrpcHttpPool.getClient(
         host,
-        timeout: 3000,
+        // timeout: 3000, // 设置了但没生效
         headers: {'content-type': "text/plain"},
       ).post(
         '/IVitalLoginService',
         data:
-            '{"jsonrpc":"2.0","method":"CommonLoginAsync","params":["AnyAccount": "abc123","AnyCode": "","Platform": 1,"LoginSource": 1,"Password": "fb6414d24e3c347d46032b0496f1c4e4"],"id":1}',
+            '{"jsonrpc":"2.0","method":"CommonLoginAsync","params":[{"AnyAccount":"test","Password":"Symmetry_mk9xah8N","LoginSource":2}],"id":1}',
+        options: FHttpScopedOptions(timeout: 3000),
       );
       if (response.data != null) {
         print(response.data);

+ 8 - 0
pubspec.lock

@@ -1620,6 +1620,14 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "0.2.1"
+  wifi_iot:
+    dependency: "direct main"
+    description:
+      name: wifi_iot
+      sha256: "27a9b77ea589f089f94a65c937bcb8e2910e6cf9190583e117b76b8a8d592c03"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.3.19"
   win32:
     dependency: transitive
     description:

+ 1 - 0
pubspec.yaml

@@ -133,6 +133,7 @@ dependencies:
   barcode: ^2.2.6
   barcode_image: ^2.0.2
   barcode_finder: ^0.0.5
+  wifi_iot: ^0.3.19
   # camera_android_camerax: ^0.5.0+22
 
 # 需要覆盖版本号的依赖