Browse Source

处理组件路由
处理全局Provider 网络,用户服务,AppConfig服务
初始化Slpash页面
完善安卓环境
加入必要的底层图片
公共页面的页面路由与配置

liukai 4 months ago
parent
commit
42b0e65090
61 changed files with 1124 additions and 688 deletions
  1. 11 15
      app/lib/main.dart
  2. 2 0
      app/lib/router/app_page_router.dart
  3. 10 8
      packages/cs_initializer/lib/app_initializer.dart
  4. 0 47
      packages/cs_initializer/lib/global_services_injection.dart
  5. 9 8
      packages/cs_plugin_basic/lib/dio_interceptors/interceptor_auth_dio.dart
  6. 5 3
      packages/cs_plugin_basic/lib/dio_interceptors/interceptor_status_code_dio.dart
  7. 43 41
      packages/cs_plugin_basic/lib/modules/global_web_page.dart
  8. 173 183
      packages/cs_plugin_basic/lib/modules/preview_photo_page.dart
  9. 253 0
      packages/cs_plugin_basic/lib/provider/app_config/app_config.dart
  10. 113 0
      packages/cs_plugin_basic/lib/provider/app_config/app_config_service.dart
  11. 26 0
      packages/cs_plugin_basic/lib/provider/app_config/app_config_service.g.dart
  12. 4 0
      packages/cs_plugin_basic/lib/provider/global_provider_container.dart
  13. 19 0
      packages/cs_plugin_basic/lib/provider/http_provider/http_provider.dart
  14. 26 0
      packages/cs_plugin_basic/lib/provider/http_provider/http_provider.g.dart
  15. 84 0
      packages/cs_plugin_basic/lib/provider/user_config/user_config.dart
  16. 46 0
      packages/cs_plugin_basic/lib/provider/user_config/user_config_service.dart
  17. 26 0
      packages/cs_plugin_basic/lib/provider/user_config/user_config_service.g.dart
  18. 21 0
      packages/cs_plugin_basic/lib/router/basic_page_router.dart
  19. 144 0
      packages/cs_plugin_basic/lib/router/basic_page_router.gr.dart
  20. 0 213
      packages/cs_plugin_basic/lib/service/app_config_service.dart
  21. 0 59
      packages/cs_plugin_basic/lib/service/config_services_injection.dart
  22. 0 30
      packages/cs_plugin_basic/lib/service/http_provider_injection.dart
  23. 0 60
      packages/cs_plugin_basic/lib/service/user_service.dart
  24. BIN
      packages/cs_resources/assets/base_lib/black_back.webp
  25. BIN
      packages/cs_resources/assets/base_lib/dialog_blue_delete_icon.webp
  26. BIN
      packages/cs_resources/assets/base_lib/dialog_delete_icon.webp
  27. BIN
      packages/cs_resources/assets/base_lib/image_default_placeholder.png
  28. BIN
      packages/cs_resources/assets/base_lib/item_more_icon.webp
  29. BIN
      packages/cs_resources/assets/base_lib/search_icon.webp
  30. BIN
      packages/cs_resources/assets/base_lib/white_back.webp
  31. BIN
      packages/cs_resources/assets/base_service/border_widget_drop_down.webp
  32. BIN
      packages/cs_resources/assets/base_service/check_box_checked.webp
  33. BIN
      packages/cs_resources/assets/base_service/check_box_uncheck.webp
  34. BIN
      packages/cs_resources/assets/base_service/dialog_delete_icon.webp
  35. BIN
      packages/cs_resources/assets/base_service/item_selected_icon.webp
  36. BIN
      packages/cs_resources/assets/base_service/item_unselected_gray_icon.webp
  37. BIN
      packages/cs_resources/assets/base_service/item_unselected_icon.webp
  38. BIN
      packages/cs_resources/assets/base_service/page_load_error.webp
  39. BIN
      packages/cs_resources/assets/base_service/page_no_data.webp
  40. BIN
      packages/cs_resources/assets/base_service/radio_checked.webp
  41. BIN
      packages/cs_resources/assets/base_service/radio_uncheck.webp
  42. BIN
      packages/cs_resources/assets/base_service/rating_selected.webp
  43. BIN
      packages/cs_resources/assets/base_service/rating_unselected.webp
  44. BIN
      packages/cs_resources/assets/base_service/title_bar_filter_icon.webp
  45. BIN
      packages/cs_resources/assets/base_service/triangle_drop_down.webp
  46. BIN
      packages/cs_resources/assets/base_service/triangle_drop_down_icon.webp
  47. 23 0
      packages/cs_resources/lib/generated/assets.dart
  48. 2 0
      packages/cs_resources/pubspec.yaml
  49. 40 0
      packages/cs_router/lib/ext/auto_router_extensions.dart
  50. 1 1
      packages/cs_router/lib/path/router_path.dart
  51. 24 2
      packages/cs_shared/lib/utils/number_format_util.dart
  52. 2 2
      packages/cs_widgets/lib/load_state_layout.dart
  53. 4 4
      packages/cs_widgets/lib/my_appbar.dart
  54. 1 1
      packages/cs_widgets/lib/my_click_item.dart
  55. 3 3
      packages/cs_widgets/lib/search_app_bar.dart
  56. 1 1
      packages/cs_widgets/lib/shatter/border_select_widget.dart
  57. 1 1
      packages/cs_widgets/lib/shatter/custom_check_box.dart
  58. 2 1
      packages/cs_widgets/lib/shatter/custom_radio_check.dart
  59. 2 2
      packages/cs_widgets/lib/shatter/form_require_text.dart
  60. 1 1
      packages/cs_widgets/lib/shatter/round_my_text_field.dart
  61. 2 2
      packages/cs_widgets/lib/shatter/setting_item_container.dart

+ 11 - 15
app/lib/main.dart

@@ -1,14 +1,11 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-import 'package:flutter_localizations/flutter_localizations.dart';
-import 'package:initializer/global_services_injection.dart';
 import 'package:initializer/app_initializer.dart';
 import 'package:plugin_basic/basic_export.dart';
-import 'package:router/componentRouter/auth_service.dart';
+import 'package:plugin_basic/provider/app_config/app_config_service.dart';
+import 'package:plugin_basic/provider/global_provider_container.dart';
 
 import 'package:cs_resources/local/theme/theme_config.dart';
-import 'package:cs_resources/local/language/translation_service.dart';
-import 'package:router/path/router_path.dart';
 
 import 'package:widgets/dialog/custom_toast_widget.dart';
 import 'package:widgets/dialog/custom_error_widget.dart';
