浏览代码

device的列表
Target 35 升级与适配

liukai 1 周之前
父节点
当前提交
dc51a1880c
共有 26 个文件被更改,包括 379 次插入233 次删除
  1. 9 12
      app/android/app/build.gradle
  2. 4 0
      app/android/app/src/main/res/values-night/styles.xml
  3. 4 0
      app/android/app/src/main/res/values/styles.xml
  4. 3 0
      app/android/build.gradle
  5. 1 1
      app/android/gradle/wrapper/gradle-wrapper.properties
  6. 7 2
      app/android/settings.gradle
  7. 1 1
      app/lib/main.dart
  8. 29 29
      packages/cpt_auth/lib/modules/select_country/select_country_page.dart
  9. 28 6
      packages/cpt_uk/lib/modules/attendance/device_list/device_list_controller.dart
  10. 34 13
      packages/cpt_uk/lib/modules/attendance/device_list/device_list_item.dart
  11. 1 1
      packages/cpt_uk/lib/modules/attendance/device_list/device_list_page.dart
  12. 9 0
      packages/cpt_uk/lib/modules/attendance/device_list/device_list_state.dart
  13. 1 1
      packages/cpt_uk/lib/modules/main/main_controller.dart
  14. 1 1
      packages/cpt_uk/lib/modules/main/main_page.dart
  15. 1 1
      packages/cpt_uk/lib/modules/main/main_state.dart
  16. 8 0
      packages/cs_domain/lib/entity/response/device_list_entity.dart
  17. 29 1
      packages/cs_domain/lib/generated/json/device_list_entity.g.dart
  18. 9 0
      packages/cs_domain/lib/repository/other_repository.dart
  19. 1 1
      packages/cs_initializer/lib/app_initializer.dart
  20. 45 5
      packages/cs_plugin_basic/lib/modules/global_web_page.dart
  21. 144 153
      packages/cs_plugin_basic/lib/widget/webview_page.dart
  22. 1 1
      packages/cs_plugin_basic/pubspec.yaml
  23. 2 0
      packages/cs_resources/lib/local/language/en_US.dart
  24. 2 0
      packages/cs_resources/lib/local/language/zh_CN.dart
  25. 4 3
      packages/cs_resources/lib/local/theme/theme_config.dart
  26. 1 1
      packages/cs_widgets/pubspec.yaml

+ 9 - 12
app/android/app/build.gradle

@@ -24,19 +24,18 @@ if (flutterRoot == null) {
     throw new Exception("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
 }
 
-// 模拟器运行报错时尝试开启此项
-// project.setProperty('target-platform', 'android-arm')
 
 android {
-    compileSdkVersion 34
+    namespace 'com.guadou.yyemployer'
+    compileSdk 35
 
     compileOptions {
-        sourceCompatibility JavaVersion.VERSION_11
-        targetCompatibility JavaVersion.VERSION_11
+        sourceCompatibility JavaVersion.VERSION_17
+        targetCompatibility JavaVersion.VERSION_17
     }
 
     kotlinOptions {
-        jvmTarget = JavaVersion.VERSION_11
+        jvmTarget = JavaVersion.VERSION_17
     }
 
     sourceSets {
@@ -51,7 +50,7 @@ android {
     defaultConfig {
         applicationId "com.guadou.yyemployer"
         minSdkVersion 21
-        targetSdkVersion 34
+        targetSdkVersion 35
         versionCode 305
         versionName "3.0.5"
 
@@ -91,8 +90,6 @@ android {
             signingConfig signingConfigs.release
             //默认系统混淆
             minifyEnabled true
-            // 不显示Log
-            buildConfigField "boolean", "LOG_DEBUG", "false"
             //是否可调试
             debuggable false
             //Zipalign优化
@@ -114,13 +111,13 @@ flutter {
 }
 
 dependencies {
-    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0"
-    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0"
+    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0"
+    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0"
 
     implementation 'com.github.bumptech.glide:glide:4.11.0'
     kapt 'com.github.bumptech.glide:compiler:4.11.0'
 
-    implementation 'androidx.appcompat:appcompat:1.3.1'  //加入AndroidX依赖
+    implementation 'androidx.appcompat:appcompat:1.6.1'  //加入AndroidX依赖
     implementation 'com.android.support:multidex:1.0.3'
 //    implementation 'androidx.core:core-splashscreen:1.0.0' //启动12兼容
 }

+ 4 - 0
app/android/app/src/main/res/values-night/styles.xml

@@ -5,6 +5,8 @@
         <!-- Show a splash screen on the activity. Automatically removed when
              Flutter draws its first frame -->
         <item name="android:windowBackground">@drawable/launch_background</item>
+        <item name="android:windowTranslucentNavigation">false</item>
+        <item name="android:windowTranslucentStatus">false</item>
     </style>
     <!-- Theme applied to the Android Window as soon as the process has started.
          This theme determines the color of the Android Window while your
@@ -14,6 +16,8 @@
          This Theme is only used starting with V2 of Flutter's Android embedding. -->
     <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
         <item name="android:windowBackground">?android:colorBackground</item>
+        <item name="android:windowTranslucentNavigation">false</item>
+        <item name="android:windowTranslucentStatus">false</item>
     </style>
 
 

+ 4 - 0
app/android/app/src/main/res/values/styles.xml

@@ -5,6 +5,8 @@
         <!-- Show a splash screen on the activity. Automatically removed when
              Flutter draws its first frame -->
         <item name="android:windowBackground">@drawable/launch_background</item>
+        <item name="android:windowTranslucentNavigation">false</item>
+        <item name="android:windowTranslucentStatus">false</item>
     </style>
     <!-- Theme applied to the Android Window as soon as the process has started.
          This theme determines the color of the Android Window while your
@@ -14,6 +16,8 @@
          This Theme is only used starting with V2 of Flutter's Android embedding. -->
     <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
         <item name="android:windowBackground">?android:colorBackground</item>
+        <item name="android:windowTranslucentNavigation">false</item>
+        <item name="android:windowTranslucentStatus">false</item>
     </style>
 
 </resources>

+ 3 - 0
app/android/build.gradle

@@ -1,5 +1,8 @@
 allprojects {
     repositories {
+        maven { url 'https://maven.aliyun.com/repository/google' }
+        maven { url 'https://maven.aliyun.com/repository/central' }
+        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
         google()
         mavenCentral()
     }

+ 1 - 1
app/android/gradle/wrapper/gradle-wrapper.properties

@@ -1,6 +1,6 @@
 #Sun Jan 24 20:08:12 CST 2021
 distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
 distributionPath=wrapper/dists
 zipStorePath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME

+ 7 - 2
app/android/settings.gradle

@@ -10,6 +10,11 @@ pluginManagement {
     includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
 
     repositories {
+        maven { url 'https://maven.aliyun.com/repository/google' }
+        maven { url 'https://maven.aliyun.com/repository/central' }
+        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
+        maven { url 'https://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
+        maven { url 'https://jitpack.io' }
         google()
         mavenCentral()
         gradlePluginPortal()
@@ -18,8 +23,8 @@ pluginManagement {
 
 plugins {
     id "dev.flutter.flutter-plugin-loader" version "1.0.0"
-    id "com.android.application" version "7.1.2" apply false
-    id "org.jetbrains.kotlin.android" version "1.8.0" apply false
+    id "com.android.application" version "8.7.3" apply false
+    id "org.jetbrains.kotlin.android" version "1.9.0" apply false
 }
 
 include ":app"

+ 1 - 1
app/lib/main.dart

@@ -127,7 +127,7 @@ class MyApp extends StatelessWidget {
           title: 'YY Employer',
           //样式相关
           theme: ThemeConfig.lightTheme,
-          darkTheme: ThemeConfig.darkTheme,
+          // darkTheme: ThemeConfig.darkTheme,
           themeMode: ThemeMode.light,
           //本地化相关
           locale: TranslationService.locale,

+ 29 - 29
packages/cpt_auth/lib/modules/select_country/select_country_page.dart

@@ -124,35 +124,35 @@ class SelectCountryPage extends BaseStatelessPage<SelectCountryController> {
                       }),
 
                       //英国的选项
-                      // Container(
-                      //   width: double.infinity,
-                      //   margin: const EdgeInsets.only(top: 13.5, left: 20, right: 20),
-                      //   padding: const EdgeInsets.symmetric(vertical: 13, horizontal: 17),
-                      //   decoration: BoxDecoration(
-                      //     color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
-                      //     borderRadius: BorderRadius.circular(5.0), // 设置圆角
-                      //   ),
-                      //   child: Row(
-                      //     children: [
-                      //       const MyAssetImage(Assets.cptAuthUkIcon, width: 50, height: 33),
-                      //       MyTextView(
-                      //         "United Kingdom".tr,
-                      //         marginLeft: 17,
-                      //         textColor: ColorConstants.white,
-                      //         isFontMedium: true,
-                      //         fontSize: 18,
-                      //       ).expanded(),
-                      //       Obx(() {
-                      //         return Visibility(
-                      //           visible: ConfigService.to.selectCountry.value == 2,
-                      //           child: const MyAssetImage(Assets.cptAuthCheckedIcon, width: 22, height: 22),
-                      //         );
-                      //       }),
-                      //     ],
-                      //   ),
-                      // ).onTap(() {
-                      //   ConfigService.to.selectCountry.value = 2;
-                      // }),
+                      Container(
+                        width: double.infinity,
+                        margin: const EdgeInsets.only(top: 13.5, left: 20, right: 20),
+                        padding: const EdgeInsets.symmetric(vertical: 13, horizontal: 17),
+                        decoration: BoxDecoration(
+                          color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+                          borderRadius: BorderRadius.circular(5.0), // 设置圆角
+                        ),
+                        child: Row(
+                          children: [
+                            const MyAssetImage(Assets.cptAuthUkIcon, width: 50, height: 33),
+                            MyTextView(
+                              "United Kingdom".tr,
+                              marginLeft: 17,
+                              textColor: ColorConstants.white,
+                              isFontMedium: true,
+                              fontSize: 18,
+                            ).expanded(),
+                            Obx(() {
+                              return Visibility(
+                                visible: ConfigService.to.selectCountry.value == 2,
+                                child: const MyAssetImage(Assets.cptAuthCheckedIcon, width: 22, height: 22),
+                              );
+                            }),
+                          ],
+                        ),
+                      ).onTap(() {
+                        ConfigService.to.selectCountry.value = 2;
+                      }),
 
                       //越南
                       // Container(

+ 28 - 6
packages/cpt_uk/lib/modules/attendance/device_list/device_list_controller.dart

@@ -4,11 +4,12 @@ import 'package:get/get.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/picker/option_pick_util.dart';
 import 'package:widgets/widget_export.dart';
 
 import 'device_list_state.dart';
 
-class DeviceListController extends GetxController with DioCancelableMixin{
+class DeviceListController extends GetxController with DioCancelableMixin {
   final OtherRepository _otherRepository = Get.find();
   final DeviceListState state = DeviceListState();
 
@@ -59,6 +60,8 @@ class DeviceListController extends GetxController with DioCancelableMixin{
     // 获取 Applied 列表
     var listResult = await _otherRepository.fetchDeviceList(
       curPage: _curPage,
+      deviceName: state.keyword,
+      isOnline: state.selectedOnlineStatusId,
       cancelToken: cancelToken,
     );
 
@@ -109,7 +112,6 @@ class DeviceListController extends GetxController with DioCancelableMixin{
   void onReady() {
     super.onReady();
     fetchDeviceList();
-
   }
 
   @override
@@ -120,13 +122,33 @@ class DeviceListController extends GetxController with DioCancelableMixin{
 
   /// 执行搜索
   void doSearch() {
-   String? deviceName = state.searchController.text;
-   ToastEngine.show('执行搜索:$deviceName');
+    String? deviceName = state.searchController.text;
+    state.keyword = deviceName;
+    refreshController.callRefresh();
   }
 
   /// Pick 在线状态
   void pickOnLineStatus() {
-    ToastEngine.show('Pick 在线状态');
-  }
+    int selectedStatusIndex;
+    if (state.selectedOnlineStatusId == null) {
+      selectedStatusIndex = 0;
+    } else {
+      selectedStatusIndex = state.onlineStatusList.indexWhere((entity) => entity.id == state.selectedOnlineStatusId);
+    }
 
+    if (selectedStatusIndex < 0) {
+      selectedStatusIndex = 0;
+    }
+
+    OptionPickerUtil.showCupertinoOptionPicker(
+      items: state.onlineStatusList.map((e) => e.name!).toList(growable: false),
+      initialSelectIndex: selectedStatusIndex,
+      onPickerChanged: (_, index) {
+        state.selectedOnlineStatusId = state.onlineStatusList[index].id;
+        state.selectedOnlineStatusName = state.onlineStatusList[index].name;
+        update();
+        refreshController.callRefresh();
+      },
+    );
+  }
 }

+ 34 - 13
packages/cpt_uk/lib/modules/attendance/device_list/device_list_item.dart

@@ -24,10 +24,10 @@ class DeviceListItem extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return Container(
-      padding: EdgeInsets.symmetric(vertical: 24, horizontal: 21),
-      margin: EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 21),
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
       decoration: BoxDecoration(
-        color: Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+        color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
         borderRadius: BorderRadius.circular(5), // 设置圆角
       ),
       child: Column(
@@ -40,15 +40,15 @@ class DeviceListItem extends StatelessWidget {
             crossAxisAlignment: CrossAxisAlignment.center,
             children: [
               MyTextView(
-                "Device MAC:".tr,
+                "Device No:".tr,
                 isFontRegular: true,
                 textColor: ColorConstants.textGrayAECAE5,
                 fontSize: 14,
               ),
 
-              //部门
+              //文本
               MyTextView(
-                item.deviceMac ?? "-",
+                item.deviceNo ?? "-",
                 marginLeft: 5,
                 isFontMedium: true,
                 textColor: Colors.white,
@@ -57,20 +57,20 @@ class DeviceListItem extends StatelessWidget {
             ],
           ),
 
-          // 设备
+          // 设备名
           Row(
             mainAxisSize: MainAxisSize.max,
             crossAxisAlignment: CrossAxisAlignment.center,
             children: [
               MyTextView(
-                "Device Alias:".tr,
+                "Device Name:".tr,
                 isFontRegular: true,
                 textColor: ColorConstants.textGrayAECAE5,
                 fontSize: 14,
               ),
 
               MyTextView(
-                item.deviceAlias ?? "-",
+                item.deviceName ?? "-",
                 marginLeft: 5,
                 isFontRegular: true,
                 textColor: Colors.white,
@@ -79,21 +79,42 @@ class DeviceListItem extends StatelessWidget {
             ],
           ).marginOnly(top: 15),
 
-          // 位置
+          // 设备Mac
           Row(
             mainAxisSize: MainAxisSize.max,
             crossAxisAlignment: CrossAxisAlignment.center,
             children: [
               MyTextView(
-                "Location:".tr,
+                "Device MAC:".tr,
                 isFontRegular: true,
                 textColor: ColorConstants.textGrayAECAE5,
                 fontSize: 14,
               ),
 
+              MyTextView(
+                item.deviceMac ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          // 位置
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Type:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
 
               MyTextView(
-                item.siteTypeShow ?? "",
+                item.siteShow ?? "",
                 marginLeft: 5,
                 isFontRegular: true,
                 textColor: ColorConstants.white,
@@ -116,7 +137,7 @@ class DeviceListItem extends StatelessWidget {
 
               //状态
               MyTextView(
-                item.aliveState == 0 ? "Offline".tr : "Online".tr,
+                item.isOnline == "0" ? "Offline".tr : "Online".tr,
                 marginLeft: 5,
                 isFontRegular: true,
                 textColor:  item.aliveState == 0 ? ColorConstants.textRedFF6262 : ColorConstants.textGreen0AC074,

+ 1 - 1
packages/cpt_uk/lib/modules/attendance/device_list/device_list_page.dart

@@ -55,7 +55,7 @@ class _DeviceListState extends BaseState<UKDeviceListPage, DeviceListController>
   Widget build(BuildContext context) {
     return autoCtlGetBuilder(builder: (controller) {
       return SafeArea(
-        bottom: true,
+        bottom: false,
         top: false,
         child: Container(
           width: double.infinity,

+ 9 - 0
packages/cpt_uk/lib/modules/attendance/device_list/device_list_state.dart

@@ -1,5 +1,7 @@
 import 'package:domain/entity/response/device_list_entity.dart';
+import 'package:domain/entity/response/id_name_entity.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_basic/basic_export.dart';
 
 class DeviceListState {
   List<DeviceListRows> datas = [];
@@ -7,4 +9,11 @@ class DeviceListState {
   String? keyword; //列表数据
   TextEditingController searchController = TextEditingController();
   FocusNode focusNode = FocusNode();
+
+  String? selectedOnlineStatusId; //当前选择的在线状态,1.online;2.offline
+  String? selectedOnlineStatusName; //当前选择的在线状态,1.online;2.offline
+  List<IdNameEntity> onlineStatusList = [
+    IdNameEntity()..name = 'Online'.tr..id = '1',
+    IdNameEntity()..name = 'Offline'.tr..id = '2',
+  ];
 }

+ 1 - 1
packages/cpt_uk/lib/modules/main/main_controller.dart

@@ -127,7 +127,7 @@ class MainController extends GetxController {
       case 'device':
         UKDeviceListPage.startInstance();
         break;
-      case 'security':
+      case 'registration':
         UKSecurityRegistrationPage.startInstance();
         break;
       case 'attendance':

+ 1 - 1
packages/cpt_uk/lib/modules/main/main_page.dart

@@ -98,7 +98,7 @@ class _MainPageState extends BaseState<UKMainPage, MainController> with StateLif
         child: autoCtlGetBuilder(builder: (controller) {
           return Scaffold(
             body: SafeArea(
-              bottom: true,
+              bottom: false,
               top: false,
               //真正的 Content 布局,使用PageView保存状态
               child: Container(

+ 1 - 1
packages/cpt_uk/lib/modules/main/main_state.dart

@@ -10,7 +10,7 @@ class MainState {
   final List<HomeModule> modules = [
     HomeModule(key: 'job', moduleName: 'Jobs'.tr, moduleIconPath: Assets.mainHomeJobList, iconWidth: 45, iconHeight: 45),
     HomeModule(key: 'device', moduleName: 'Devices'.tr, moduleIconPath: Assets.mainHomeDevices, iconWidth: 45.5, iconHeight: 45.5),
-    HomeModule(key: 'security', moduleName: 'Security Registration'.tr, moduleIconPath: Assets.mainHomeSecurity, iconWidth: 58.5, iconHeight: 44.5),
+    HomeModule(key: 'registration', moduleName: 'Security Registration'.tr, moduleIconPath: Assets.mainHomeSecurity, iconWidth: 58.5, iconHeight: 44.5),
     HomeModule(key: 'attendance', moduleName: 'E-Attendance'.tr, moduleIconPath: Assets.mainHomeAttendance, iconWidth: 44.5, iconHeight: 44.5),
     HomeModule(key: 'report', moduleName: 'Report'.tr, moduleIconPath: Assets.mainHomeReport, iconWidth: 50.5, iconHeight: 45.5),
   ];

+ 8 - 0
packages/cs_domain/lib/entity/response/device_list_entity.dart

@@ -41,6 +41,14 @@ class DeviceListRows {
 	String? siteTypeShow = null;
 	@JSONField(name: "created_at")
 	String? createdAt = null;
+	@JSONField(name: "device_name")
+	String? deviceName = null;
+	@JSONField(name: "device_no")
+	String? deviceNo = null;
+	@JSONField(name: "is_online")
+	String? isOnline = null;
+	@JSONField(name: "site_show")
+	String? siteShow = null;
 
 	DeviceListRows();
 

+ 29 - 1
packages/cs_domain/lib/generated/json/device_list_entity.g.dart

@@ -75,6 +75,22 @@ DeviceListRows $DeviceListRowsFromJson(Map<String, dynamic> json) {
   if (createdAt != null) {
     deviceListRows.createdAt = createdAt;
   }
+  final String? deviceName = jsonConvert.convert<String>(json['device_name']);
+  if (deviceName != null) {
+    deviceListRows.deviceName = deviceName;
+  }
+  final String? deviceNo = jsonConvert.convert<String>(json['device_no']);
+  if (deviceNo != null) {
+    deviceListRows.deviceNo = deviceNo;
+  }
+  final String? isOnline = jsonConvert.convert<String>(json['is_online']);
+  if (isOnline != null) {
+    deviceListRows.isOnline = isOnline;
+  }
+  final String? siteShow = jsonConvert.convert<String>(json['site_show']);
+  if (siteShow != null) {
+    deviceListRows.siteShow = siteShow;
+  }
   return deviceListRows;
 }
 
@@ -90,6 +106,10 @@ Map<String, dynamic> $DeviceListRowsToJson(DeviceListRows entity) {
   data['last_online'] = entity.lastOnline;
   data['site_type_show'] = entity.siteTypeShow;
   data['created_at'] = entity.createdAt;
+  data['device_name'] = entity.deviceName;
+  data['device_no'] = entity.deviceNo;
+  data['is_online'] = entity.isOnline;
+  data['site_show'] = entity.siteShow;
   return data;
 }
 
@@ -105,6 +125,10 @@ extension DeviceListRowsExtension on DeviceListRows {
     String? lastOnline,
     String? siteTypeShow,
     String? createdAt,
+    String? deviceName,
+    String? deviceNo,
+    String? isOnline,
+    String? siteShow,
   }) {
     return DeviceListRows()
       ..id = id ?? this.id
@@ -116,6 +140,10 @@ extension DeviceListRowsExtension on DeviceListRows {
       ..aliveState = aliveState ?? this.aliveState
       ..lastOnline = lastOnline ?? this.lastOnline
       ..siteTypeShow = siteTypeShow ?? this.siteTypeShow
-      ..createdAt = createdAt ?? this.createdAt;
+      ..createdAt = createdAt ?? this.createdAt
+      ..deviceName = deviceName ?? this.deviceName
+      ..deviceNo = deviceNo ?? this.deviceNo
+      ..isOnline = isOnline ?? this.isOnline
+      ..siteShow = siteShow ?? this.siteShow;
   }
 }

+ 9 - 0
packages/cs_domain/lib/repository/other_repository.dart

@@ -22,6 +22,8 @@ class OtherRepository extends GetxService {
   // 雇主的设备列表
   Future<HttpResult<DeviceListEntity>> fetchDeviceList({
     required int curPage,
+    String? deviceName,
+    String? isOnline,
     CancelToken? cancelToken,
   }) async {
     //参数
@@ -29,6 +31,13 @@ class OtherRepository extends GetxService {
     params["cur_page"] = curPage.toString();
     params["page_size"] = "10";
 
+    if (Utils.isNotEmpty(deviceName)) {
+      params["device_name"] = deviceName!;
+    }
+    if (Utils.isNotEmpty(isOnline)) {
+      params["is_online"] = isOnline!;
+    }
+
     final result = await httpProvider.requestNetResult(
       ApiConstants.apiDeviceList,
       params: params,

+ 1 - 1
packages/cs_initializer/lib/app_initializer.dart

@@ -107,6 +107,6 @@ class AppInitializer {
     ]);
 
     //处理显示区域
-    SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]);
+    SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
   }
 }

+ 45 - 5
packages/cs_plugin_basic/lib/modules/global_web_page.dart

@@ -3,6 +3,9 @@ import 'package:get/get.dart';
 import 'package:plugin_basic/utils/ext_get_nav.dart';
 import 'package:router/path/router_path.dart';
 import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/screen_util.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/widget_export.dart';
 
 import '../base/base_stateless_page.dart';
 import '../widget/webview_page.dart';
@@ -36,10 +39,47 @@ class GlobalWebPage extends BaseStatelessPage {
     String initialUrl = Get.arguments['initialUrl'];
     String title = Get.arguments['title'];
     Log.d("GlobalWebPage 的参数 isShowAppBar:$isShowAppBar title:$title initialUrl:$initialUrl ");
-    return WebViewPage(
-      showAppbar: isShowAppBar,
-      initialUrl: initialUrl,
-      arguments: {'title': title},
-    );
+
+    if (initialUrl.startsWith('http')) {
+      //网页加载
+      return WebViewPage(
+        showAppbar: isShowAppBar,
+        initialUrl: initialUrl,
+        arguments: {'title': title},
+      );
+    } else {
+      //富文本加载
+      return SafeArea(
+        bottom: true,
+        top: false,
+        child: Container(
+          width: double.infinity,
+          height: double.infinity,
+          padding: EdgeInsets.only(top: ScreenUtil.getStatusBarH(context)),
+          decoration: const BoxDecoration(
+            gradient: LinearGradient(
+              colors: [
+                Color(0xFF091D44),
+                Color(0xFF245A8A),
+                Color(0xFF7F7CEC),
+              ],
+              begin: Alignment.topCenter,
+              end: Alignment.bottomCenter,
+            ),
+          ),
+          child: Column(
+            children: [
+              MyAppBar.titleBar(context, title),
+
+              SingleChildScrollView(
+                scrollDirection: Axis.vertical,
+                physics: const BouncingScrollPhysics(),
+                child: Html(data: initialUrl).paddingOnly(left: 10, right: 10),
+              )
+            ],
+          ),
+        ),
+      );
+    }
   }
 }

+ 144 - 153
packages/cs_plugin_basic/lib/widget/webview_page.dart

@@ -1,10 +1,16 @@
+import 'dart:convert';
+
 import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/image/image_nine_grid.dart';
 import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/screen_util.dart';
 import 'package:url_launcher/url_launcher.dart';
 import 'dart:io';
 import 'package:webview_flutter/webview_flutter.dart';
+import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:cs_resources/constants/color_constants.dart';
+import 'package:widgets/my_button.dart';
 
 /// webview 封装
 // ignore: must_be_immutable
@@ -12,10 +18,12 @@ class WebViewPage extends StatefulWidget {
   final String? initialUrl;
   bool? showAppbar = true;
   Map? arguments = {'title': '', 'initialUrl': ''};
+  String? bottomBtnTxt; //是否有底部按钮,底部按钮的文本
+  VoidCallback? bottomBtnAction; //底部按钮的回调
 
   List<Widget>? actions = [];
 
-  WebViewPage({Key? key, this.showAppbar, this.initialUrl, this.arguments, this.actions}) : super(key: key);
+  WebViewPage({Key? key, this.showAppbar, this.initialUrl, this.arguments, this.actions, this.bottomBtnTxt, this.bottomBtnAction}) : super(key: key);
 
   @override
   _WebViewPageState createState() => _WebViewPageState();
@@ -24,7 +32,7 @@ class WebViewPage extends StatefulWidget {
 class _WebViewPageState extends State<WebViewPage> {
   WebViewController? webViewController;
   final _key = UniqueKey();
-  String title = '';
+  String? title;
   bool _showAppbar = true;
   int _stackToView = 1;
   String? _initialUrl;
@@ -35,15 +43,82 @@ class _WebViewPageState extends State<WebViewPage> {
     super.initState();
     title = widget.arguments != null ? widget.arguments!['title'] : null;
     _showAppbar = widget.showAppbar ?? true;
+    Log.d("传入的initialUrl:${widget.initialUrl}");
     _initialUrl = widget.initialUrl ?? widget.arguments!['initialUrl'];
-    if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
+
+    _initializeController();
+  }
+
+  void _initializeController() {
+    webViewController = WebViewController()
+      ..setJavaScriptMode(JavaScriptMode.unrestricted)
+      ..setBackgroundColor(const Color(0x00000000))
+      ..setNavigationDelegate(
+        NavigationDelegate(
+          onProgress: (int progress) {
+            if (progress == 100) {
+              Future.delayed(const Duration(milliseconds: 500)).then((value) => {
+                    // 获取页面高度
+                    _getWebViewHeight()
+                  });
+            }
+          },
+          onPageStarted: (String url) {
+            if (mounted) {
+              setState(() {
+                _stackToView = 1;
+              });
+            }
+          },
+          onPageFinished: (String url) {
+            if (mounted) {
+              setState(() {
+                _stackToView = 0;
+              });
+            }
+          },
+          onWebResourceError: (WebResourceError error) {},
+          onNavigationRequest: (NavigationRequest request) async {
+            if (request.url.startsWith('tel:')) {
+              // 拦截tel链接
+              if (!await launchUrl(Uri.parse(request.url))) throw 'Unable to activate the call function';
+              return NavigationDecision.prevent; // 阻止WebView导航到该链接
+            }
+            return NavigationDecision.navigate;
+          },
+        ),
+      )
+      ..loadRequest(Uri.parse(_initialUrl ?? ""));
+  }
+
+  _getWebViewHeight() async {
+    // try {
+    //   final result = await webViewController?.runJavaScriptReturningResult('''
+    //   new Promise((resolve) => {
+    //     const scrollHeight = document.documentElement.scrollHeight;
+    //     resolve(scrollHeight);
+    //   });
+    // ''');
+    //   return double.parse(result.toString());
+    // } catch (e) {
+    //   return 300.0; // 默认高度
+    // }
+
+    // 方式二:
+    var originalHeight = await webViewController?.runJavaScriptReturningResult("document.body.offsetHeight;");
+    _webViewHeight = double.parse(originalHeight.toString());
+    if (mounted) {
+      setState(() {
+        _webViewHeight = _webViewHeight <= 0 ? 300 : _webViewHeight;
+      });
+    }
   }
 
   @override
   void dispose() async {
     super.dispose();
     // 销毁 WebView 实例
-    webViewController?.loadUrl('about:blank');
+    webViewController?.loadHtmlString('about:blank');
     webViewController?.clearCache();
   }
 
@@ -55,80 +130,6 @@ class _WebViewPageState extends State<WebViewPage> {
     }
   }
 
-  // 注册js回调
-  _invokeJavascriptChannel(BuildContext context) {
-    return [
-      JavascriptChannel(
-        name: 'Invoke',
-        onMessageReceived: (JavascriptMessage message) {
-          // var webHeight = double.parse(message.message);
-          // setState(() {
-          //   print('打印webHeight:$_webViewHeight');
-          //   _webViewHeight = webHeight;
-          // });
-        },
-      ),
-      JavascriptChannel(
-        name: 'Invoke1',
-        onMessageReceived: (JavascriptMessage message) {
-          // var devicePixelRatio = double.parse(message.message);
-          // setState(() {
-          // _webViewHeight = devicePixelRatio;
-          // });
-        },
-      ),
-      JavascriptChannel(
-        name: "integral",
-        onMessageReceived: (JavascriptMessage message) {
-          // print("交互");
-          // print("参数: ${message.message}");
-          // Map res = changeStringToJsonMap(message.message);
-          // print(res["operation"]);
-          // _controller?.evaluateJavascript("getAddressBook('sdad')");
-        },
-      ),
-      JavascriptChannel(
-        name: "MessageDeal",
-        onMessageReceived: (JavascriptMessage message) async {
-          // print("交互");
-          // print("参数: ${message.message}");
-          // print(webViewController);
-          // webViewController
-          //     ?.runJavascriptReturningResult("showMessage('我(Flutter)收到了你的消息)");
-          // _controller?.evaluateJavascript("document.title");
-        },
-      ),
-      JavascriptChannel(
-        name: "callWithDict",
-        onMessageReceived: (JavascriptMessage message) {
-          // print("交互");
-          // print("参数: ${message.message}");
-        },
-      ),
-    ];
-  }
-
-  // 获取页面高度
-  _getWebViewHeight() async {
-    // 方式一:
-    // await webViewController?.runJavascriptReturningResult('''
-    //     try {
-    //       // Invoke.postMessage([document.body.clientHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight]);
-    //       let scrollHeight = document.documentElement.scrollHeight;
-    //       if (scrollHeight) {
-    //         Invoke.postMessage(scrollHeight);
-    //       }
-    //     } catch {}
-    //     ''');
-    // 方式二:
-    var originalHeight = await webViewController!.runJavascriptReturningResult("document.body.offsetHeight;");
-    _webViewHeight = double.parse(originalHeight);
-    setState(() {
-      _webViewHeight = _webViewHeight <= 0 ? 300 : _webViewHeight;
-    });
-    // print('网页高度-----' + _webViewHeight.toString());
-  }
-
   // 返回与后退的处理
   Future<bool> _onWillPop() async {
     if (webViewController == null) {
@@ -152,84 +153,74 @@ class _WebViewPageState extends State<WebViewPage> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-        backgroundColor: Colors.white,
-        appBar:
-            _showAppbar ? MyAppBar.appBar(context, title, backgroundColor: Colors.white, actions: widget.actions, backCallback: _onWillPop) : null,
-        body: SafeArea(
-          bottom: true,
-          top: false,
-          child: IndexedStack(
-            index: _stackToView,
-            children: [
-              Column(
-                children: [
-                  Expanded(
-                    child: WillPopScope(
-                      onWillPop: _onWillPop,
-                      child: WebView(
-                        key: _key,
-                        initialUrl: _initialUrl,
-                        userAgent: '',
-                        //JS执行模式 是否允许JS执行
-                        javascriptMode: JavascriptMode.unrestricted,
-                        //webview创建好
-                        onWebViewCreated: (WebViewController controller) {
-                          webViewController = controller;
-                        },
-                        onProgress: (int progress) {
-                          // print('progress=====>$progress');
-                          if (progress == 100) {
-                            Future.delayed(const Duration(milliseconds: 500)).then((value) => {
-                                  // 获取页面高度
-                                  _getWebViewHeight()
-                                });
-                          }
-                        },
-                        onPageStarted: (String url) {
-                          // print('onPageStarted=====>$url');
-                        },
-                        onPageFinished: (String url) {
-                          Log.d('onPageFinished=====>$url');
-                          if (mounted) {
-                            setState(() {
-                              _stackToView = 0;
-                            });
-                          }
-                        },
-                        onWebResourceError: (WebResourceError error) {
-                          // print('error=====>$error');
-                        },
-                        gestureNavigationEnabled: true,
-                        // 注册js 回调
-                        javascriptChannels: _invokeJavascriptChannel(context).toSet(),
-                        navigationDelegate: (NavigationRequest request) async {
-                          //如果是tel标签需要阻止并调用 launchUrl 的方法调用拨打电话
-                          if (request.url.startsWith('tel:')) {
-                            // 拦截tel链接
-                            if (!await launchUrl(Uri.parse(request.url))) throw '无法启动拨打电话功能';
-                            return NavigationDecision.prevent; // 阻止WebView导航到该链接
-                          }
-
-                          // 可以继续WebView的内部跳转
-                          return NavigationDecision.navigate;
-                        },
+    return SafeArea(
+      bottom: true,
+      top: false,
+      child: Container(
+        width: double.infinity,
+        height: double.infinity,
+        padding: EdgeInsets.only(top: ScreenUtil.getStatusBarH(context)),
+        decoration: const BoxDecoration(
+          gradient: LinearGradient(
+            colors: [
+              Color(0xFF091D44),
+              Color(0xFF245A8A),
+              Color(0xFF7F7CEC),
+            ],
+            begin: Alignment.topCenter,
+            end: Alignment.bottomCenter,
+          ),
+        ),
+        child: Column(
+          children: [
+            MyAppBar.titleBar(context, title ?? "Title"),
+
+            IndexedStack(
+              index: _stackToView,
+              children: [
+                //WebView控件
+                Column(
+                  children: [
+                    Expanded(
+                      child: WillPopScope(
+                        onWillPop: _onWillPop,
+                        child: WebViewWidget(
+                          key: _key,
+                          controller: webViewController!,
+                        ),
                       ),
+                    )
+                  ],
+                ),
+                //Loading加载控件
+                Container(
+                  color: Colors.white,
+                  child: const Center(
+                    child: CircularProgressIndicator(
+                      strokeWidth: 3,
+                      valueColor: AlwaysStoppedAnimation(ColorConstants.appBlue),
                     ),
-                  )
-                ],
-              ),
-              Container(
-                color: Colors.white,
-                child: Center(
-                  child: CircularProgressIndicator(
-                    strokeWidth: 3,
-                    valueColor: AlwaysStoppedAnimation(ColorConstants.appBlue),
                   ),
                 ),
-              ),
-            ],
-          ),
-        ));
+              ],
+            ).expanded(),
+
+            //底部按钮
+            if (widget.bottomBtnTxt != null)
+              MyButton(
+                onPressed: widget.bottomBtnAction,
+                text: widget.bottomBtnTxt ?? "",
+                textColor: Colors.white,
+                backgroundColor: ColorConstants.blue1578fe,
+                fontWeight: FontWeight.w500,
+                type: ClickType.throttle,
+                fontSize: 16,
+                minHeight: 50,
+                radius: 0,
+              )
+          ],
+        ),
+      ),
+    );
   }
 }

+ 1 - 1
packages/cs_plugin_basic/pubspec.yaml

@@ -41,7 +41,7 @@ dependencies:
   package_info_plus: 8.0.2
 
   # 获取当前设备信息 https://github.com/fluttercommunity/plus_plugins/tree/main/packages/device_info_plus
-  device_info_plus: 10.0.1
+  device_info_plus: ^11.3.0
 
   # 跳转应用处理 https://github.com/flutter/plugins/tree/master_archive/packages/url_launcher/url_launcher
   # 例如:拨打电话,发送短信,发送邮件,跳转Whatsapp,打开本地文件等操作

+ 2 - 0
packages/cs_resources/lib/local/language/en_US.dart

@@ -147,6 +147,8 @@ const Map<String, String> en_US = {
   'Device List': 'Device List',
   'Device MAC:': 'Device MAC:',
   'Device Alias:': 'Device Alias:',
+  'Device No:': 'Device No:',
+  'Device Name:': 'Device Name:',
   'Location:': 'Location:',
   'Alive State:': 'Alive State:',
   'Offline': 'Offline',

+ 2 - 0
packages/cs_resources/lib/local/language/zh_CN.dart

@@ -147,6 +147,8 @@ const Map<String, String> zh_CN = {
   'Device List': '设备列表',
   'Device MAC:': '设备Mac地址:',
   'Device Alias:': '设备别名:',
+  'Device No:': '设备编号:',
+  'Device Name:': '设备名称:',
   'Location:': '位置:',
   'Alive State:': '在线状态:',
   'Offline': '离线',

+ 4 - 3
packages/cs_resources/lib/local/theme/theme_config.dart

@@ -147,9 +147,10 @@ class ThemeConfig {
       statusBarColor: Colors.transparent,
       statusBarBrightness: Brightness.dark,
       statusBarIconBrightness: Brightness.light,
-      systemNavigationBarDividerColor: Colors.transparent,
-      systemNavigationBarColor: Colors.white,
-      systemNavigationBarIconBrightness: Brightness.dark,
+
+      systemNavigationBarColor: Colors.transparent, // 保持透明
+      systemNavigationBarIconBrightness: Brightness.light, // 强制浅色图标(白色手势条)
+      systemNavigationBarContrastEnforced: false,   // 允许内容延伸到导航栏
     );
   }
 

+ 1 - 1
packages/cs_widgets/pubspec.yaml

@@ -28,7 +28,7 @@ dependencies:
   get: 4.6.6
 
   # WebView插件 https://github.com/flutter/plugins/tree/master/packages/webview_flutter
-  webview_flutter: ^3.0.4
+  webview_flutter: ^4.10.0
   # 如何使用?WebviewScaffold 整体WebView带上下结构布局
   #          FlutterWebviewPlugin  单独的WebView插件
   # https://pub.dev/packages/flutter_webview_plugin#-readme-tab