@@ -26,16 +23,6 @@ void main() async {
   //交给初始化构造器去统一初始化
   await AppInitializer.initializeRunalone();
 
-  //全局自定义单例服务的注入
-  // GlobalServicesInjection.init(additionalDependencies: () {
-  //   Get.lazyPut<AuthService>(() => AuthServiceImpl());
-  //   Get.lazyPut<LabourService>(() => LabourServiceImpl());
-  //   Get.lazyPut<JobService>(() => JobServiceImpl());
-  //   Get.lazyPut<ReportService>(() => ReportServiceImpl());
-  //   Get.lazyPut<JobSGService>(() => JobSGServiceImpl());
-  //   Get.lazyPut<LabourSGService>(() => LabourSGServiceImpl());
-  // });
-
   runApp(ProviderScope(
     observers: [RiverpodObserver()],
     child: MyApp(),
@@ -99,6 +86,15 @@ class MyApp extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
+
+    // Future.microtask(() {
+    //   globalContainer.read(appConfigServiceProvider.notifier).initSize(context);
+    // });
+
+    WidgetsBinding.instance.addPostFrameCallback((_) {
+      globalContainer.read(appConfigServiceProvider.notifier).initSize(context);
+    });
+
     //设置全局的状态栏文本样式
     SystemChrome.setSystemUIOverlayStyle(ThemeConfig.systemUiOverlayStyleLightThemeWhite);
     final appRouter = AppRouter();

+ 2 - 0
app/lib/router/app_page_router.dart

@@ -1,5 +1,6 @@
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_basic/router/basic_page_router.dart';
 import 'package:router/path/router_path.dart';
 
 import '../modules/splash/page/splash_page.dart';
@@ -11,5 +12,6 @@ class AppRouter extends _$AppRouter {
   @override
   List<AutoRoute> get routes => [
         AutoRoute(page: SplashPageRoute.page, initial: true, path: RouterPath.splash),
+        ...BasicPageRouter().routes,
       ];
 }

+ 10 - 8
packages/cs_initializer/lib/app_initializer.dart

@@ -1,19 +1,20 @@
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-import 'package:plugin_basic/service/config_services_injection.dart';
+import 'package:plugin_basic/provider/global_provider_container.dart';
 import 'package:plugin_platform/engine/directory/directory_util.dart';
 import 'package:plugin_platform/engine/sp/sp_util.dart';
 import 'package:shared/utils/log_utils.dart';
+import 'package:plugin_basic/provider/app_config/app_config_service.dart';
 
-/**
+/*
  * Main函数入口的初始化
  */
 class AppInitializer {
   // 私有的构造函数,防止实例化
   AppInitializer._();
 
-  /**
+  /*
    * 1.入口初始化方法 - Platform 插件中的Engine其他功能初始化
    * main.dart 中宿主的配置
    */
@@ -38,7 +39,7 @@ class AppInitializer {
     SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]);
   }
 
-  /**
+  /*
    * 2.延迟初始化,一般是在用户同意隐私权限之后再调用
    * 同意权限之后的其他插件初始化,用于宿主的配置
    */
@@ -55,7 +56,8 @@ class AppInitializer {
 
       DirectoryUtil.getInstance(), // SD卡管控
 
-      ConfigServicesInjection.init(), // 假设这是一个 Future 方法
+      //AppConfig服务
+      globalContainer.read(appConfigServiceProvider.notifier).initAsync(),
     ];
 
     // 如果提供了 futureTasks,调用并添加到 futures 列表
@@ -78,7 +80,7 @@ class AppInitializer {
     await Future.wait(futures);
   }
 
-  /**
+  /*
    * 3.入口初始化方法 - Platform 插件中的Engine其他功能初始化
    * 独立运行模块中的 main.dart 配置,用于测试
    */
@@ -96,8 +98,8 @@ class AppInitializer {
     setInitDir(initTempDir: true, initAppDocDir: true, initAppSupportDir: true, initStorageDir: false);
     DirectoryUtil.getInstance(); //SD卡管控
 
-    //注入全局单例Service(内部包含 AppInfo,DeviceInfo 等初始化,并注入了 ConfigService 配置服务类)
-    await ConfigServicesInjection.init();
+    //AppConfig服务
+    await globalContainer.read(appConfigServiceProvider.notifier).initAsync();
 
     //指定页面的展示方向为哪一种,常用的三种屏幕方向
     SystemChrome.setPreferredOrientations([

+ 0 - 47
packages/cs_initializer/lib/global_services_injection.dart

@@ -1,47 +0,0 @@
-import 'package:domain/constants/api_constants.dart';
-import 'package:plugin_basic/basic_export.dart';
-import 'package:plugin_basic/dio_interceptors/interceptor_auth_dio.dart';
-import 'package:plugin_basic/dio_interceptors/interceptor_status_code_dio.dart';
-import 'package:plugin_basic/service/http_provider_injection.dart';
-import 'package:plugin_basic/service/user_service.dart';
-import 'package:plugin_platform/http/http_provider.dart';
-import 'package:shared/utils/log_utils.dart';
-
-/*
-   全局服务 Service 的初始化入口
-
-   1. 默认注入网络请求Provider与Domain的Repository
-   2. 留下高阶函数的入口,方便加入其他的全局服务
-
-   全局单例服务的注入,在 main.dart 入口就可直接调用,注意手动调用
- */
-class GlobalServicesInjection {
-  /// init
-  static void init({void Function()? additionalDependencies}) {
-    Log.d('----ConfigServicesInjection------start-----');
-
-    //全局单例的 HttpProvider 用于发起网络请求 (根据不同的选择国家注入不同的域名)
-    // HttpProviderInjection.putHttpProviderByCountry();
-
-    //全局单例的用户数据仓库
-    // Get.put(AuthRepository(httpProvider: Get.find()));
-
-    //其他的数据仓库注入
-    // Get.lazyPut(() => JobRepository(httpProvider: Get.find()));
-    // Get.lazyPut(() => JobSGRepository(httpProvider: Get.find()));
-    // Get.lazyPut(() => LabourRepository(httpProvider: Get.find()));
-    // Get.lazyPut(() => LabourSGRepository(httpProvider: Get.find()));
-    // Get.lazyPut(() => OtherRepository(httpProvider: Get.find()));
-
-    // 用户信息服务(用户信息相关业务类)
-    // Get.put(UserService(Get.find()));
-
-    // 调用额外的依赖注入逻辑(如果提供了)
-    if (additionalDependencies != null) {
-      additionalDependencies();
-    }
-
-    Log.d('----ConfigServicesInjection------end-----');
-  }
-
-}

+ 9 - 8
packages/cs_plugin_basic/lib/dio_interceptors/interceptor_auth_dio.dart

@@ -2,8 +2,10 @@ import 'package:dio/dio.dart';
 import 'package:shared/utils/device_utils.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:shared/utils/util.dart';
-import '../service/app_config_service.dart';
-import '../service/user_service.dart';
+
+import '../provider/global_provider_container.dart';
+import '../provider/user_config/user_config_service.dart';
+
 
 /*
  * 用户授权加密等相关处理的拦截器
@@ -43,12 +45,11 @@ class AuthDioInterceptors extends Interceptor {
     // }
 
     //如果有通行令牌,都带上通行令牌
-    //todo 待改造
-    // String? token = UserService.to.token;
-    // Log.d("AuthDioInterceptors 添加用户授权Token:$token");
-    // if (!Utils.isEmpty(token)) {
-    //   headers['Authorization'] = 'Bearer $token';
-    // }
+    String? token = globalContainer.read(userConfigServiceProvider)?.token;
+    Log.d("AuthDioInterceptors 添加用户授权Token:$token");
+    if (!Utils.isEmpty(token)) {
+      headers['Authorization'] = 'Bearer $token';
+    }
     // 参数加密
 
     // 通讯加密

+ 5 - 3
packages/cs_plugin_basic/lib/dio_interceptors/interceptor_status_code_dio.dart

@@ -1,8 +1,10 @@
 
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:plugin_platform/dio_export.dart';
 import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
 import 'package:widgets/dialog/app_default_dialog.dart';
-import '../service/user_service.dart';
+
+import '../provider/global_provider_container.dart';
 
 /*
  * 特殊状态code处理的拦截器,
@@ -36,8 +38,8 @@ class StatusCodeDioInterceptors extends Interceptor {
     // 避免重复展示弹窗
     if (!isDialogShowing) {
       //弹框就清除了数据
-      //todo 待改造
-      // UserService.to.handleLogoutParams();
+      //使用 UserConfigService 对象中的方法处理
+      globalContainer.read(userConfigServiceProvider.notifier).handleLogoutParams();
 
       //拦截 token 过期,弹出弹窗提示用户重新登录
       DialogEngine.show(

+ 43 - 41
packages/cs_plugin_basic/lib/modules/global_web_page.dart

@@ -1,41 +1,43 @@
-// import 'package:flutter/material.dart';
-// import 'package:router/path/router_path.dart';
-// import 'package:shared/utils/log_utils.dart';
-// import '../widget/webview_page.dart';
-//
-// /*
-//  * 全局的公共Web页面
-//  */
-// class GlobalWebPage extends BaseStatelessPage {
-//   GlobalWebPage({super.key});
-//
-//   //启动当前页面
-//   static void startInstance(
-//     String title,
-//     String url, {
-//     bool isShowAppBar = true,
-//   }) {
-//     return Get.start(RouterPath.globalWeb, arguments: {'title': title, 'initialUrl': Uri.encodeFull(url), 'isShowAppBar': isShowAppBar});
-//   }
-//
-//   @override
-//   GetxController createRawController() {
-//     throw UnimplementedError();
-//   }
-//
-//   @override
-//   void initState() {}
-//
-//   @override
-//   Widget buildWidget(BuildContext context) {
-//     bool isShowAppBar = Get.arguments['isShowAppBar'];
-//     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},
-//     );
-//   }
-// }
+import 'package:flutter/material.dart';
+import 'package:plugin_basic/router/basic_page_router.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import '../widget/webview_page.dart';
+import 'package:auto_route/auto_route.dart';
+
+/*
+ * 全局的公共Web页面
+ */
+@RoutePage()
+class GlobalWebPage extends HookConsumerWidget {
+  final bool isShowAppBar;
+  final String initialUrl;
+  final String title;
+
+  const GlobalWebPage({
+    Key? key,
+    @PathParam('isShowAppBar') required this.isShowAppBar,
+    @PathParam('initialUrl') required this.initialUrl,
+    @PathParam('title') required this.title,
+  }) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({
+    required BuildContext context,
+    required String title,
+    required String url,
+    bool isShowAppBar = true,
+  }) {
+    context.router.push(GlobalWebPageRoute(isShowAppBar: isShowAppBar, initialUrl: url, title: title));
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    Log.d("GlobalWebPage 的参数 isShowAppBar:$isShowAppBar title:$title initialUrl:$initialUrl ");
+    return WebViewPage(
+      showAppbar: isShowAppBar,
+      initialUrl: initialUrl,
+      arguments: {'title': title},
+    );
+  }
+}

+ 173 - 183
packages/cs_plugin_basic/lib/modules/preview_photo_page.dart

@@ -1,183 +1,173 @@
-// import 'dart:io';
-//
-// import 'package:flutter/material.dart';
-// import 'package:cs_resources/generated/assets.dart';
-// import 'package:router/path/router_path.dart';
-// import 'package:shared/utils/screen_util.dart';
-// import 'package:widgets/my_load_image.dart';
-// import 'package:widgets/my_text_view.dart';
-// import 'package:cs_resources/constants/color_constants.dart';
-// import 'package:extended_image/extended_image.dart';
-//
-// /*
-//  * 预览的图片的页面,内部使用PageView左右切换
-//  */
-// class PreviewPhotoPage extends BaseStatefulPage {
-//   PreviewPhotoPage({super.key});
-//
-//   //启动当前页面
-//   static Future<T?>? startInstance<T>(List<String> imgs, int position) {
-//     return Get.toNamed(RouterPath.previewImage, arguments: {'imgs': imgs, "position": position});
-//   }
-//
-//   @override
-//   _PreviewPhotoPageState createState() => _PreviewPhotoPageState();
-//
-//   @override
-//   GetxController createRawController() {
-//     throw UnimplementedError();
-//   }
-// }
-//
-// class _PreviewPhotoPageState extends State<PreviewPhotoPage> {
-//   late List<String> images;
-//   int currentIndex = 0;
-//
-//   @override
-//   void initState() {
-//     super.initState();
-//     images = Get.arguments['imgs'];
-//     currentIndex = Get.arguments['position'];
-//   }
-//
-//   @override
-//   void dispose() {
-//     super.dispose();
-//     clearGestureDetailsCache();
-//   }
-//
-//   @override
-//   Widget build(BuildContext context) {
-//     return Scaffold(
-//         backgroundColor: ColorConstants.black,
-//
-//         body: SafeArea(
-//           bottom: true,
-//           top: false,
-//           //真正的 Content 布局
-//           child: Column(`
-//             children: [
-//               SizedBox(height: ScreenUtil.getStatusBarH(context)),
-//               Row(
-//                 children: [
-//                   //间距
-//                   SizedBox(width: 30),
-//                   Expanded(
-//                     child: MyTextView(
-//                       "${currentIndex + 1}/${images.length}",
-//                       textColor: Colors.white,
-//                       fontSize: 18,
-//                       isFontRegular: true,
-//                       textAlign: TextAlign.center,
-//                     ),
-//                   ),
-//
-//                   InkWell(
-//                     onTap: () {
-//                       Get.back();
-//                     },
-//                     child: const MyAssetImage(
-//                       Assets.baseLibDialogDeleteIcon,
-//                       width: 14,
-//                       height: 14,
-//                     ),
-//                   ),
-//
-//                   //间距
-//                   SizedBox(width: 15),
-//                 ],
-//               ),
-//               Expanded(
-//                   child: ExtendedImageGesturePageView.builder(
-//                 controller: ExtendedPageController(
-//                   //图片PageView的配置选项
-//                   initialPage: currentIndex,
-//                   pageSpacing: 10,
-//                 ),
-//                 itemCount: images.length,
-//                 scrollDirection: Axis.horizontal,
-//                 onPageChanged: (int index) {
-//                   setState(() {
-//                     currentIndex = index;
-//                   });
-//                 },
-//                 itemBuilder: (BuildContext context, int index) {
-//                   //默认网络加载的占位图
-//                   final Widget placeholder = Container(
-//                     //如果没有设置占位图,使用默认的灰色背景内置Icon小图标
-//                     width: double.infinity,
-//                     height: double.infinity,
-//                     color: ColorConstants.greye0,
-//                     alignment: Alignment.center,
-//                     child: const MyAssetImage(
-//                       Assets.baseLibImageDefaultPlaceholder,
-//                       width: 38,
-//                       height: 32,
-//                     ),
-//                   );
-//
-//                   //区分网络图片和本地图片
-//                   Widget image = images[index].startsWith("http")
-//                       ? ExtendedImage.network(
-//                           images[index],
-//                           fit: BoxFit.contain,
-//                           timeLimit: const Duration(milliseconds: 30000),
-//                           cache: true,
-//                           mode: ExtendedImageMode.gesture,
-//                           loadStateChanged: (ExtendedImageState state) {
-//                             switch (state.extendedImageLoadState) {
-//                               case LoadState.loading:
-//                                 return placeholder;
-//
-//                               case LoadState.completed:
-//                                 return null;
-//
-//                               case LoadState.failed:
-//                                 return placeholder;
-//                             }
-//                           },
-//                           initGestureConfigHandler: (ExtendedImageState state) {
-//                             return GestureConfig(
-//                               // 图片展示的配置选项
-//                               inPageView: true,
-//                               initialScale: 1.0,
-//                               maxScale: 5.0,
-//                               animationMaxScale: 6.0,
-//                               initialAlignment: InitialAlignment.center,
-//                               cacheGesture: false,
-//                             );
-//                           },
-//                         )
-//                       : ExtendedImage.file(
-//                           File(images[index]),
-//                           fit: BoxFit.contain,
-//                           mode: ExtendedImageMode.gesture,
-//                           initGestureConfigHandler: (ExtendedImageState state) {
-//                             return GestureConfig(
-//                               // 图片展示的配置选项
-//                               inPageView: true,
-//                               initialScale: 1.0,
-//                               maxScale: 5.0,
-//                               animationMaxScale: 6.0,
-//                               initialAlignment: InitialAlignment.center,
-//                               cacheGesture: false,
-//                             );
-//                           },
-//                         );
-//
-//                   if (index == currentIndex) {
-//                     return Hero(
-//                       // tag: index.toString(),
-//                       tag: "0",
-//                       child: image,
-//                     );
-//                   } else {
-//                     return image;
-//                   }
-//                 },
-//               )),
-//             ],
-//           ),
-//         ));
-//   }
-// }
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:plugin_basic/router/basic_page_router.dart';
+import 'package:router/path/router_path.dart';
+import 'package:shared/utils/screen_util.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:extended_image/extended_image.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:auto_route/auto_route.dart';
+
+/*
+ * 预览的图片的页面,内部使用PageView左右切换
+ */
+@RoutePage()
+class PreviewPhotoPage extends HookConsumerWidget {
+  final List<String> images;
+  final int position;
+
+  const PreviewPhotoPage({
+    Key? key,
+    required this.images,
+    required this.position,
+  }) : super(key: key);
+
+  //启动当前页面
+  static Future<T?>? startInstance<T>({
+    required BuildContext context,
+    required List<String> images,
+    required int position,
+  }) {
+    return context.router.push(PreviewPhotoPageRoute(images: images, position: position));
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final currentIndex = useState<int>(position);
+
+    return Scaffold(
+      backgroundColor: ColorConstants.black,
+      body: SafeArea(
+        bottom: true,
+        top: false,
+        //真正的 Content 布局
+        child: Column(
+          children: [
+            SizedBox(height: ScreenUtil.getStatusBarH(context)),
+            Row(
+              children: [
+                //间距
+                const SizedBox(width: 30),
+                Expanded(
+                  child: MyTextView(
+                    "${currentIndex.value + 1}/${images.length}",
+                    textColor: Colors.white,
+                    fontSize: 18,
+                    isFontRegular: true,
+                    textAlign: TextAlign.center,
+                  ),
+                ),
+
+                InkWell(
+                  onTap: () {
+                    Navigator.pop(context);
+                  },
+                  child: const MyAssetImage(
+                    Assets.baseLibDialogDeleteIcon,
+                    width: 14,
+                    height: 14,
+                  ),
+                ),
+
+                //间距
+                const SizedBox(width: 15),
+              ],
+            ),
+            Expanded(
+                child: ExtendedImageGesturePageView.builder(
+              controller: ExtendedPageController(
+                //图片PageView的配置选项
+                initialPage: currentIndex.value,
+                pageSpacing: 10,
+              ),
+              itemCount: images.length,
+              scrollDirection: Axis.horizontal,
+              onPageChanged: (int index) {
+                currentIndex.value = index;
+              },
+              itemBuilder: (BuildContext context, int index) {
+                //默认网络加载的占位图
+                final Widget placeholder = Container(
+                  //如果没有设置占位图,使用默认的灰色背景内置Icon小图标
+                  width: double.infinity,
+                  height: double.infinity,
+                  color: ColorConstants.greye0,
+                  alignment: Alignment.center,
+                  child: const MyAssetImage(
+                    Assets.baseLibImageDefaultPlaceholder,
+                    width: 38,
+                    height: 32,
+                  ),
+                );
+
+                //区分网络图片和本地图片
+                Widget image = images[index].startsWith("http")
+                    ? ExtendedImage.network(
+                        images[index],
+                        fit: BoxFit.contain,
+                        timeLimit: const Duration(milliseconds: 30000),
+                        cache: true,
+                        mode: ExtendedImageMode.gesture,
+                        loadStateChanged: (ExtendedImageState state) {
+                          switch (state.extendedImageLoadState) {
+                            case LoadState.loading:
+                              return placeholder;
+
+                            case LoadState.completed:
+                              return null;
+
+                            case LoadState.failed:
+                              return placeholder;
+                          }
+                        },
+                        initGestureConfigHandler: (ExtendedImageState state) {
+                          return GestureConfig(
+                            // 图片展示的配置选项
+                            inPageView: true,
+                            initialScale: 1.0,
+                            maxScale: 5.0,
+                            animationMaxScale: 6.0,
+                            initialAlignment: InitialAlignment.center,
+                            cacheGesture: false,
+                          );
+                        },
+                      )
+                    : ExtendedImage.file(
+                        File(images[index]),
+                        fit: BoxFit.contain,
+                        mode: ExtendedImageMode.gesture,
+                        initGestureConfigHandler: (ExtendedImageState state) {
+                          return GestureConfig(
+                            // 图片展示的配置选项
+                            inPageView: true,
+                            initialScale: 1.0,
+                            maxScale: 5.0,
+                            animationMaxScale: 6.0,
+                            initialAlignment: InitialAlignment.center,
+                            cacheGesture: false,
+                          );
+                        },
+                      );
+
+                if (index == currentIndex.value) {
+                  return Hero(
+                    // tag: index.toString(),
+                    tag: "0",
+                    child: image,
+                  );
+                } else {
+                  return image;
+                }
+              },
+            )),
+          ],
+        ),
+      ),
+    );
+  }
+}

+ 253 - 0
packages/cs_plugin_basic/lib/provider/app_config/app_config.dart

@@ -0,0 +1,253 @@
+// 应用相关操作状态 State 类,用于 RiverPod 中 Provider 的定义
+import 'package:device_info_plus/device_info_plus.dart';
+import 'package:flutter/material.dart';
+import 'package:package_info_plus/package_info_plus.dart';
+import 'package:shared/utils/device_utils.dart';
+
+class AppConfig {
+  /// android 设备信息
+  AndroidDeviceInfo? androidDeviceInfo;
+
+  /// ios 设备信息
+  IosDeviceInfo? iosDeviceInfo;
+
+  /// 包信息
+  PackageInfo? packageInfo;
+
+  double? _safeAreaPaddingTop;
+
+  double? _safeAreaPaddingBottom;
+
+  //屏幕大小
+  Size? mSize;
+
+  //密度
+  double? mRatio;
+
+  //设备像素px
+  double? width;
+  double? height;
+
+  //设备宽高比,大于1.9是全面屏手机
+  double whRatio = 1;
+  double density = 0;
+
+  //是否是全面屏设备(宽高比大于1.9)
+  bool isFullScreenDevice = false;
+
+  // 上下边距 (主要用于 刘海  和  内置导航键)
+  double? topPadding;
+  double? bottomPadding;
+  double? textScaleFactor;
+
+  Brightness? platformBrightness;
+  EdgeInsets? viewInsets;
+  EdgeInsets? padding;
+  bool? alwaysUse24HourFormat;
+  bool? accessibleNavigation;
+  bool? invertColors;
+  bool? disableAnimations;
+  bool? boldText;
+  Orientation? orientation;
+
+  /// 是否 release  包(生产环境)
+  bool get isRelease => const bool.fromEnvironment("dart.vm.product");
+
+  String get version => packageInfo?.version ?? '-';
+
+  String get appName => packageInfo?.appName ?? '-';
+
+  String get packageName => packageInfo?.packageName ?? '-';
+
+  String get buildNumber => packageInfo?.buildNumber ?? '-';
+
+  // 顶部安全距离(pt)
+  double get safeAreaPaddingTop => _safeAreaPaddingTop!;
+
+  // 底部安全距离(pt)
+  double get safeAreaPaddingBottom => _safeAreaPaddingBottom!;
+
+  // 获取当前Android设备的Android版本
+  int getAndroidSdkInt() {
+    if (DeviceUtils.isAndroid) {
+      return androidDeviceInfo?.version.sdkInt ?? -1;
+    } else {
+      return -1;
+    }
+  }
+
+  //=====================  插件自动生成-无需手动修改  ↓  ===================================
+
+//<editor-fold desc="Data Methods">
+
+  AppConfig({
+    this.androidDeviceInfo,
+    this.iosDeviceInfo,
+    this.packageInfo,
+    this.mSize,
+    this.mRatio,
+    this.width,
+    this.height,
+    required this.whRatio,
+    required this.density,
+    required this.isFullScreenDevice,
+    this.topPadding,
+    this.bottomPadding,
+    this.textScaleFactor,
+    this.platformBrightness,
+    this.viewInsets,
+    this.padding,
+    this.alwaysUse24HourFormat,
+    this.accessibleNavigation,
+    this.invertColors,
+    this.disableAnimations,
+    this.boldText,
+    this.orientation,
+    required double? safeAreaPaddingTop,
+    required double? safeAreaPaddingBottom,
+  })  : _safeAreaPaddingTop = safeAreaPaddingTop,
+        _safeAreaPaddingBottom = safeAreaPaddingBottom;
+
+  @override
+  bool operator ==(Object other) =>
+      identical(this, other) ||
+      (other is AppConfig &&
+          runtimeType == other.runtimeType &&
+          androidDeviceInfo == other.androidDeviceInfo &&
+          iosDeviceInfo == other.iosDeviceInfo &&
+          packageInfo == other.packageInfo &&
+          _safeAreaPaddingTop == other._safeAreaPaddingTop &&
+          _safeAreaPaddingBottom == other._safeAreaPaddingBottom &&
+          mSize == other.mSize &&
+          mRatio == other.mRatio &&
+          width == other.width &&
+          height == other.height &&
+          whRatio == other.whRatio &&
+          density == other.density &&
+          isFullScreenDevice == other.isFullScreenDevice &&
+          topPadding == other.topPadding &&
+          bottomPadding == other.bottomPadding &&
+          textScaleFactor == other.textScaleFactor &&
+          platformBrightness == other.platformBrightness &&
+          viewInsets == other.viewInsets &&
+          padding == other.padding &&
+          alwaysUse24HourFormat == other.alwaysUse24HourFormat &&
+          accessibleNavigation == other.accessibleNavigation &&
+          invertColors == other.invertColors &&
+          disableAnimations == other.disableAnimations &&
+          boldText == other.boldText &&
+          orientation == other.orientation);
+
+  @override
+  int get hashCode =>
+      androidDeviceInfo.hashCode ^
+      iosDeviceInfo.hashCode ^
+      packageInfo.hashCode ^
+      _safeAreaPaddingTop.hashCode ^
+      _safeAreaPaddingBottom.hashCode ^
+      mSize.hashCode ^
+      mRatio.hashCode ^
+      width.hashCode ^
+      height.hashCode ^
+      whRatio.hashCode ^
+      density.hashCode ^
+      isFullScreenDevice.hashCode ^
+      topPadding.hashCode ^
+      bottomPadding.hashCode ^
+      textScaleFactor.hashCode ^
+      platformBrightness.hashCode ^
+      viewInsets.hashCode ^
+      padding.hashCode ^
+      alwaysUse24HourFormat.hashCode ^
+      accessibleNavigation.hashCode ^
+      invertColors.hashCode ^
+      disableAnimations.hashCode ^
+      boldText.hashCode ^
+      orientation.hashCode;
+
+  @override
+  String toString() {
+    return 'AppConfig{' +
+        ' androidDeviceInfo: $androidDeviceInfo,' +
+        ' iosDeviceInfo: $iosDeviceInfo,' +
+        ' packageInfo: $packageInfo,' +
+        ' _safeAreaPaddingTop: $_safeAreaPaddingTop,' +
+        ' _safeAreaPaddingBottom: $_safeAreaPaddingBottom,' +
+        ' mSize: $mSize,' +
+        ' mRatio: $mRatio,' +
+        ' width: $width,' +
+        ' height: $height,' +
+        ' whRatio: $whRatio,' +
+        ' density: $density,' +
+        ' isFullScreenDevice: $isFullScreenDevice,' +
+        ' topPadding: $topPadding,' +
+        ' bottomPadding: $bottomPadding,' +
+        ' textScaleFactor: $textScaleFactor,' +
+        ' platformBrightness: $platformBrightness,' +
+        ' viewInsets: $viewInsets,' +
+        ' padding: $padding,' +
+        ' alwaysUse24HourFormat: $alwaysUse24HourFormat,' +
+        ' accessibleNavigation: $accessibleNavigation,' +
+        ' invertColors: $invertColors,' +
+        ' disableAnimations: $disableAnimations,' +
+        ' boldText: $boldText,' +
+        ' orientation: $orientation,' +
+        '}';
+  }
+
+  AppConfig copyWith({
+    AndroidDeviceInfo? androidDeviceInfo,
+    IosDeviceInfo? iosDeviceInfo,
+    PackageInfo? packageInfo,
+    double? safeAreaPaddingTop,
+    double? safeAreaPaddingBottom,
+    Size? mSize,
+    double? mRatio,
+    double? width,
+    double? height,
+    double? whRatio,
+    double? density,
+    bool? isFullScreenDevice,
+    double? topPadding,
+    double? bottomPadding,
+    double? textScaleFactor,
+    Brightness? platformBrightness,
+    EdgeInsets? viewInsets,
+    EdgeInsets? padding,
+    bool? alwaysUse24HourFormat,
+    bool? accessibleNavigation,
+    bool? invertColors,
+    bool? disableAnimations,
+    bool? boldText,
+    Orientation? orientation,
+  }) {
+    return AppConfig(
+      androidDeviceInfo: androidDeviceInfo ?? this.androidDeviceInfo,
+      iosDeviceInfo: iosDeviceInfo ?? this.iosDeviceInfo,
+      packageInfo: packageInfo ?? this.packageInfo,
+      safeAreaPaddingTop: safeAreaPaddingTop ?? this._safeAreaPaddingTop,
+      safeAreaPaddingBottom: safeAreaPaddingBottom ?? this._safeAreaPaddingBottom,
+      mSize: mSize ?? this.mSize,
+      mRatio: mRatio ?? this.mRatio,
+      width: width ?? this.width,
+      height: height ?? this.height,
+      whRatio: whRatio ?? this.whRatio,
+      density: density ?? this.density,
+      isFullScreenDevice: isFullScreenDevice ?? this.isFullScreenDevice,
+      topPadding: topPadding ?? this.topPadding,
+      bottomPadding: bottomPadding ?? this.bottomPadding,
+      textScaleFactor: textScaleFactor ?? this.textScaleFactor,
+      platformBrightness: platformBrightness ?? this.platformBrightness,
+      viewInsets: viewInsets ?? this.viewInsets,
+      padding: padding ?? this.padding,
+      alwaysUse24HourFormat: alwaysUse24HourFormat ?? this.alwaysUse24HourFormat,
+      accessibleNavigation: accessibleNavigation ?? this.accessibleNavigation,
+      invertColors: invertColors ?? this.invertColors,
+      disableAnimations: disableAnimations ?? this.disableAnimations,
+      boldText: boldText ?? this.boldText,
+      orientation: orientation ?? this.orientation,
+    );
+  }
+
+//</editor-fold>
+}

+ 113 - 0
packages/cs_plugin_basic/lib/provider/app_config/app_config_service.dart

@@ -0,0 +1,113 @@
+import 'package:device_info_plus/device_info_plus.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:package_info_plus/package_info_plus.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/device_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/screen_util.dart';
+import 'app_config.dart';
+
+part 'app_config_service.g.dart';
+
+@Riverpod(keepAlive: true)
+class AppConfigService extends _$AppConfigService {
+  @override
+  AppConfig build() {
+    return AppConfig(
+      whRatio: 1,
+      isFullScreenDevice: false,
+      safeAreaPaddingTop: 0,
+      safeAreaPaddingBottom: 0,
+      density: 0,
+    );
+  }
+
+  Future initAsync() async {
+    final startTime = DateTime.now();
+    Log.d('----AppConfigService------initAsync() --  start ---');
+
+    // package_info 插件获取到App的包信息
+    final packageInfo = await PackageInfo.fromPlatform();
+    var configState = state.copyWith(packageInfo: packageInfo);
+
+    // device_info_plus插件获取设备信息
+    DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
+    if (DeviceUtils.isIOS) {
+      //赋值iOS信息
+      configState.iosDeviceInfo = await deviceInfoPlugin.iosInfo;
+    } else if (DeviceUtils.isAndroid) {
+      //赋值Android信息
+      configState.androidDeviceInfo = await deviceInfoPlugin.androidInfo;
+    }
+
+    state = configState;
+
+    Log.d('----AppConfigService------initAsync() --  end 任务耗时:${DateTime.now().difference(startTime).inMilliseconds} ms ---');
+  }
+
+  void initSize(BuildContext context) {
+    //屏幕大小
+    final size = MediaQuery.of(context).size;
+    //密度
+    final ratio = MediaQuery.of(context).devicePixelRatio;
+    //设备像素 px
+    final width = size.width * ratio;
+    final height = size.height * ratio;
+
+    var configState = state.copyWith(
+      mSize: size,
+      mRatio: ratio,
+      width: width,
+      height: height,
+      whRatio: height / width,
+      isFullScreenDevice: (height / width) > 1.9,
+      topPadding: MediaQuery.of(context).padding.top,
+      bottomPadding: MediaQuery.of(context).padding.bottom,
+      textScaleFactor: MediaQuery.of(context).textScaleFactor,
+      platformBrightness: MediaQuery.of(context).platformBrightness,
+      viewInsets: MediaQuery.of(context).viewInsets,
+      padding: MediaQuery.of(context).padding,
+      alwaysUse24HourFormat: MediaQuery.of(context).alwaysUse24HourFormat,
+      accessibleNavigation: MediaQuery.of(context).accessibleNavigation,
+      invertColors: MediaQuery.of(context).invertColors,
+      disableAnimations: MediaQuery.of(context).disableAnimations,
+      boldText: MediaQuery.of(context).boldText,
+      orientation: MediaQuery.of(context).orientation,
+      density: MediaQuery.devicePixelRatioOf(context),
+    );
+
+    state = configState;
+
+    //初始化Flustarts工具类中 ScreenUtils 工具,可以设置设计稿的大小,可以选择性的使用 getAdapterSizeCtx 适配大小屏不同尺寸的展示
+    setDesignWHD(375, 667, density: configState.density);
+
+    printAppConfig();
+  }
+
+  /// 测试并打印数据
+  void printAppConfig() {
+    Log.d('AppConfig 是否是Release环境 ${state.isRelease}');
+    Log.d('AppConfig 插件获获取到的app【appName】${state.appName}');
+    Log.d('AppConfig 插件获获取到的app【packageName】${state.packageName}');
+    Log.d('AppConfig 插件获获取到的app【version】${state.version}');
+    Log.d('AppConfig 插件获获取到的app【buildNumber】${state.buildNumber}');
+    Log.d('AppConfig 插件获取到设备信息【iosDeviceInfo】${state.iosDeviceInfo}');
+    Log.d('AppConfig 插件获取到设备信息【androidDeviceInfo】${state.androidDeviceInfo}');
+    Log.d('AppConfig---设备像素比dpr(物理像素/逻辑像素)【mRatio】:${state.mRatio}');
+    Log.d('AppConfig--- ScreenUtil像素比: ${state.density}');
+    Log.d('AppConfig---逻辑像素pt【mSize.width * mSize.height】:${state.mSize!.width} x ${state.mSize!.height}');
+    Log.d('AppConfig---屏幕分辨率px(物理像素)【mSize.width * mRatio】 X【mSize.height * mRatio】:${state.width} x ${state.height} 屏幕的宽高比:${state.whRatio}');
+    Log.d('AppConfig---上边刘海(状态栏)【MediaQuery.of(context).padding.top】: ${state.topPadding}');
+    Log.d('AppConfig---下边导航【MediaQuery.of(context).padding.bottom】:  ${state.bottomPadding}');
+    Log.d('AppConfig---textScaleFactor【MediaQuery.of(context).textScaleFactor】: ${state.textScaleFactor}');
+    Log.d('AppConfig---platformBrightness【MediaQuery.of(context).platformBrightness】: ${state.platformBrightness}');
+    Log.d('AppConfig---viewInsets【MediaQuery.of(context).viewInsets】: ${state.viewInsets}');
+    Log.d('AppConfig---padding【MediaQuery.of(context).padding】: ${state.padding}');
+    Log.d('AppConfig---alwaysUse24HourFormat: ${state.alwaysUse24HourFormat}');
+    Log.d('AppConfig---accessibleNavigation: ${state.accessibleNavigation}');
+    Log.d('AppConfig---invertColors: ${state.invertColors}');
+    Log.d('AppConfig---disableAnimations: ${state.disableAnimations}');
+    Log.d('AppConfig---boldText: ${state.boldText}');
+    Log.d('AppConfig---orientation:${state.orientation}');
+  }
+}

+ 26 - 0
packages/cs_plugin_basic/lib/provider/app_config/app_config_service.g.dart

@@ -0,0 +1,26 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'app_config_service.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$appConfigServiceHash() => r'9b335afd361b5b0d5c354977fadec7bb7235b013';
+
+/// See also [AppConfigService].
+@ProviderFor(AppConfigService)
+final appConfigServiceProvider =
+    NotifierProvider<AppConfigService, AppConfig>.internal(
+  AppConfigService.new,
+  name: r'appConfigServiceProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$appConfigServiceHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$AppConfigService = Notifier<AppConfig>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 4 - 0
packages/cs_plugin_basic/lib/provider/global_provider_container.dart

@@ -0,0 +1,4 @@
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+
+//全局单例的Provider 用于非UI无ref对象的场景引入
+final globalContainer = ProviderContainer();

+ 19 - 0
packages/cs_plugin_basic/lib/provider/http_provider/http_provider.dart

@@ -0,0 +1,19 @@
+import 'package:domain/constants/api_constants.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:plugin_platform/http/http_provider.dart';
+
+import '../../dio_interceptors/interceptor_auth_dio.dart';
+import '../../dio_interceptors/interceptor_status_code_dio.dart';
+
+part 'http_provider.g.dart';
+
+@Riverpod(keepAlive: true)
+HttpProvider http(Ref ref) {
+
+  return HttpProvider(
+    ApiConstants.baseUrl,
+    interceptors: [StatusCodeDioInterceptors(), AuthDioInterceptors()], //需要加上与App关联的一些拦截处理
+  );
+}
+

+ 26 - 0
packages/cs_plugin_basic/lib/provider/http_provider/http_provider.g.dart

@@ -0,0 +1,26 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'http_provider.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$httpHash() => r'7a58e9288487d9685e6b32abb754a1a84ba1844e';
+
+/// See also [http].
+@ProviderFor(http)
+final httpProvider = Provider<HttpProvider>.internal(
+  http,
+  name: r'httpProvider',
+  debugGetCreateSourceHash:
+      const bool.fromEnvironment('dart.vm.product') ? null : _$httpHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef HttpRef = ProviderRef<HttpProvider>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 84 - 0
packages/cs_plugin_basic/lib/provider/user_config/user_config.dart

@@ -0,0 +1,84 @@
+// 用户相关的操作状态 State 类,用于 RiverPod 中 Provider 的定义
+class UserConfig {
+  //用户的详情信息
+  // UserProfile userProfile;
+
+  //用户的登录Token
+  String? token;
+
+  //用户是否已经登录
+  bool haslogin = false;
+
+  //用户的 registrationId 推送标识
+  String? registrationId;
+
+  //用户的未读消息数量
+  int unreadNotificationsCount = 0;
+
+// ===================================  插件自动生成-无需手动修改  ↓  ===================================
+
+  //<editor-fold desc="Data Methods">
+  UserConfig({
+    this.token,
+    required this.haslogin,
+    required this.registrationId,
+    required this.unreadNotificationsCount,
+  });
+
+  @override
+  bool operator ==(Object other) =>
+      identical(this, other) ||
+      (other is UserConfig &&
+          runtimeType == other.runtimeType &&
+          token == other.token &&
+          haslogin == other.haslogin &&
+          registrationId == other.registrationId &&
+          unreadNotificationsCount == other.unreadNotificationsCount);
+
+  @override
+  int get hashCode => token.hashCode ^ haslogin.hashCode ^ registrationId.hashCode ^ unreadNotificationsCount.hashCode;
+
+  @override
+  String toString() {
+    return 'UserConfig{' +
+        ' token: $token,' +
+        ' haslogin: $haslogin,' +
+        ' registrationId: $registrationId,' +
+        ' unreadNotificationsCount: $unreadNotificationsCount,' +
+        '}';
+  }
+
+  UserConfig copyWith({
+    String? token,
+    bool? haslogin,
+    String? registrationId,
+    int? unreadNotificationsCount,
+  }) {
+    return UserConfig(
+      token: token ?? this.token,
+      haslogin: haslogin ?? this.haslogin,
+      registrationId: registrationId ?? this.registrationId,
+      unreadNotificationsCount: unreadNotificationsCount ?? this.unreadNotificationsCount,
+    );
+  }
+
+  Map<String, dynamic> toMap() {
+    return {
+      'token': this.token,
+      'haslogin': this.haslogin,
+      'registrationId': this.registrationId,
+      'unreadNotificationsCount': this.unreadNotificationsCount,
+    };
+  }
+
+  factory UserConfig.fromMap(Map<String, dynamic> map) {
+    return UserConfig(
+      token: map['token'] as String,
+      haslogin: map['haslogin'] as bool,
+      registrationId: map['registrationId'] as String,
+      unreadNotificationsCount: map['unreadNotificationsCount'] as int,
+    );
+  }
+
+//</editor-fold>
+}

+ 46 - 0
packages/cs_plugin_basic/lib/provider/user_config/user_config_service.dart

@@ -0,0 +1,46 @@
+import 'package:plugin_basic/provider/user_config/user_config.dart';
+import 'package:plugin_platform/engine/sp/sp_util.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
+
+import '../../constants/app_constant.dart';
+
+part 'user_config_service.g.dart';
+
+/*
+ * 用户的信息与状态的服务 - 全局单例
+ */
+@Riverpod(keepAlive: true)
+class UserConfigService extends _$UserConfigService {
+  @override
+  UserConfig build() {
+    String? token = SPUtil.getString(AppConstant.storageToken);
+    Log.d('UserService - 查询SP token:$token 并赋值');
+    return UserConfig(token: token, haslogin: false, registrationId: null, unreadNotificationsCount: 0);
+  }
+
+  /// 设置全局的Token,同时更新 hasLogin 的值,赋值时机如下
+  void setToken(String? token) {
+    UserConfig configState = state.copyWith(token: token);
+
+    if (Utils.isEmpty(token)) {
+      configState.copyWith(haslogin: false);
+      SPUtil.remove(AppConstant.storageToken);
+    } else {
+      configState.copyWith(haslogin: true);
+      SPUtil.putString(AppConstant.storageToken, token!);
+    }
+
+    state = configState;
+
+    Log.d('UserService =========> 设置Token为:$token');
+  }
+
+  /// 处理退出登录之后的数据清除
+  void handleLogoutParams() {
+    SPUtil.remove(AppConstant.storageToken);
+    state = state.copyWith(haslogin: false);
+    // hotelInfo = HotelInfoEntity();
+  }
+}

+ 26 - 0
packages/cs_plugin_basic/lib/provider/user_config/user_config_service.g.dart

@@ -0,0 +1,26 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'user_config_service.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$userConfigServiceHash() => r'b6990fa6d1ddc625877f48661e6df875a876acc6';
+
+/// See also [UserConfigService].
+@ProviderFor(UserConfigService)
+final userConfigServiceProvider =
+    NotifierProvider<UserConfigService, UserConfig>.internal(
+  UserConfigService.new,
+  name: r'userConfigServiceProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$userConfigServiceHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$UserConfigService = Notifier<UserConfig>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 21 - 0
packages/cs_plugin_basic/lib/router/basic_page_router.dart

@@ -0,0 +1,21 @@
+import 'package:auto_route/auto_route.dart';
+import 'package:flutter/material.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:router/path/router_path.dart';
+
+import '../modules/global_web_page.dart';
+import '../modules/preview_photo_page.dart';
+
+part 'basic_page_router.gr.dart';
+
+/*\
+ * 全局的通用页面的路由
+ */
+@AutoRouterConfig(replaceInRouteName: 'Page|Screen,PageRoute')
+class BasicPageRouter extends _$BasicPageRouter {
+  @override
+  List<AutoRoute> get routes => [
+        CustomRoute(page: GlobalWebPageRoute.page, path: RouterPath.globalWeb, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: PreviewPhotoPageRoute.page, path: RouterPath.previewImage, transitionsBuilder: applySlideTransition),
+      ];
+}

+ 144 - 0
packages/cs_plugin_basic/lib/router/basic_page_router.gr.dart

@@ -0,0 +1,144 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+// **************************************************************************
+// AutoRouterGenerator
+// **************************************************************************
+
+// ignore_for_file: type=lint
+// coverage:ignore-file
+
+part of 'basic_page_router.dart';
+
+abstract class _$BasicPageRouter extends RootStackRouter {
+  // ignore: unused_element
+  _$BasicPageRouter({super.navigatorKey});
+
+  @override
+  final Map<String, PageFactory> pagesMap = {
+    GlobalWebPageRoute.name: (routeData) {
+      final pathParams = routeData.inheritedPathParams;
+      final args = routeData.argsAs<GlobalWebPageRouteArgs>(
+          orElse: () => GlobalWebPageRouteArgs(
+                isShowAppBar: pathParams.getBool('isShowAppBar'),
+                initialUrl: pathParams.getString('initialUrl'),
+                title: pathParams.getString('title'),
+              ));
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: GlobalWebPage(
+          key: args.key,
+          isShowAppBar: args.isShowAppBar,
+          initialUrl: args.initialUrl,
+          title: args.title,
+        ),
+      );
+    },
+    PreviewPhotoPageRoute.name: (routeData) {
+      final args = routeData.argsAs<PreviewPhotoPageRouteArgs>();
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: PreviewPhotoPage(
+          key: args.key,
+          images: args.images,
+          position: args.position,
+        ),
+      );
+    },
+  };
+}
+
+/// generated route for
+/// [GlobalWebPage]
+class GlobalWebPageRoute extends PageRouteInfo<GlobalWebPageRouteArgs> {
+  GlobalWebPageRoute({
+    Key? key,
+    required bool isShowAppBar,
+    required String initialUrl,
+    required String title,
+    List<PageRouteInfo>? children,
+  }) : super(
+          GlobalWebPageRoute.name,
+          args: GlobalWebPageRouteArgs(
+            key: key,
+            isShowAppBar: isShowAppBar,
+            initialUrl: initialUrl,
+            title: title,
+          ),
+          rawPathParams: {
+            'isShowAppBar': isShowAppBar,
+            'initialUrl': initialUrl,
+            'title': title,
+          },
+          initialChildren: children,
+        );
+
+  static const String name = 'GlobalWebPageRoute';
+
+  static const PageInfo<GlobalWebPageRouteArgs> page =
+      PageInfo<GlobalWebPageRouteArgs>(name);
+}
+
+class GlobalWebPageRouteArgs {
+  const GlobalWebPageRouteArgs({
+    this.key,
+    required this.isShowAppBar,
+    required this.initialUrl,
+    required this.title,
+  });
+
+  final Key? key;
+
+  final bool isShowAppBar;
+
+  final String initialUrl;
+
+  final String title;
+
+  @override
+  String toString() {
+    return 'GlobalWebPageRouteArgs{key: $key, isShowAppBar: $isShowAppBar, initialUrl: $initialUrl, title: $title}';
+  }
+}
+
+/// generated route for
+/// [PreviewPhotoPage]
+class PreviewPhotoPageRoute extends PageRouteInfo<PreviewPhotoPageRouteArgs> {
+  PreviewPhotoPageRoute({
+    Key? key,
+    required List<String> images,
+    required int position,
+    List<PageRouteInfo>? children,
+  }) : super(
+          PreviewPhotoPageRoute.name,
+          args: PreviewPhotoPageRouteArgs(
+            key: key,
+            images: images,
+            position: position,
+          ),
+          initialChildren: children,
+        );
+
+  static const String name = 'PreviewPhotoPageRoute';
+
+  static const PageInfo<PreviewPhotoPageRouteArgs> page =
+      PageInfo<PreviewPhotoPageRouteArgs>(name);
+}
+
+class PreviewPhotoPageRouteArgs {
+  const PreviewPhotoPageRouteArgs({
+    this.key,
+    required this.images,
+    required this.position,
+  });
+
+  final Key? key;
+
+  final List<String> images;
+
+  final int position;
+
+  @override
+  String toString() {
+    return 'PreviewPhotoPageRouteArgs{key: $key, images: $images, position: $position}';
+  }
+}

+ 0 - 213
packages/cs_plugin_basic/lib/service/app_config_service.dart

@@ -1,213 +0,0 @@
-import 'dart:ui';
-
-import 'package:device_info_plus/device_info_plus.dart';
-import 'package:flutter/material.dart';
-
-import 'package:package_info_plus/package_info_plus.dart';
-import 'package:plugin_basic/service/config_services_injection.dart';
-import 'package:shared/utils/device_utils.dart';
-import 'package:shared/utils/log_utils.dart';
-import 'package:shared/utils/screen_util.dart';
-
-/*
- * 获取并保存当前应用的信息。
- * 获取并保存当前设备的信息。
- */
-class ConfigService {
-
-  // 设备信息
-  /// android 设备信息
-  AndroidDeviceInfo? androidDeviceInfo;
-
-  /// ios 设备信息
-  IosDeviceInfo? iosDeviceInfo;
-
-  // 当前的languageCode
-  Locale locale = PlatformDispatcher.instance.locale;
-  PackageInfo? _appPackageInfo;
-
-  String get version => _appPackageInfo?.version ?? '-';
-
-  String get appName => _appPackageInfo?.appName ?? '-';
-
-  String get packageName => _appPackageInfo?.packageName ?? '-';
-
-  String get buildNumber => _appPackageInfo?.buildNumber ?? '-';
-
-  // final RxBool _isDarkModel = Get.isDarkMode.obs;
-
-  // 是否是暗黑模式
-  // bool get isDarkModel => _isDarkModel.value;
-
-  // 顶部安全距离(pt)
-  double get safeAreaPaddingTop => _safeAreaPaddingTop!;
-
-  // 底部安全距离(pt)
-  double get safeAreaPaddingBottom => _safeAreaPaddingBottom!;
-
-  double? _safeAreaPaddingTop;
-  double? _safeAreaPaddingBottom;
-
-  //屏幕大小
-  Size? mSize;
-
-  //密度
-  double? mRatio;
-
-  //设备像素px
-  double? width;
-  double? height;
-
-  //设备宽高比,大于1.9是全面屏手机
-  double whRatio = 1;
-
-  //是否是全面屏设备(宽高比大于1.9)
-  bool isFullScreenDevice = false;
-
-  // 上下边距 (主要用于 刘海  和  内置导航键)
-  double? topPadding;
-  double? bottomPadding;
-  double? textScaleFactor;
-
-  Brightness? platformBrightness;
-  EdgeInsets? viewInsets;
-  EdgeInsets? padding;
-  bool? alwaysUse24HourFormat;
-  bool? accessibleNavigation;
-  bool? invertColors;
-  bool? disableAnimations;
-  bool? boldText;
-  Orientation? orientation;
-
-
-  void init() {
-
-    //打印应用与设备的信息
-    getDeviceInfo();
-    getAppInfos();
-
-    //打印当前设备的一些Media信息
-    // getMediaInfo(context: Get.context!);
-    // paddingSizeTop(context: Get.context!);
-    // paddingSizeBottom(context: Get.context!);
-  }
-
-  // ServicesInjection 已经获取到了信息,直接赋值过来并打印当前的应用信息
-  Future<void> getAppInfos() async {
-    // package_info 插件获取到当前运行平台上App的包信息
-    _appPackageInfo = ConfigServicesInjection.packageInfo;
-
-    Log.d('package_info 插件获获取到的app【appName】$appName');
-    Log.d('package_info 插件获获取到的app【packageName】$packageName');
-    Log.d('package_info 插件获获取到的app【version】$version');
-    Log.d('package_info 插件获获取到的app【buildNumber】$buildNumber');
-  }
-
-  // ServicesInjection 已经获取到了信息,直接赋值过来并打印当前的设备信息
-  void getDeviceInfo() {
-    if (DeviceUtils.isIOS) {
-      iosDeviceInfo = ConfigServicesInjection.iosDeviceInfo;
-      Log.d('device_info_plus插件获取到设备信息【iosDeviceInfo】$iosDeviceInfo');
-    } else if (DeviceUtils.isAndroid) {
-      androidDeviceInfo = ConfigServicesInjection.androidDeviceInfo;
-      Log.d('device_info_plus插件获取到设备信息【androidDeviceInfo】$androidDeviceInfo');
-    }
-  }
-
-
-  // 获取media相关信息
-  void getMediaInfo({BuildContext? context}) {
-    //屏幕大小
-    mSize = MediaQuery.of(context!).size;
-    //密度
-    mRatio = MediaQuery.of(context).devicePixelRatio;
-    //设备像素 px
-    width = mSize!.width * mRatio!;
-    height = mSize!.height * mRatio!;
-    whRatio = (height ?? 1) / (width ?? 1);
-    isFullScreenDevice = whRatio > 1.9;
-
-    // 上下边距 (主要用于 刘海  和  内置导航键)
-    topPadding = MediaQuery.of(context).padding.top;
-    bottomPadding = MediaQuery.of(context).padding.bottom;
-    textScaleFactor = MediaQuery.of(context).textScaleFactor;
-
-    platformBrightness = MediaQuery.of(context).platformBrightness;
-    viewInsets = MediaQuery.of(context).viewInsets;
-    padding = MediaQuery.of(context).padding;
-    alwaysUse24HourFormat = MediaQuery.of(context).alwaysUse24HourFormat;
-    accessibleNavigation = MediaQuery.of(context).accessibleNavigation;
-    invertColors = MediaQuery.of(context).invertColors;
-    disableAnimations = MediaQuery.of(context).disableAnimations;
-    boldText = MediaQuery.of(context).boldText;
-    orientation = MediaQuery.of(context).orientation;
-    final screenDensity = MediaQuery.devicePixelRatioOf(context);
-
-    //初始化Flustarts工具类中 ScreenUtils 工具,可以设置设计稿的大小,可以选择性的使用 getAdapterSizeCtx 适配大小屏不同尺寸的展示
-    setDesignWHD(375, 667, density: screenDensity);
-
-    Log.d('service-app_config_service.dart---设备信息【MediaQuery.of(context)】:${MediaQuery.of(context)}');
-
-    Log.d('service-app_config_service.dart---设备像素比dpr(物理像素/逻辑像素)【mRatio】:$mRatio');
-    Log.d('service-app_config_service.dart--- ScreenUtil像素比: $screenDensity');
-
-    Log.d('service-app_config_service.dart---逻辑像素pt【mSize.width * mSize.height】:${mSize!.width} x ${mSize!.height}');
-    Log.d('service-app_config_service.dart---屏幕分辨率px(物理像素)【mSize.width * mRatio】 X 【mSize.height * mRatio】:$width x $height '
-        '屏幕的宽高比:$whRatio');
-
-    Log.d('service-app_config_service.dart---上边刘海(状态栏)【MediaQuery.of(context).padding.top】:$topPadding');
-    Log.d('service-app_config_service.dart---下边导航【MediaQuery.of(context).padding.bottom】:$bottomPadding');
-
-    Log.d('service-app_config_service.dart---textScaleFactor【MediaQuery.of(context).textScaleFactor】: $textScaleFactor');
-    Log.d('service-app_config_service.dart---platformBrightness【MediaQuery.of(context).platformBrightness】: $platformBrightness');
-    Log.d('service-app_config_service.dart---viewInsets【MediaQuery.of(context).viewInsets】: $viewInsets');
-    Log.d('service-app_config_service.dart---padding【MediaQuery.of(context).padding】: $padding');
-    Log.d('service-app_config_service.dart---alwaysUse24HourFormat: $alwaysUse24HourFormat');
-    Log.d('service-app_config_service.dart---accessibleNavigation: $accessibleNavigation');
-    Log.d('service-app_config_service.dart---invertColors: $invertColors');
-    Log.d('service-app_config_service.dart---disableAnimations: $disableAnimations');
-    Log.d('service-app_config_service.dart---boldText: $boldText');
-    Log.d('service-app_config_service.dart---orientation: $orientation');
-  }
-
-  double paddingSizeBottom({required BuildContext context}) {
-    final MediaQueryData data = MediaQuery.of(context);
-    EdgeInsets padding = data.padding;
-    padding = padding.copyWith(bottom: data.viewPadding.bottom);
-    Log.d("glabalService-config.dart该设备底部的安全距离为----${padding.bottom}");
-    _safeAreaPaddingBottom = padding.bottom;
-    return padding.bottom;
-  }
-
-  double paddingSizeTop({required BuildContext context}) {
-    final MediaQueryData data = MediaQuery.of(context);
-    EdgeInsets padding = data.padding;
-    padding = padding.copyWith(top: data.viewPadding.top);
-    Log.d("glabalService-config.dart该设备顶部的安全距离为----${padding.top}");
-    _safeAreaPaddingTop = padding.top;
-    return padding.top;
-  }
-
-  int compareVersionNumbers(String version1, String version2) {
-    List<int> v1 = version1.split('.').map(int.parse).toList();
-    List<int> v2 = version2.split('.').map(int.parse).toList();
-
-    int minLength = v1.length < v2.length ? v1.length : v2.length;
-
-    for (int i = 0; i < minLength; i++) {
-      if (v1[i] < v2[i]) {
-        return -1; // version1 < version2
-      } else if (v1[i] > v2[i]) {
-        return 1;
-      }
-    }
-
-    if (v1.length < v2.length) {
-      return -1;
-    } else if (v1.length > v2.length) {
-      return 1; // version1 > version2
-    }
-
-    return 0; //version1 = version2
-  }
-}

+ 0 - 59
packages/cs_plugin_basic/lib/service/config_services_injection.dart

@@ -1,59 +0,0 @@
-import 'package:device_info_plus/device_info_plus.dart';
-import 'package:package_info_plus/package_info_plus.dart';
-import 'package:shared/utils/device_utils.dart';
-import 'package:shared/utils/log_utils.dart';
-
-import 'app_config_service.dart';
-
-
-/*
-   全局服务 Service 的初始化入口
-
-   1. 初始化 AppPackageInfo 插件,获取应用相关信息。
-   2. 初始化 DeviceInfo 插件,获取设备相关信息。
-
-   全局一些服务的注入与信息的保存。
-   注意:最好是用户同意了隐私协议之后再初始化
- */
-class ConfigServicesInjection {
-  /// android 设备信息
-  static AndroidDeviceInfo? androidDeviceInfo;
-
-  /// ios 设备信息
-  static IosDeviceInfo? iosDeviceInfo;
-
-  /// 包信息
-  static PackageInfo? packageInfo;
-
-  /// 是否 release  包(生产环境)
-  static bool get isRelease => const bool.fromEnvironment("dart.vm.product");
-
-  /// init
-  static Future init() async {
-    Log.d('----ConfigServicesInjection------start-----');
-
-    // device_info_plus插件获取设备信息
-    DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
-    if (DeviceUtils.isIOS) {
-      ConfigServicesInjection.iosDeviceInfo = await deviceInfoPlugin.iosInfo;
-    } else if (DeviceUtils.isAndroid) {
-      ConfigServicesInjection.androidDeviceInfo = await deviceInfoPlugin.androidInfo;
-    }
-
-    // package_info 插件获取到App的包信息
-    ConfigServicesInjection.packageInfo = await PackageInfo.fromPlatform();
-
-    // 一些配置信息的全局单例保存 (国际化、版本信息、设备信息、主题(暗黑/明亮))
-    // Get.put<ConfigService>(ConfigService());
-
-  }
-
-  // 获取当前Android设备的Android版本
-  static int getAndroidSdkInt() {
-    if (DeviceUtils.isAndroid) {
-      return androidDeviceInfo?.version.sdkInt ?? -1;
-    } else {
-      return -1;
-    }
-  }
-}

+ 0 - 30
packages/cs_plugin_basic/lib/service/http_provider_injection.dart

@@ -1,30 +0,0 @@
-import 'package:domain/constants/api_constants.dart';
-import 'package:plugin_basic/constants/app_constant.dart';
-import 'package:plugin_platform/engine/sp/sp_util.dart';
-import 'package:plugin_platform/http/http_provider.dart';
-
-import '../basic_export.dart';
-import '../dio_interceptors/interceptor_auth_dio.dart';
-import '../dio_interceptors/interceptor_status_code_dio.dart';
-
-class HttpProviderInjection {
-  // 设置默认的
-  static void putHttpProviderByCountry() {
-
-    //注入 HttpProvider
-    // Get.put(
-    //     HttpProvider(
-    //       ApiConstants.baseUrl,
-    //       interceptors: [StatusCodeDioInterceptors(), AuthDioInterceptors()], //需要加上与App关联的一些拦截处理
-    //     ),
-    //     permanent: true);
-  }
-
-  // 切换应用的BaseUrl的逻辑
-  static void switchBaseUrl(String baseUrl) {
-    //找到单例对象 HttpProvider,切换域名
-    // HttpProvider httpProvider = Get.find();
-    // httpProvider.switchBaseUrl(baseUrl);
-
-  }
-}

+ 0 - 60
packages/cs_plugin_basic/lib/service/user_service.dart

@@ -1,60 +0,0 @@
-import 'dart:core';
-
-import 'package:plugin_platform/engine/sp/sp_util.dart';
-import 'package:shared/utils/event_bus.dart';
-import 'package:shared/utils/log_utils.dart';
-import 'package:shared/utils/util.dart';
-
-import '../constants/app_constant.dart';
-
-/// 用户相关的单例服务,保存了Token,UserProfile等信息
-class UserService {
-  UserService();
-
-  //用户登录Token
-  String? token;
-
-  //用户是否已经登录 - 可变字段
-  bool haslogin = false;
-
-  //用户详情信息 - 可变字段
-  // Rx<HotelInfoEntity> hotelInfo = HotelInfoEntity();
-  //极光推送的 registrationId - 可变字段
-  String registrationId = '';
-
-  //当前用户的未读消息数量
-  int unreadNotificationsCount = 0;
-
-  /// 设置全局的Token,同时更新 hasLogin 的值,赋值时机如下
-  /*
-      1. 在登录或注册成功的时候赋值
-      2. 在main.dart中初始化的时候查询是否有Token,如果有的话需要赋值
-      3. 退出登录的时候需要赋值
-   */
-  void setToken(String? token) {
-    this.token = token;
-
-    if (Utils.isEmpty(token)) {
-      haslogin = false;
-      SPUtil.remove(AppConstant.storageToken);
-    } else {
-      haslogin = true;
-      SPUtil.putString(AppConstant.storageToken, token!);
-    }
-
-    Log.d('UserService =========> 设置Token为:$token');
-  }
-
-  /// 处理退出登录之后的数据清除
-  void handleLogoutParams() {
-    SPUtil.remove(AppConstant.storageToken);
-    haslogin = false;
-    // hotelInfo = HotelInfoEntity();
-  }
-
-  void init() {
-    String? token = SPUtil.getString(AppConstant.storageToken);
-    Log.d('UserService - 查询SP token:$token 并赋值');
-    setToken(token);
-  }
-}

BIN
packages/cs_resources/assets/base_lib/black_back.webp


BIN
packages/cs_resources/assets/base_lib/dialog_blue_delete_icon.webp


BIN
packages/cs_resources/assets/base_lib/dialog_delete_icon.webp


BIN
packages/cs_resources/assets/base_lib/image_default_placeholder.png


BIN
packages/cs_resources/assets/base_lib/item_more_icon.webp


BIN
packages/cs_resources/assets/base_lib/search_icon.webp


BIN
packages/cs_resources/assets/base_lib/white_back.webp


BIN
packages/cs_resources/assets/base_service/border_widget_drop_down.webp


BIN
packages/cs_resources/assets/base_service/check_box_checked.webp


BIN
packages/cs_resources/assets/base_service/check_box_uncheck.webp


BIN
packages/cs_resources/assets/base_service/dialog_delete_icon.webp


BIN
packages/cs_resources/assets/base_service/item_selected_icon.webp


BIN
packages/cs_resources/assets/base_service/item_unselected_gray_icon.webp


BIN
packages/cs_resources/assets/base_service/item_unselected_icon.webp


BIN
packages/cs_resources/assets/base_service/page_load_error.webp


BIN
packages/cs_resources/assets/base_service/page_no_data.webp


BIN
packages/cs_resources/assets/base_service/radio_checked.webp


BIN
packages/cs_resources/assets/base_service/radio_uncheck.webp


BIN
packages/cs_resources/assets/base_service/rating_selected.webp


BIN
packages/cs_resources/assets/base_service/rating_unselected.webp


BIN
packages/cs_resources/assets/base_service/title_bar_filter_icon.webp


BIN
packages/cs_resources/assets/base_service/triangle_drop_down.webp


BIN
packages/cs_resources/assets/base_service/triangle_drop_down_icon.webp


+ 23 - 0
packages/cs_resources/lib/generated/assets.dart

@@ -3,5 +3,28 @@ class Assets {
   Assets._();
 
   static const String assetsYyBusinessTopLogo = 'assets/yy_business_top_logo.webp';
+  static const String baseLibBlackBack = 'assets/base_lib/black_back.webp';
+  static const String baseLibDialogBlueDeleteIcon = 'assets/base_lib/dialog_blue_delete_icon.webp';
+  static const String baseLibDialogDeleteIcon = 'assets/base_lib/dialog_delete_icon.webp';
+  static const String baseLibImageDefaultPlaceholder = 'assets/base_lib/image_default_placeholder.png';
+  static const String baseLibItemMoreIcon = 'assets/base_lib/item_more_icon.webp';
+  static const String baseLibSearchIcon = 'assets/base_lib/search_icon.webp';
+  static const String baseLibWhiteBack = 'assets/base_lib/white_back.webp';
+  static const String baseServiceBorderWidgetDropDown = 'assets/base_service/border_widget_drop_down.webp';
+  static const String baseServiceCheckBoxChecked = 'assets/base_service/check_box_checked.webp';
+  static const String baseServiceCheckBoxUncheck = 'assets/base_service/check_box_uncheck.webp';
+  static const String baseServiceDialogDeleteIcon = 'assets/base_service/dialog_delete_icon.webp';
+  static const String baseServiceItemSelectedIcon = 'assets/base_service/item_selected_icon.webp';
+  static const String baseServiceItemUnselectedGrayIcon = 'assets/base_service/item_unselected_gray_icon.webp';
+  static const String baseServiceItemUnselectedIcon = 'assets/base_service/item_unselected_icon.webp';
+  static const String baseServicePageLoadError = 'assets/base_service/page_load_error.webp';
+  static const String baseServicePageNoData = 'assets/base_service/page_no_data.webp';
+  static const String baseServiceRadioChecked = 'assets/base_service/radio_checked.webp';
+  static const String baseServiceRadioUncheck = 'assets/base_service/radio_uncheck.webp';
+  static const String baseServiceRatingSelected = 'assets/base_service/rating_selected.webp';
+  static const String baseServiceRatingUnselected = 'assets/base_service/rating_unselected.webp';
+  static const String baseServiceTitleBarFilterIcon = 'assets/base_service/title_bar_filter_icon.webp';
+  static const String baseServiceTriangleDropDown = 'assets/base_service/triangle_drop_down.webp';
+  static const String baseServiceTriangleDropDownIcon = 'assets/base_service/triangle_drop_down_icon.webp';
 
 }

+ 2 - 0
packages/cs_resources/pubspec.yaml

@@ -25,3 +25,5 @@ flutter:
 
   assets:
     - assets/
+    - assets/base_lib/
+    - assets/base_service/

+ 40 - 0
packages/cs_router/lib/ext/auto_router_extensions.dart

@@ -0,0 +1,40 @@
+import 'package:auto_route/auto_route.dart';
+import 'package:flutter/material.dart';
+
+// 扩展 RootStackRouter 类
+extension RootStackRouterExtensions on RootStackRouter {
+  // SlideFadeTransition 动画效果 (平移渐变动画)
+  Widget applySlideFadeTransition(
+      BuildContext context,
+      Animation<double> animation,
+      Animation<double> secondaryAnimation,
+      Widget child,
+      ) {
+    return SlideTransition(
+      position: Tween<Offset>(
+        begin: const Offset(1.0, 0.0),
+        end: Offset.zero,
+      ).animate(animation),
+      child: FadeTransition(
+        opacity: animation,
+        child: child,
+      ),
+    );
+  }
+
+  // SlideTransition 动画效果 (平移动画)
+  Widget applySlideTransition(
+      BuildContext context,
+      Animation<double> animation,
+      Animation<double> secondaryAnimation,
+      Widget child,
+      ) {
+    return SlideTransition(
+      position: Tween<Offset>(
+        begin: const Offset(1.0, 0.0),
+        end: Offset.zero,
+      ).animate(animation),
+      child: child,
+    );
+  }
+}

+ 1 - 1
packages/cs_router/lib/path/router_path.dart

@@ -67,7 +67,7 @@ class RouterPath {
 
   //全局其他
   static const previewImage = '/preview/image'; //预览图片
-  static const globalWeb = '/global/web'; //全局公用的Web页面
+  static const globalWeb = '/global/web/:isShowAppBar/:initialUrl/:title'; //全局公用的Web页面
 
   //Runalone
   static const runAloneMain = '/runalone/main'; //独立运行的入口页面

+ 24 - 2
packages/cs_shared/lib/utils/number_format_util.dart

@@ -1,8 +1,7 @@
 /// 对数字或金额的格式化
 class NumberFormatUtil {
-
   /// 格式化金额,每三位数分割一个逗号,1000 -> 1,000
- static String formatMoney(int number) {
+  static String formatMoney(int number) {
     List<String> parts = [];
     String numberString = number.toString();
 
@@ -16,4 +15,27 @@ class NumberFormatUtil {
     return parts.reversed.join(",");
   }
 
+  //对比带. 的版本号大小
+  static int compareVersionNumbers(String version1, String version2) {
+    List<int> v1 = version1.split('.').map(int.parse).toList();
+    List<int> v2 = version2.split('.').map(int.parse).toList();
+
+    int minLength = v1.length < v2.length ? v1.length : v2.length;
+
+    for (int i = 0; i < minLength; i++) {
+      if (v1[i] < v2[i]) {
+        return -1; // version1 < version2
+      } else if (v1[i] > v2[i]) {
+        return 1;
+      }
+    }
+
+    if (v1.length < v2.length) {
+      return -1;
+    } else if (v1.length > v2.length) {
+      return 1; // version1 > version2
+    }
+
+    return 0; //version1 = version2
+  }
 }

+ 2 - 2
packages/cs_widgets/lib/load_state_layout.dart

@@ -143,7 +143,7 @@ class _LoadStateLayoutState extends State<LoadStateLayout> {
               crossAxisAlignment: CrossAxisAlignment.center,
               mainAxisAlignment: MainAxisAlignment.center,
               children: <Widget>[
-                const MyAssetImage("Assets.baseServicePageLoadError", width: 141, height: 117.5, fit: BoxFit.contain),
+                const MyAssetImage(Assets.baseServicePageLoadError, width: 141, height: 117.5, fit: BoxFit.contain),
                 MyTextView(
                   widget.errorMessage ?? 'Data loading failed! Please refresh and try again',
                   marginTop: 18,
@@ -166,7 +166,7 @@ class _LoadStateLayoutState extends State<LoadStateLayout> {
         crossAxisAlignment: CrossAxisAlignment.center,
         mainAxisAlignment: MainAxisAlignment.center,
         children: <Widget>[
-          const MyAssetImage("Assets.baseServicePageNoData", width: 123.5, height: 115.5, fit: BoxFit.contain),
+          const MyAssetImage(Assets.baseServicePageNoData, width: 123.5, height: 115.5, fit: BoxFit.contain),
           MyTextView(
             'There is currently no content available',
             marginTop: 18,

+ 4 - 4
packages/cs_widgets/lib/my_appbar.dart

@@ -26,7 +26,7 @@ class MyAppBar {
       surfaceTintColor: backgroundColor,
       systemOverlayStyle: systemUiOverlayStyle,
       leading: IconButton(
-        icon: MyAssetImage(backIconPath ?? "Assets.baseLibWhiteBack", width: backIconWidth ?? 11, height: backIconHeight ?? 18),
+        icon: MyAssetImage(backIconPath ?? Assets.baseLibWhiteBack, width: backIconWidth ?? 11, height: backIconHeight ?? 18),
         onPressed: () {
           if (backCallback != null) {
             backCallback();
@@ -97,7 +97,7 @@ class MyAppBar {
       // 标题与其他控件的间隔
       titleSpacing: 0,
       leading: IconButton(
-        icon: const MyAssetImage("Assets.baseLibWhiteBack", width: 11, height: 18),
+        icon: const MyAssetImage(Assets.baseLibWhiteBack, width: 11, height: 18),
         onPressed: () {
           if (backCallback != null) {
             backCallback();
@@ -161,7 +161,7 @@ class MyAppBar {
                   alignment: Alignment.center,
                   child: IconButton(
                     icon: MyAssetImage(
-                      backIconPath ?? "Assets.baseLibWhiteBack",
+                      backIconPath ?? Assets.baseLibWhiteBack,
                       width: backIconWidth ?? 11,
                       height: backIconHeight ?? 18,
                     ),
@@ -260,7 +260,7 @@ class MyAppBar {
                 alignment: Alignment.center,
                 child: IconButton(
                   icon: MyAssetImage(
-                    "Assets.baseLibWhiteBack",
+                    Assets.baseLibWhiteBack,
                     width: 11,
                     height: 18,
                   ),

+ 1 - 1
packages/cs_widgets/lib/my_click_item.dart

@@ -100,7 +100,7 @@ class MyClickItem extends StatelessWidget {
                   style: TextStyle(color: title_color, fontSize: title_size,fontWeight: fontWeight),
                 )),
                 MyLoadImage(
-                  "Assets.baseLibBlackBack",
+                  Assets.baseLibBlackBack,
                   width: 5.5,
                   height: 9.5,
                 )

+ 3 - 3
packages/cs_widgets/lib/search_app_bar.dart

@@ -115,8 +115,8 @@ class _SearchAppBarState extends State<SearchAppBar> {
   Widget build(BuildContext context) {
     return Container(
       height: widget.searchBarHeight,
-      padding: EdgeInsets.only(left: 15, right: 11),
-      margin: widget.margin ?? EdgeInsets.only(right: 15),
+      padding: const EdgeInsets.only(left: 15, right: 11),
+      margin: widget.margin ?? const EdgeInsets.only(right: 15),
       decoration: BoxDecoration(
         color: widget.searchBarBgColor ?? Color(0xFF4DCFF6).withOpacity(0.2), // 设置// 背景颜色和不透明度
         borderRadius: BorderRadius.circular(widget.searchBarBorderRadius), // 设置圆角
@@ -174,7 +174,7 @@ class _SearchAppBarState extends State<SearchAppBar> {
           ).expanded(),
 
           //搜索图标
-          MyAssetImage("Assets.cptJobSearchIcon", width: 15, height: 15).marginOnly(left: 10).onTap(() {
+          const MyAssetImage(Assets.baseLibSearchIcon, width: 15, height: 15).marginOnly(left: 10).onTap(() {
             widget.onSearch?.call(_controller?.text ?? "");
             _unFocus();
           }),

+ 1 - 1
packages/cs_widgets/lib/shatter/border_select_widget.dart

@@ -40,7 +40,7 @@ class BorderSelectWidget extends StatelessWidget {
               marginRight: 7,
             ),
             MyAssetImage(
-             "Assets.baseServiceBorderWidgetDropDown",
+             Assets.baseServiceBorderWidgetDropDown,
               color: color,
               height: 7.5,
               width: 4.5,

+ 1 - 1
packages/cs_widgets/lib/shatter/custom_check_box.dart

@@ -70,7 +70,7 @@ class _CustomCheckBoxState extends State<CustomCheckBox> {
         int index = entry.key;
         String option = entry.value;
         return _buildCheckBoxWithIconAndText(
-          path: _selectedIndexes.contains(index) ? "Assets.baseServiceCheckBoxChecked" : "Assets.baseServiceCheckBoxUncheck",
+          path: _selectedIndexes.contains(index) ? Assets.baseServiceCheckBoxChecked : Assets.baseServiceCheckBoxUncheck,
           text: option,
           value: _selectedIndexes.contains(index),
           onChanged: (isChecked) {

+ 2 - 1
packages/cs_widgets/lib/shatter/custom_radio_check.dart

@@ -1,4 +1,5 @@
 import 'package:cs_resources/constants/color_constants.dart';
+import 'package:cs_resources/generated/assets.dart';
 import 'package:flutter/material.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
@@ -59,7 +60,7 @@ class _CustomRadioCheckState extends State<CustomRadioCheck> {
       runSpacing: 8.0,
       children: widget.options.map((option) {
         return _buildRadioWithIconAndText(
-          path: option == _selectedOption ? "Assets.cptAuthLoginRadioChecked" : "Assets.cptAuthLoginRadioUncheck",
+          path: option == _selectedOption ? Assets.baseServiceRadioChecked : Assets.baseServiceRadioUncheck,
           text: option,
           value: option == _selectedOption,
           onChanged: widget.enable

+ 2 - 2
packages/cs_widgets/lib/shatter/form_require_text.dart

@@ -1,6 +1,6 @@
 import 'package:flutter/material.dart';
 
-/**
+/*
  * 表单中必填的文本描述,文本后加红色*标识
  * 使用富文本的方式实现
  */
@@ -21,7 +21,7 @@ class FormRequireText extends StatelessWidget {
           TextSpan(
             text: text,
           ),
-          TextSpan(
+          const TextSpan(
             text: " *",
             style: TextStyle(color: Colors.red),
           ),

+ 1 - 1
packages/cs_widgets/lib/shatter/round_my_text_field.dart

@@ -5,7 +5,7 @@ import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
 
 import '../my_text_field.dart';
 
-/**
+/*
  * 基于 MyTextField 实现圆角背景的文本框表单。
  *
  * 主要用于注册,忘记密码等页面。

+ 2 - 2
packages/cs_widgets/lib/shatter/setting_item_container.dart

@@ -22,7 +22,7 @@ class SettingItemContainer extends StatelessWidget {
       margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 15),
       padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 16.5),
       decoration: BoxDecoration(
-        color: Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+        color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
         borderRadius: BorderRadius.circular(5.0), // 设置圆角
       ),
       child: Row(
@@ -39,7 +39,7 @@ class SettingItemContainer extends StatelessWidget {
             marginRight: 11,
             textColor: ColorConstants.textGrayAECAE5,
           ).expanded(),
-          MyAssetImage("Assets.mainItemMoreIcon", width: 7.5, height: 13.5),
+          const MyAssetImage(Assets.baseLibItemMoreIcon, width: 7.5, height: 13.5),
         ],
       ),
     );