From 72443f7abfdbbfb784e4bdbb6cedb15f759ec20e Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Sun, 16 Mar 2025 18:01:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=88=87=E6=8D=A2flutter=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .fvmrc | 3 + .gitignore | 3 + .vscode/launch.json | 26 +++ .vscode/settings.json | 3 + android/app/src/main/AndroidManifest.xml | 12 +- .../flutter/FlutterFaceDiscernPlugin.java | 9 +- .../plugins/facediscern/ui/FaceDiscern.java | 39 ++--- .../ui/viewmodel/FaceDiscernViewModel.java | 14 +- .../pj_supermarket_cloud/MainActivity.kt | 2 +- .../tool/FlutterRouterManager.kt | 75 ++++++++ android/app/src/main/res/values/attrs.xml | 5 + lib/common/routers/pages.dart | 18 +- .../database/entity/classify_entity.dart | 16 +- lib/common/utils/app/app_setting_tool.dart | 2 - lib/common/utils/app/control/app_control.dart | 7 +- lib/common/utils/sync/sync_config_tool.dart | 11 +- lib/common/widgets/app/app_img.dart | 44 +---- .../widgets/order/mixin/order_mixin.dart | 29 +--- lib/common/widgets/order/order_common.dart | 36 ++++ .../widgets/order/select_pay_type_dialog.dart | 66 ++++--- lib/main.dart | 29 ++-- lib/pages/canteen_product/controller.dart | 78 ++++----- lib/pages/canteen_product/view.dart | 161 +++++++----------- lib/pages/panel/controller.dart | 17 +- lib/pages/setting/controller.dart | 4 +- .../setting/widgets/setting_baseInfo.dart | 4 +- lib/pages/supermarket_order/controller.dart | 20 ++- lib/pages/supermarket_order/view.dart | 44 +++-- lib/sub_screen/page/sub_app.dart | 12 +- lib/sub_screen/page/sub_product.dart | 16 +- pubspec.lock | 96 ++++++++++- pubspec.yaml | 10 +- 32 files changed, 536 insertions(+), 375 deletions(-) create mode 100644 .fvmrc create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 android/app/src/main/kotlin/com/example/pj_supermarket_cloud/tool/FlutterRouterManager.kt create mode 100644 android/app/src/main/res/values/attrs.xml diff --git a/.fvmrc b/.fvmrc new file mode 100644 index 0000000..c2783c6 --- /dev/null +++ b/.fvmrc @@ -0,0 +1,3 @@ +{ + "flutter": "3.27.4" +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 79c113f..b6323af 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +# FVM Version Cache +.fvm/ \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..5aa1f6d --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "name": "pj_supermarket_cloud", + "request": "launch", + "type": "dart" + }, + { + "name": "pj_supermarket_cloud (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "pj_supermarket_cloud (release mode)", + "request": "launch", + "type": "dart", + "flutterMode": "release" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..926bd45 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "dart.flutterSdkPath": ".fvm/versions/3.27.4" +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 9afaf69..b9a8f32 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -22,13 +22,19 @@ android:name="${applicationName}" android:icon="@mipmap/ic_launcher" android:label="智慧食堂" - android:largeHeap="true" android:requestLegacyExternalStorage="true"> + + diff --git a/android/app/src/main/java/io/flutter/plugins/facediscern/flutter/FlutterFaceDiscernPlugin.java b/android/app/src/main/java/io/flutter/plugins/facediscern/flutter/FlutterFaceDiscernPlugin.java index 3081d6b..fb986c9 100644 --- a/android/app/src/main/java/io/flutter/plugins/facediscern/flutter/FlutterFaceDiscernPlugin.java +++ b/android/app/src/main/java/io/flutter/plugins/facediscern/flutter/FlutterFaceDiscernPlugin.java @@ -5,8 +5,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Build; -import android.os.Handler; -import android.os.Looper; import androidx.annotation.NonNull; @@ -76,15 +74,10 @@ public class FlutterFaceDiscernPlugin implements FlutterPlugin, MethodChannel.Me switch (method) { case "jumpFaceDiscern": try { -// Intent intent = new Intent(context, FaceDiscern.class); -// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); -// intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); -// context.startActivity(intent); - Intent intent = new Intent(context, FaceDiscern.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - new Handler(Looper.getMainLooper()).post(() -> context.startActivity(intent)); + context.startActivity(intent); result.success(true); } catch (Exception e) { result.success(false); diff --git a/android/app/src/main/java/io/flutter/plugins/facediscern/ui/FaceDiscern.java b/android/app/src/main/java/io/flutter/plugins/facediscern/ui/FaceDiscern.java index 414b866..ad1ba1b 100644 --- a/android/app/src/main/java/io/flutter/plugins/facediscern/ui/FaceDiscern.java +++ b/android/app/src/main/java/io/flutter/plugins/facediscern/ui/FaceDiscern.java @@ -4,10 +4,7 @@ import android.Manifest; import android.content.Intent; import android.graphics.Point; import android.hardware.Camera; -import android.os.AsyncTask; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; import android.util.DisplayMetrics; import android.view.View; import android.view.ViewGroup; @@ -18,9 +15,9 @@ import androidx.core.app.ActivityCompat; import androidx.databinding.DataBindingUtil; import androidx.lifecycle.ViewModelProvider; -import com.example.pj_supermarket_cloud.MainActivity; import com.example.pj_supermarket_cloud.R; import com.example.pj_supermarket_cloud.databinding.ActivityFaceDiscernBinding; +import com.example.pj_supermarket_cloud.tool.FlutterRouterManager; import io.flutter.Log; import io.flutter.embedding.android.FlutterActivity; @@ -96,12 +93,6 @@ public class FaceDiscern extends BaseActivity implements ViewTreeObserver.OnGlob initRgbCamera(); } - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - Log.e(TAG, "相机触发onNewIntent"); - } - @Override protected void onDestroy() { super.onDestroy(); @@ -133,10 +124,13 @@ public class FaceDiscern extends BaseActivity implements ViewTreeObserver.OnGlob if (Objects.nonNull(channel)) { channel.invokeMethod("faceDiscernPageInit", null); } + if (rgbCameraHelper != null) { + rgbCameraHelper.resumePreview(); + } scheduler.schedule(() -> { try { - if (rgbCameraHelper != null) { - rgbCameraHelper.resumePreview(); + if (viewModel != null) { + viewModel.stop(); previewLock = false; Log.i(TAG, "相机开始识别"); } @@ -155,26 +149,33 @@ public class FaceDiscern extends BaseActivity implements ViewTreeObserver.OnGlob } } - // 以前的方式 - // intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - // 推荐的方式 - // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - // intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - // 手机返回按钮 @Override public void onBackPressed() { + Log.e(TAG, "相机onBackPressed"); + + if (rgbCameraHelper != null) { + rgbCameraHelper.stop(); + } + if (viewModel != null) { + viewModel.stop(); + } + binding.dualCameraFaceRectView.clearFaceInfo(); + previewLock = true; MethodChannel channel = FlutterFaceDiscernPlugin.staticChannel; if (Objects.nonNull(channel)) { channel.invokeMethod("faceDiscernBack", null); } + // FlutterRouterManager loadEngine = new FlutterRouterManager("/load", "login_engine", this); + // loadEngine.push(); + // loadEngine.destroy(); + Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); intent.setClassName(this.getPackageName(), this.getPackageName() + ".MainActivity"); this.startActivity(intent); - } diff --git a/android/app/src/main/java/io/flutter/plugins/facediscern/ui/viewmodel/FaceDiscernViewModel.java b/android/app/src/main/java/io/flutter/plugins/facediscern/ui/viewmodel/FaceDiscernViewModel.java index c256799..879bcdc 100644 --- a/android/app/src/main/java/io/flutter/plugins/facediscern/ui/viewmodel/FaceDiscernViewModel.java +++ b/android/app/src/main/java/io/flutter/plugins/facediscern/ui/viewmodel/FaceDiscernViewModel.java @@ -20,10 +20,8 @@ import com.arcsoft.face.LivenessInfo; import com.arcsoft.face.LivenessParam; import com.arcsoft.face.enums.DetectFaceOrientPriority; import com.arcsoft.face.enums.DetectMode; -import com.example.pj_supermarket_cloud.MainActivity; import com.google.gson.Gson; -import io.flutter.embedding.android.FlutterActivity; import io.flutter.plugins.facediscern.tool.camera.DualCameraHelper; import io.flutter.plugins.facediscern.tool.camera.config.PreviewConfig; import io.flutter.plugins.facediscern.tool.face.constants.FaceBrodConstant; @@ -293,15 +291,17 @@ public class FaceDiscernViewModel extends ViewModel implements RecognizeCallback if (flutterFaceCallbackIntent == null) { flutterFaceCallbackIntent = new Intent(FaceBrodConstant.FACE_GLOBAL_INTENT); } - flutterFaceCallbackIntent.putExtra("json", new Gson().toJson(faceDiscern)); Log.i(TAG, "人脸识别成功json:" + new Gson().toJson(faceDiscern)); + flutterFaceCallbackIntent.putExtra("json", new Gson().toJson(faceDiscern)); + context.sendBroadcast(flutterFaceCallbackIntent); + faceDiscern = null; if (context instanceof Activity) { Thread.sleep(500); - Intent intent = new Intent(context, MainActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + String packageName = context.getPackageName(); + Intent intent = new Intent(); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + intent.setClassName(packageName, packageName + ".MainActivity"); context.startActivity(intent); - context.sendBroadcast(flutterFaceCallbackIntent); - faceDiscern = null; } } catch (Exception e) { Log.e(TAG, "提示文字变更的回调,错误error:" + e.getMessage(), e); diff --git a/android/app/src/main/kotlin/com/example/pj_supermarket_cloud/MainActivity.kt b/android/app/src/main/kotlin/com/example/pj_supermarket_cloud/MainActivity.kt index b4a924c..a6223b6 100644 --- a/android/app/src/main/kotlin/com/example/pj_supermarket_cloud/MainActivity.kt +++ b/android/app/src/main/kotlin/com/example/pj_supermarket_cloud/MainActivity.kt @@ -17,4 +17,4 @@ class MainActivity : FlutterActivity() { GeneratedPluginRegistrant.registerWith(flutterEngine) } -} +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/example/pj_supermarket_cloud/tool/FlutterRouterManager.kt b/android/app/src/main/kotlin/com/example/pj_supermarket_cloud/tool/FlutterRouterManager.kt new file mode 100644 index 0000000..fe14931 --- /dev/null +++ b/android/app/src/main/kotlin/com/example/pj_supermarket_cloud/tool/FlutterRouterManager.kt @@ -0,0 +1,75 @@ +package com.example.pj_supermarket_cloud.tool + +import android.app.Activity +import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.android.FlutterActivityLaunchConfigs +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.embedding.engine.FlutterEngineCache +import io.flutter.embedding.engine.dart.DartExecutor + +class FlutterRouterManager(val targetRoute: String, val mEngineId: String, val mContext: Activity) { + + var mEngine: FlutterEngine? = null + + init { + createCachedEngine() + } + + companion object { + + /** + * 获取缓存中的 Flutter引擎 + */ + @JvmStatic + fun getEngineCacheInstance(engineId: String): FlutterEngine? { + return FlutterEngineCache.getInstance().get(engineId) + } + + } + + /** + * 1、创建Flutter引擎 + * 2、将初始命名路由,修改为目标页面路由 + * 3、缓存Flutter引擎 + */ + fun createCachedEngine(): FlutterEngine { + val flutterEngine = FlutterEngine(mContext) // 创建Flutter引擎 + + // 将初始命名路由,修改为目标页面路由 + flutterEngine.navigationChannel.setInitialRoute(targetRoute) + + // 这一步,是在执行相关Dart文件入口的 main函数,将Flutter页面渲染出结果 + // 原生端获取结果,进行最终渲染上屏 + flutterEngine.dartExecutor.executeDartEntrypoint( + DartExecutor.DartEntrypoint.createDefault() + ) + + // 将加载好的引擎,存储起来 + FlutterEngineCache.getInstance().put(mEngineId, flutterEngine) + + mEngine = flutterEngine + + return flutterEngine + } + + /** + * 根据引擎ID,前往指定的Flutter页面 + */ + fun push() { + // 使用缓存好的引擎(推荐) + mContext.startActivity( + FlutterActivity + .withCachedEngine(mEngineId) + .backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent) + .build(mContext) + ) + } + + /** + * 销毁当前Flutter引擎 + */ + fun destroy() { + mEngine?.destroy() + } + +} diff --git a/android/app/src/main/res/values/attrs.xml b/android/app/src/main/res/values/attrs.xml new file mode 100644 index 0000000..9b9f75c --- /dev/null +++ b/android/app/src/main/res/values/attrs.xml @@ -0,0 +1,5 @@ + + + + true + \ No newline at end of file diff --git a/lib/common/routers/pages.dart b/lib/common/routers/pages.dart index f292013..c51e1bd 100644 --- a/lib/common/routers/pages.dart +++ b/lib/common/routers/pages.dart @@ -21,15 +21,6 @@ class RoutePages { Get.lazyPut(() => PanelController()); }), ), - GetPage( - name: RouteNames.supermarketProduct, - page: () => const SupermarketOrderPage(), - binding: BindingsBuilder(() { - Get.lazyPut(() => SelectPayTypeDialogController()); - Get.lazyPut(() => PanelController()); - Get.lazyPut(() => SupermarketOrderController()); - }), - ), GetPage( name: RouteNames.canteenProduct, page: () => const CanteenProductPage(), @@ -39,6 +30,15 @@ class RoutePages { Get.lazyPut(() => PanelController()); }), ), + GetPage( + name: RouteNames.supermarketProduct, + page: () => const SupermarketOrderPage(), + binding: BindingsBuilder(() { + Get.lazyPut(() => SelectPayTypeDialogController()); + Get.lazyPut(() => PanelController()); + Get.lazyPut(() => SupermarketOrderController()); + }), + ), GetPage( name: RouteNames.takeFood, page: () => const TakeFoodPage(), diff --git a/lib/common/services/database/entity/classify_entity.dart b/lib/common/services/database/entity/classify_entity.dart index 8e2e3f5..02bc605 100644 --- a/lib/common/services/database/entity/classify_entity.dart +++ b/lib/common/services/database/entity/classify_entity.dart @@ -14,28 +14,28 @@ class ClassifyEntity extends Equatable { int? id; /// 服务端唯一标识 - String serviceUniqueCode; + final String serviceUniqueCode; /// 平台类型 - SysType sysType; + final SysType sysType; /// 分类名 - String name; + final String name; /// 用餐类型,早餐、中餐、晚餐 - String categoryType; + final String categoryType; /// 排序 倒序排列 - int sort; + final int sort; /// 创建时间 - DateTime createTime; + final DateTime createTime; /// 同步时间 - DateTime updateTime; + final DateTime updateTime; /// 是否删除 - bool delFlag; + final bool delFlag; ClassifyEntity({ this.id, diff --git a/lib/common/utils/app/app_setting_tool.dart b/lib/common/utils/app/app_setting_tool.dart index facd568..3c7992d 100644 --- a/lib/common/utils/app/app_setting_tool.dart +++ b/lib/common/utils/app/app_setting_tool.dart @@ -91,8 +91,6 @@ abstract class AppSettingTool { } static Future setSysSetting(SysSetting sysInfo) async { - final globalSysInfo = await getSysSetting(); - if (globalSysInfo == sysInfo) return; await _setSetting(sysJson: sysInfo); } diff --git a/lib/common/utils/app/control/app_control.dart b/lib/common/utils/app/control/app_control.dart index f87b848..004c61e 100644 --- a/lib/common/utils/app/control/app_control.dart +++ b/lib/common/utils/app/control/app_control.dart @@ -19,6 +19,7 @@ class AppControl extends GetxController { /// mq StreamSubscription? mqListen; + EventBus mqUpdateEventBus = EventBus(); /// 数据库 @@ -34,7 +35,7 @@ class AppControl extends GetxController { serialCardManage.close(); srialSteelyardManage.close(); AppNetworkTool.closeListenNetwork(); - // TtsManage.dispose(); + TtsManage.dispose(); } Future initAsync() async { @@ -43,8 +44,8 @@ class AppControl extends GetxController { serialCardManage = SerialCardManage(); srialSteelyardManage = SerialSteelyardManage(); AppNetworkTool.listenNetwork(); - // await AppFileTool.backupSqlFile(); - // await TtsManage.initialize(); + await AppFileTool.backupSqlFile(); + await TtsManage.initialize(); Get.offAllNamed(RouteNames.login); } } diff --git a/lib/common/utils/sync/sync_config_tool.dart b/lib/common/utils/sync/sync_config_tool.dart index bdf8ef4..0c5e32f 100644 --- a/lib/common/utils/sync/sync_config_tool.dart +++ b/lib/common/utils/sync/sync_config_tool.dart @@ -8,25 +8,26 @@ abstract class SyncConfigTool { static const _tag = "sync配置工具"; // 自动同步设备信息导本地缓存 - static Future autoSyncSysInfo() async { + static Future autoSyncSysInfo() async { final login = await AppUserTool.isLogin(); - if (!login) return; + if (!login) return null; final sysSetting = await AppSettingTool.getSysSetting(); logger.i("|$_tag|开始同步设备信息 sysInfo:|${json.encode(sysSetting)}|"); - if (ObjectUtil.isEmpty(sysSetting)) return; - if (ObjectUtil.isEmpty(sysSetting.serviceId)) return; + if (ObjectUtil.isEmpty(sysSetting)) return null; + if (ObjectUtil.isEmpty(sysSetting.serviceId)) return null; final serviceId = sysSetting.serviceId; final pa = {"id": serviceId}; final data = await HardApi.get(pa); if (data == null) { logger.e("|$_tag|同步设备信息错误serviceId:|$serviceId|;"); - return; + return null; } // 基本信息 await AppSettingTool.updateSysInfoByService(data); // 人脸sdk await autoSyncFaceSdk(detail: data, sysInfo: sysSetting); logger.i("|$_tag|结束同步设备信息 sysInfo:|${json.encode(sysSetting)}|"); + return sysSetting; } // 自动同步设备信息导本地缓存-同步人脸sdk diff --git a/lib/common/widgets/app/app_img.dart b/lib/common/widgets/app/app_img.dart index dffb946..f30b80d 100644 --- a/lib/common/widgets/app/app_img.dart +++ b/lib/common/widgets/app/app_img.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:cached_network_image/cached_network_image.dart'; import 'package:common_utils/common_utils.dart'; import 'package:ducafe_ui_core/ducafe_ui_core.dart'; import 'package:flutter/material.dart'; @@ -15,31 +16,11 @@ Widget appNetworkImg( double imgHeight = 60, BoxFit fit = BoxFit.cover, }) { - return Image.network( - src, - width: imgWidth, - height: imgHeight, - fit: fit, - loadingBuilder: - (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) { - if (loadingProgress == null) { - return child; - } else { - return Center( - child: SizedBox( - width: imgHeight, - height: imgHeight, - child: CircularProgressIndicator( - value: loadingProgress.expectedTotalBytes != null - ? loadingProgress.cumulativeBytesLoaded / - (loadingProgress.expectedTotalBytes ?? 1) - : null, - ), - ), - ); - } - }, - errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) { + return CachedNetworkImage( + imageUrl: AppNetworkTool.ossImage(src), + placeholder: (context, url) => + CircularProgressIndicator().width(50.w).height(50.w), + errorWidget: (context, url, error) { final theme = FTheme.of(context); return FIcon( FAssets.icons.globeLock, @@ -48,19 +29,6 @@ Widget appNetworkImg( ).width(imgWidth * 0.5).height(imgHeight * 0.5); }, ); - // return CachedNetworkImage( - // imageUrl: AppNetworkTool.ossImage(src), - // placeholder: (context, url) => - // CircularProgressIndicator().width(50.w).height(50.w), - // errorWidget: (context, url, error) { - // final theme = FTheme.of(context); - // return FIcon( - // FAssets.icons.globeLock, - // color: theme.colorScheme.error, - // size: theme.typography.base.fontSize, - // ).width(imgWidth * 0.5).height(imgHeight * 0.5); - // }, - // ); } Widget appFileImg( diff --git a/lib/common/widgets/order/mixin/order_mixin.dart b/lib/common/widgets/order/mixin/order_mixin.dart index 89a21e3..77a2188 100644 --- a/lib/common/widgets/order/mixin/order_mixin.dart +++ b/lib/common/widgets/order/mixin/order_mixin.dart @@ -14,9 +14,6 @@ mixin OrderMixin { final appController = Get.find(); - // 路由变化 - StreamSubscription? routerBus; - /// **************** start 需要重制 start **************** // 时间类型 @@ -57,7 +54,7 @@ mixin OrderMixin { ); // 当前的tab - RxInt currentTabIndex = RxInt(0); + int currentTabIndex = 0; // 购买用户 Rxn payUser = Rxn(null); @@ -80,11 +77,12 @@ mixin OrderMixin { // 点击分类tab Future doTab(int i) async { + if (currentTabIndex == i) return; EasyLoading.show( status: '切换中...', maskType: EasyLoadingMaskType.black, ); - currentTabIndex.value = i; + currentTabIndex = i; if (i <= classifyList.length - 1) { final current = classifyList[i]; await getProduct(classifyCode: current.serviceUniqueCode); @@ -113,12 +111,11 @@ mixin OrderMixin { ), ); classifyList.value = list; + classifyList.refresh(); } // 获取商品 - Future getProduct({ - String classifyCode = "-1", - }) async { + Future getProduct({String classifyCode = "-1"}) async { final list = await appController.dataBase.getProductDao.getAll( classifyCode, hourType.value.code, @@ -401,9 +398,7 @@ mixin OrderMixin { /// **************** start 副屏幕相关 start **************** - void putOffSendSubScreen({ - int seconds = 5, - }) { + void putOffSendSubScreen({int seconds = 5}) { if (putOffSendSubScreenDelayed != null) { sendSubScreen(); putOffSendSubScreenDelayed = null; @@ -432,18 +427,6 @@ mixin OrderMixin { /// **************** end 副屏幕相关 end **************** - /// **************** start 路由变化相关 start **************** - listenRouter() { - routerBus = GlobalRouteObserver.globalRouteObserverBus - .on() - .listen((event) { - if (event.action == RouterActionType.didPop && - event.name == RouteNames.faceDiscern) {} - }); - } - - /// **************** end 路由变化相关 end **************** - // 生成安卓唯一的code Future _getUniqueCode() async { String code = ""; diff --git a/lib/common/widgets/order/order_common.dart b/lib/common/widgets/order/order_common.dart index d8633d1..9ba84de 100644 --- a/lib/common/widgets/order/order_common.dart +++ b/lib/common/widgets/order/order_common.dart @@ -1,3 +1,5 @@ +import 'dart:ffi'; + import 'package:ducafe_ui_core/ducafe_ui_core.dart'; import 'package:flutter/material.dart'; import 'package:forui/forui.dart'; @@ -148,3 +150,37 @@ Widget orderSelectPanel( }, ); } + +Widget orderRowClassify( + BuildContext context, { + required List classifyList, + required Function(int) onChange, + int currentTabIndex = 0, +}) { + final theme = FTheme.of(context); + return classifyList + .map((v) { + final target = classifyList[currentTabIndex]; + final active = target.id == v.id; + return FButton( + style: active ? FButtonStyle.primary : FButtonStyle.secondary, + label: Text( + v.name, + textAlign: TextAlign.center, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: theme.typography.xl.copyWith( + color: active + ? theme.colorScheme.secondary + : theme.colorScheme.primary, + ), + ).center().width(120.w), + onPress: () { + final index = classifyList.indexWhere((i) => i.id == v.id); + onChange(index); + }, + ); + }) + .toList() + .toRowSpace(space: 20.w); +} diff --git a/lib/common/widgets/order/select_pay_type_dialog.dart b/lib/common/widgets/order/select_pay_type_dialog.dart index 27dd118..a82ed27 100644 --- a/lib/common/widgets/order/select_pay_type_dialog.dart +++ b/lib/common/widgets/order/select_pay_type_dialog.dart @@ -12,6 +12,8 @@ import 'package:get/get.dart'; import 'package:pj_supermarket_cloud/common/index.dart'; class SelectPayTypeDialogController extends GetxController { + SelectPayTypeDialogController(); + /// **************** start 回调函数 start **************** // |开始识别|的回调 @@ -114,16 +116,16 @@ class SelectPayTypeDialogController extends GetxController { } // |开始识别|点击 - doRecognition() { + Future doRecognition() async { switch (orderPayDisplayType.value) { case OrderPayDisplayType.qrCode: - _dispatchQrCode(); + await _dispatchQrCode(); break; case OrderPayDisplayType.walletCard: - _dispatchWalletCard(); + await _dispatchWalletCard(); break; case OrderPayDisplayType.face: - _dispatchFace(); + await _dispatchFace(); break; default: } @@ -143,7 +145,7 @@ class SelectPayTypeDialogController extends GetxController { globalQrCode, ); _closeStatus(); - Navigator.of(Get.context!, rootNavigator: true).pop(); + Navigator.of(Get.context!).pop(); } // |取消|点击 @@ -151,18 +153,18 @@ class SelectPayTypeDialogController extends GetxController { if (isRecognition.value) { final flag = await appMessageDialog(Get.context!, "是否取消识别"); if (!flag) return; - Navigator.of(Get.context!, rootNavigator: true).pop(); + Navigator.of(Get.context!).pop(); return; } _closeStatus(); onCancel?.call(); - Navigator.of(Get.context!, rootNavigator: true).pop(); + Navigator.of(Get.context!).pop(); } // ************************************************************************** // 二维码识别 start // ************************************************************************** - void _dispatchQrCode() async { + Future _dispatchQrCode() async { try { if (isRecognition.value) { Toast.error(msg: "正在识别中,请勿重复点击"); @@ -229,7 +231,7 @@ class SelectPayTypeDialogController extends GetxController { // ************************************************************************** // 饭卡识别 start // ************************************************************************** - void _dispatchWalletCard() async { + Future _dispatchWalletCard() async { if (isRecognition.value) { Toast.error(msg: "正在识别中,请勿重复点击"); return; @@ -302,9 +304,8 @@ class SelectPayTypeDialogController extends GetxController { // ************************************************************************** // 人脸支付 start // ************************************************************************** - void _dispatchFace() async { + Future _dispatchFace() async { try { - EasyLoading.dismiss(); EasyLoading.show( status: '人脸识别准备中...', maskType: EasyLoadingMaskType.black, @@ -312,13 +313,15 @@ class SelectPayTypeDialogController extends GetxController { final faceDao = app.dataBase.getFaceDao; final databaseFaceCount = await faceDao.findCount("-1"); if (databaseFaceCount == null || databaseFaceCount == 0) { - Toast.error(msg: "人脸数据库为空,请前往'设置'->'人脸管理'点击同步人脸"); - throw Error(); + String msg = "人脸数据库为空,请前往'设置'->'人脸管理'点击同步人脸"; + Toast.error(msg: msg); + throw Exception(msg); } final isActive = await AppFaceTool.isActiveSdk(); if (!isActive) { - Toast.error(msg: "请检查激人脸sdk激活码"); - throw Error(); + String msg = "请检查激人脸sdk激活码"; + Toast.error(msg: msg); + throw Exception(msg); } final faceCount = await FaceDiscernPlugs.getFaceCount(); if (faceCount == 0) { @@ -326,8 +329,9 @@ class SelectPayTypeDialogController extends GetxController { } final isJump = await AppFaceTool.jumpFacePage(); if (!isJump) { - Toast.error(msg: "跳转到人脸检测页面失败"); - throw Error(); + String msg = "跳转到人脸检测页面失败"; + Toast.error(msg: msg); + throw Exception(msg); } faceDiscernListen = FaceDiscernPlugs.faceStream.listen((event) { if (event == null) return; @@ -342,6 +346,7 @@ class SelectPayTypeDialogController extends GetxController { SubScreenPlugin.doubleScreenShow(); }); } catch (e) { + logger.e("|$_tag|跳转人脸识别页面,意外的错误error:|$e|"); EasyLoading.dismiss(); } } @@ -418,12 +423,11 @@ class SelectPayTypeDialogController extends GetxController { } Future selectPayTypeDialog() async { - final context = Get.context!; final payTypeC = Get.find(); payTypeC.initPayType(); - final theme = FTheme.of(context); - final width = context.width; - final height = context.height; + final theme = FTheme.of(Get.context!); + final width = Get.context!.width; + final height = Get.context!.height; return showDialog( context: Get.context!, barrierDismissible: false, @@ -467,14 +471,8 @@ Future selectPayTypeDialog() async { Obx( () => Visibility( visible: payTypeC.payUser.value == null, - replacement: selectPayTypeUser( - context, - payTypeC.payUser.value, - ), - child: selectPayTypeHint( - context, - payTypeC.orderPayDisplayType.value, - ), + replacement: selectPayTypeUser(payTypeC.payUser.value), + child: selectPayTypeHint(payTypeC.orderPayDisplayType.value), ), ).center().expanded(), ].toColumn().width(width * 0.5).height(height * 0.6), @@ -518,8 +516,8 @@ Future selectPayTypeDialog() async { ); } -Widget selectPayTypeUser(BuildContext context, ServiceUser? user) { - final theme = FTheme.of(context); +Widget selectPayTypeUser(ServiceUser? user) { + final theme = FTheme.of(Get.context!); if (user == null) return const SizedBox.shrink(); final isFree = user.walletIsFreeze ?? true; final textStyle = theme.typography.xl; @@ -545,7 +543,7 @@ Widget selectPayTypeUser(BuildContext context, ServiceUser? user) { style: titleTheme, prefixIcon: FIcon(FAssets.icons.badgeDollarSign), title: Text('余额', style: textStyle), - details: appPrice(context, user.walletBalance), + details: appPrice(Get.context!, user.walletBalance), ), FTile( style: titleTheme, @@ -564,8 +562,8 @@ Widget selectPayTypeUser(BuildContext context, ServiceUser? user) { .height(double.infinity); } -Widget selectPayTypeHint(BuildContext context, OrderPayDisplayType? type) { - final theme = FTheme.of(context); +Widget selectPayTypeHint(OrderPayDisplayType? type) { + final theme = FTheme.of(Get.context!); if (type == null) return const SizedBox.shrink(); const baseMsg = "请点击开始识别按钮"; String msg = ""; diff --git a/lib/main.dart b/lib/main.dart index abdbbd5..32ed252 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:ui'; import 'package:flutter/material.dart'; @@ -8,10 +9,8 @@ import 'package:pj_supermarket_cloud/app.dart'; import 'package:pj_supermarket_cloud/common/index.dart'; import 'package:pj_supermarket_cloud/sub_screen/page/index.dart'; -void main() async { - WidgetsFlutterBinding.ensureInitialized(); - DartPluginRegistrant.ensureInitialized(); - await checkSubScreen(); +void main() { + checkSubScreen(); } Future checkSubScreen() async { @@ -19,19 +18,21 @@ Future checkSubScreen() async { case "/": final appTheme = Get.put(AppThemeControl()); runApp(MainApp()); - final app = Get.put(AppControl()); - await app.initAsync(); - await appTheme.initAsync(); + await Future.microtask(() async { + final app = Get.put(AppControl()); + await app.initAsync(); + await appTheme.initAsync(); + }); break; case "subMain": - await Future(() async { - bool isMultipleScreen = await SubScreenPlugin.isMultipleScreen; - bool isOverlay = await SubScreenPlugin.checkOverlayPermission; - if (isMultipleScreen && isOverlay) { - SubScreenPlugin.doubleScreenShow(); - } + WidgetsFlutterBinding.ensureInitialized(); + DartPluginRegistrant.ensureInitialized(); + bool isMultipleScreen = await SubScreenPlugin.isMultipleScreen; + bool isOverlay = await SubScreenPlugin.checkOverlayPermission; + if (isMultipleScreen && isOverlay) { runApp(SubAppPage()); - }); + SubScreenPlugin.doubleScreenShow(); + } break; } } diff --git a/lib/pages/canteen_product/controller.dart b/lib/pages/canteen_product/controller.dart index e603e35..43ef875 100644 --- a/lib/pages/canteen_product/controller.dart +++ b/lib/pages/canteen_product/controller.dart @@ -1,11 +1,10 @@ -import 'dart:async'; - import 'package:common_utils/common_utils.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_subscreen_plugin/flutter_subscreen_plugin.dart'; -import 'package:forui/forui.dart'; import 'package:get/get.dart'; +import 'package:forui/forui.dart'; + import 'package:pj_supermarket_cloud/common/index.dart'; class CanteenProductController extends GetxController with OrderMixin { @@ -13,9 +12,7 @@ class CanteenProductController extends GetxController with OrderMixin { static const _tag = "食堂购买页面"; - final app = Get.find(); - - StreamSubscription? mqUpdateListen; + final appC = Get.find(); final hourTypeC = FRadioSelectGroupController( value: ProductHourType.MORNING.code, @@ -27,42 +24,48 @@ class CanteenProductController extends GetxController with OrderMixin { update(["canteen_product"]); } - void onTap() {} - @override void onInit() async { super.onInit(); - EasyLoading.dismiss(); + await _initState(); + } + + @override + void onReady() { + super.onReady(); + _initData(); + } + + @override + void onClose() { + super.onClose(); + SubScreenPlugin.sendMsgToViceScreen(SubScreenAction.jumpSubBack.name); + // 读卡器 + appC.serialCardManage.readerClose(); + appC.serialCardManage.close(); + hourTypeC.dispose(); + } + + Future _initState() async { EasyLoading.show( status: '初始化资源...', maskType: EasyLoadingMaskType.black, ); - appSetting = await AppSettingTool.getSysSetting(); - // 打开副屏 - SubScreenPlugin.doubleScreenShow(); SubScreenPlugin.sendMsgToViceScreen(SubScreenAction.jumpSubPage.name); - - /// **************** start 组件初始化 start **************** + // 组件初始化 hourType.value = appSetting.hourType ?? ProductHourType.MORNING; hourTypeC.value = {hourType.value.code}; sysType = SysType.CANTEEN; _listenPayTypeSelectCallback(); - - /// **************** end 组件初始化 end **************** - - /// **************** start 获取分类和商品 start **************** - + // 获取分类和商品 await getClassify(); await getProduct(); - - /// **************** end 获取分类和商品 end **************** - + // 清空购物车 await _clearShopCard(); - EasyLoading.dismiss(); - + // 监听时间段选择 hourTypeC.addValueListener((v) async { final currentHourType = ProductHourType.values.fromCode( v.first, @@ -84,32 +87,13 @@ class CanteenProductController extends GetxController with OrderMixin { }); } - @override - void onReady() { - super.onReady(); - _initData(); - } - - @override - void onClose() { - super.onClose(); - SubScreenPlugin.sendMsgToViceScreen(SubScreenAction.jumpSubBack.name); - // 读卡器 - app.serialCardManage.readerClose(); - app.serialCardManage.close(); - // 路由监听 - routerBus?.cancel(); - mqUpdateListen?.cancel(); - hourTypeC.dispose(); - } - // |下单|点击购买 Future doPay() async { final validShopCar = _validateShopCar(); if (!validShopCar) return; // 创建本地订单 await createSqlOrder(); - await selectPayTypeDialog(); + selectPayTypeDialog(); } // |下单|点击取消下单 @@ -131,7 +115,6 @@ class CanteenProductController extends GetxController with OrderMixin { return e.productServiceUniqueCode == current.productServiceUniqueCode; }); } - shopCardList.refresh(); computedTotalPrice(); await _computedAmountMealPrice(); sendSubScreen(); @@ -162,7 +145,6 @@ class CanteenProductController extends GetxController with OrderMixin { target.productNumber, ); } - shopCardList.refresh(); computedTotalPrice(); await _computedAmountMealPrice(); sendSubScreen(); @@ -194,7 +176,6 @@ class CanteenProductController extends GetxController with OrderMixin { this.orderPayDisplayType.value = orderPayDisplayType; this.globalQrCode = qrCode; payUser.value = user; - payUser.refresh(); final validPayUser = _validatePayUser(); if (!validPayUser) return; final validShopCar = _validateShopCar(); @@ -265,9 +246,8 @@ class CanteenProductController extends GetxController with OrderMixin { // 获取默认商品 Future _getDefaultProduct() async { - final appSetting = await AppSettingTool.getSysSetting(); final sysType = appSetting.sysType.name; - final productDao = app.dataBase.getProductDao; + final productDao = appC.dataBase.getProductDao; List list = await productDao.getDefault( sysType, hourType.value.code, diff --git a/lib/pages/canteen_product/view.dart b/lib/pages/canteen_product/view.dart index 2a62a1b..246fcc3 100644 --- a/lib/pages/canteen_product/view.dart +++ b/lib/pages/canteen_product/view.dart @@ -1,8 +1,10 @@ -import 'package:common_utils/common_utils.dart'; -import 'package:ducafe_ui_core/ducafe_ui_core.dart'; import 'package:flutter/material.dart'; -import 'package:forui/forui.dart'; + +import 'package:common_utils/common_utils.dart'; import 'package:get/get.dart'; +import 'package:ducafe_ui_core/ducafe_ui_core.dart'; +import 'package:forui/forui.dart'; + import 'package:pj_supermarket_cloud/common/index.dart'; import 'index.dart'; @@ -11,71 +13,33 @@ class CanteenProductPage extends GetView { const CanteenProductPage({super.key}); // 头部 - Widget _buildHeader(BuildContext context, double headerHeight) { + Widget _buildHeader(double headerHeight) { + final context = Get.context!; final theme = FTheme.of(context); return [ FIcon( FAssets.icons.chevronLeft, size: theme.typography.xl4.fontSize, - ).alignLeft().width(headerHeight).onTap(() => Get.back()), - Obx(() => controller.classifyList - .map( - (v) { - final currentIndex = controller.currentTabIndex.value; - final target = controller.classifyList[currentIndex]; - final active = target.id == v.id; - return FButton( - style: - active ? FButtonStyle.primary : FButtonStyle.secondary, - label: Text( - v.name, - textAlign: TextAlign.center, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: theme.typography.xl.copyWith( - color: active - ? theme.colorScheme.secondary - : theme.colorScheme.primary, - ), - ).center().width(120.w), - onPress: () => controller.doTab( - controller.classifyList.indexWhere((i) => i.id == v.id), - ), - ); - }, - ) - .toList() - .toRowSpace(space: 20.w)) - .scrollable(scrollDirection: Axis.horizontal) - .expanded(), - appRadioHourTypeDialog( - context, - controller.hourTypeC, - ).width(300.w), - ].toRow(); - } - - // 主体部分 - Widget _buildMain(BuildContext context) { - final width = context.width; - final theme = FTheme.of(context); - return [ - _buildProduct(context).expanded(), - SizedBox(width: 15.w), - _buildUser(context).width(width * 0.25).decorated( - border: Border.all( - color: theme.colorScheme.primary, - width: 1, - ), - borderRadius: theme.style.borderRadius, - ), + ) + .alignLeft() + .width(headerHeight) + .onTap(() => Get.offAndToNamed(RouteNames.panel)), + Obx( + () => orderRowClassify( + context, + classifyList: controller.classifyList, + currentTabIndex: controller.currentTabIndex, + onChange: (tabIndex) => controller.doTab(tabIndex), + ), + ).scrollable(scrollDirection: Axis.horizontal).expanded(), + appRadioHourTypeDialog(context, controller.hourTypeC).width(300.w), ].toRow(); } // 商品 - Widget _buildProduct(BuildContext context) { + Widget _buildProduct() { return LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { + builder: (BuildContext _, BoxConstraints constraints) { const spacing = 10; const runSpacing = 10; double maxHeight = constraints.maxHeight; @@ -166,31 +130,31 @@ class CanteenProductPage extends GetView { } // 用户信息 - Widget _buildUser(BuildContext context) { - final theme = FTheme.of(context); + Widget _buildUser() { + final theme = FTheme.of(Get.context!); return [ [ Obx(() { final payUser = controller.payUser.value; return appUserInfo( - context, + Get.context!, username: payUser?.username, balance: payUser?.walletBalance, avatar: payUser?.userAvatar, ); - }).width(400.w), - ].toRow(mainAxisAlignment: MainAxisAlignment.center), - SizedBox(height: 10.h), - FDivider( - style: theme.dividerStyles.verticalStyle.copyWith( - color: theme.colorScheme.primary, - padding: EdgeInsets.zero, + }).width(400.w).center(), + SizedBox(height: 10.h), + FDivider( + style: theme.dividerStyles.verticalStyle.copyWith( + color: theme.colorScheme.primary, + padding: EdgeInsets.zero, + ), ), - ), - Text( - "已点菜品", - style: theme.typography.xl2, - ).alignLeft(), + Text( + "已点菜品", + style: theme.typography.xl2, + ).alignLeft(), + ].toColumn(), Obx( () => ListView.builder( padding: EdgeInsets.zero, @@ -198,7 +162,7 @@ class CanteenProductPage extends GetView { itemBuilder: (context, index) { final current = controller.shopCardList[index]; return orderSelectPanel( - context, + Get.context!, label: current.productName, price: current.productPrice, total: current.productNumber, @@ -209,14 +173,14 @@ class CanteenProductPage extends GetView { }, ), ).expanded(), - Obx( - () => orderAllPrice( - context, - totalPrice: controller.totalPrice.value, - amountMealPrice: controller.amountMealPrice.value, - ), - ), [ + Obx( + () => orderAllPrice( + Get.context!, + totalPrice: controller.totalPrice.value, + amountMealPrice: controller.amountMealPrice.value, + ), + ), SizedBox(height: 20.h), [ FButton( @@ -245,29 +209,36 @@ class CanteenProductPage extends GetView { } // 主视图 - Widget _buildView(BuildContext context) { + Widget _buildView() { + final context = Get.context!; + final width = context.width; + final theme = FTheme.of(context); return [ - _buildMain(context).marginOnly(bottom: 20.h).expanded(), - ].toColumn(); + _buildProduct().expanded(), + SizedBox(width: 15.w), + _buildUser().width(width * 0.25).decorated( + border: Border.all( + color: theme.colorScheme.primary, + width: 1, + ), + borderRadius: theme.style.borderRadius, + ), + ].toRow().marginOnly(bottom: 20.h); } @override Widget build(BuildContext context) { - final height = context.height; - final headerHeight = height * 0.08; + final height = 90; return GetBuilder( - init: CanteenProductController(), + init: Get.find(), id: "canteen_product", builder: (_) { return FScaffold( - header: _buildHeader( - context, - headerHeight, - ) - .height(headerHeight) - .padding(vertical: 30.h, horizontal: 10.w) - .decorated(), - content: _buildView(context), + header: _buildHeader(height.h) + .height(height.h) + .padding(vertical: 30.h, horizontal: 10.w), + content: _buildView(), + contentPad: true, resizeToAvoidBottomInset: false, ); }, diff --git a/lib/pages/panel/controller.dart b/lib/pages/panel/controller.dart index 16f915b..4c1340f 100644 --- a/lib/pages/panel/controller.dart +++ b/lib/pages/panel/controller.dart @@ -11,7 +11,7 @@ class PanelController extends GetxController { RxList panelBtnList = [ PanelItem(title: "购买", visible: false, type: PanelType.supermarketOrder), PanelItem(title: "点餐", visible: false, type: PanelType.canteenOrder), - PanelItem(title: "取餐", visible: true, type: PanelType.takeFood), + PanelItem(title: "取餐", visible: false, type: PanelType.takeFood), PanelItem(title: "交易查询", visible: true, type: PanelType.orderHistory), PanelItem(title: "开卡管理", visible: true, type: PanelType.cardActive), PanelItem(title: "设置", visible: true, type: PanelType.setting), @@ -21,15 +21,17 @@ class PanelController extends GetxController { final canteenMenus = [ PanelType.canteenOrder, + PanelType.takeFood, ]; final supermarketMenus = [ PanelType.supermarketOrder, ]; - _initData() async { + @override + void onInit() async { + super.onInit(); await _updateMenus(); - update(["panel"]); } @override @@ -38,15 +40,19 @@ class PanelController extends GetxController { _initData(); } + _initData() async { + update(["panel"]); + } + Future doBtn(PanelType type) async { switch (type) { case PanelType.supermarketOrder: if (!await _checkIsBind()) return; - Get.toNamed(RouteNames.supermarketProduct); + Get.offAllNamed(RouteNames.supermarketProduct); break; case PanelType.canteenOrder: if (!await _checkIsBind()) return; - Get.toNamed(RouteNames.canteenProduct); + Get.offAllNamed(RouteNames.canteenProduct); break; case PanelType.takeFood: if (!await _checkIsBind()) return; @@ -75,7 +81,6 @@ class PanelController extends GetxController { Get.offAndToNamed(RouteNames.login); break; case PanelType.test: - await AppFaceTool.jumpFacePage(); break; default: break; diff --git a/lib/pages/setting/controller.dart b/lib/pages/setting/controller.dart index 667cb88..8efa995 100644 --- a/lib/pages/setting/controller.dart +++ b/lib/pages/setting/controller.dart @@ -87,6 +87,7 @@ class SettingController extends GetxController { if (payType == null) continue; usePayList.add(payType); } + usePayList.sort((pren, next) => pren.code.compareTo(next.code)); sysSetting.value?.usePayDisplayType = usePayList; await AppSettingTool.setSysSetting(sysSetting.value!); }); @@ -131,7 +132,8 @@ class SettingController extends GetxController { maskType: EasyLoadingMaskType.black, ); try { - await SyncConfigTool.autoSyncSysInfo(); + final setting = await SyncConfigTool.autoSyncSysInfo(); + if (setting != null) sysSetting.value = setting; Toast.success(msg: "同步设备信息成功"); EasyLoading.dismiss(); } catch (e, stack) { diff --git a/lib/pages/setting/widgets/setting_baseInfo.dart b/lib/pages/setting/widgets/setting_baseInfo.dart index a11a579..760bc5c 100644 --- a/lib/pages/setting/widgets/setting_baseInfo.dart +++ b/lib/pages/setting/widgets/setting_baseInfo.dart @@ -16,9 +16,9 @@ Future _bindServiceDialog(BuildContext context, SysSetting sys) async { uniqueCodeC.text = sys.serviceId ?? ""; } else if (AppSysTool.isDev()) { // 超市 - uniqueCodeC.text = "1894303392833716226"; + // uniqueCodeC.text = "1894303392833716226"; // 测试 - // uniqueCodeC.text = "1896157295523049473"; + uniqueCodeC.text = "1896157295523049473"; } await showAdaptiveDialog( context: context, diff --git a/lib/pages/supermarket_order/controller.dart b/lib/pages/supermarket_order/controller.dart index 275834e..23720d1 100644 --- a/lib/pages/supermarket_order/controller.dart +++ b/lib/pages/supermarket_order/controller.dart @@ -1,6 +1,8 @@ import 'package:get/get.dart'; -class SupermarketOrderController extends GetxController { +import 'package:pj_supermarket_cloud/common/index.dart'; + +class SupermarketOrderController extends GetxController with OrderMixin { SupermarketOrderController(); _initData() { @@ -9,10 +11,10 @@ class SupermarketOrderController extends GetxController { void onTap() {} - // @override - // void onInit() { - // super.onInit(); - // } + @override + void onInit() { + super.onInit(); + } @override void onReady() { @@ -20,8 +22,8 @@ class SupermarketOrderController extends GetxController { _initData(); } - // @override - // void onClose() { - // super.onClose(); - // } + @override + void onClose() { + super.onClose(); + } } diff --git a/lib/pages/supermarket_order/view.dart b/lib/pages/supermarket_order/view.dart index 2fdbfaa..414ec98 100644 --- a/lib/pages/supermarket_order/view.dart +++ b/lib/pages/supermarket_order/view.dart @@ -3,11 +3,36 @@ import 'package:flutter/material.dart'; import 'package:forui/forui.dart'; import 'package:get/get.dart'; +import 'package:pj_supermarket_cloud/common/index.dart'; + import 'index.dart'; class SupermarketOrderPage extends GetView { const SupermarketOrderPage({super.key}); + // 头部 + Widget _buildHeader(double headerHeight) { + final context = Get.context!; + final theme = FTheme.of(context); + return [ + FIcon( + FAssets.icons.chevronLeft, + size: theme.typography.xl4.fontSize, + ) + .alignLeft() + .width(headerHeight) + .onTap(() => Get.offAndToNamed(RouteNames.panel)), + Obx( + () => orderRowClassify( + context, + classifyList: controller.classifyList, + currentTabIndex: controller.currentTabIndex, + onChange: (tabIndex) => controller.doTab(tabIndex), + ), + ).scrollable(scrollDirection: Axis.horizontal).expanded(), + ].toRow(); + } + // 主视图 Widget _buildView(BuildContext context) { return const Center( @@ -17,26 +42,17 @@ class SupermarketOrderPage extends GetView { @override Widget build(BuildContext context) { - final theme = FTheme.of(context); - final height = context.height; + final height = 90; return GetBuilder( init: SupermarketOrderController(), id: "supermarket_order", builder: (_) { return FScaffold( - header: FHeader.nested( - title: Text("取餐"), - prefixActions: [ - FHeaderAction.back(onPress: Get.back), - ], - style: theme.headerStyle.nestedStyle.copyWith( - titleTextStyle: theme.typography.lg, - actionStyle: theme.headerStyle.nestedStyle.actionStyle.copyWith( - size: theme.typography.xl2.fontSize, - ), - ), - ).height(height * 0.1), + header: _buildHeader(height.h) + .height(height.h) + .padding(vertical: 30.h, horizontal: 10.w), content: _buildView(context), + contentPad: true, resizeToAvoidBottomInset: false, ); }, diff --git a/lib/sub_screen/page/sub_app.dart b/lib/sub_screen/page/sub_app.dart index 68f9ac2..11ce906 100644 --- a/lib/sub_screen/page/sub_app.dart +++ b/lib/sub_screen/page/sub_app.dart @@ -1,9 +1,9 @@ import 'dart:async'; -import 'package:ducafe_ui_core/ducafe_ui_core.dart'; +// import 'package:ducafe_ui_core/ducafe_ui_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_subscreen_plugin/flutter_subscreen_plugin.dart'; -import 'package:forui/forui.dart'; +// import 'package:forui/forui.dart'; import 'package:pj_supermarket_cloud/common/index.dart'; import 'package:pj_supermarket_cloud/sub_screen/page/index.dart'; @@ -37,7 +37,6 @@ class _SubAppPageState extends State { @override Widget build(BuildContext context) { - final theme = FTheme.of(context); return MaterialApp( navigatorKey: SubNavigatorKey.navigatorKey, debugShowCheckedModeBanner: false, @@ -45,11 +44,8 @@ class _SubAppPageState extends State { SubRouteNames.subProduct: (context) => const SubProductPage(), }, home: Scaffold( - backgroundColor: theme.colorScheme.background, - body: Text( - '欢迎使用', - style: theme.typography.xl4, - ).center(), + backgroundColor: Colors.white, + body: Text('欢迎使用'), ), ); } diff --git a/lib/sub_screen/page/sub_product.dart b/lib/sub_screen/page/sub_product.dart index 9e0da39..bc8d2ad 100644 --- a/lib/sub_screen/page/sub_product.dart +++ b/lib/sub_screen/page/sub_product.dart @@ -1,10 +1,8 @@ import 'dart:async'; -import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_subscreen_plugin/flutter_subscreen_plugin.dart'; -import 'package:pj_supermarket_cloud/common/index.dart'; - class SubProductPage extends StatefulWidget { const SubProductPage({super.key}); @@ -19,10 +17,10 @@ class _SubProductPageState extends State { void initState() { super.initState(); _streamSubscription = SubScreenPlugin.viceStream.listen((event) { - dynamic params = event.arguments; - final action = SubScreenAction.values.fromCode(event.method); - if (action == null) return; - if (action == SubScreenAction.updateCard) {} + // dynamic params = event.arguments; + // final action = SubScreenAction.values.fromCode(event.method); + // if (action == null) return; + // if (action == SubScreenAction.updateCard) {} }); } @@ -34,6 +32,8 @@ class _SubProductPageState extends State { @override Widget build(BuildContext context) { - return Container(); + return Container( + color: Colors.white, + ); } } diff --git a/pubspec.lock b/pubspec.lock index 19c75a9..2e57d5f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -142,6 +142,30 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "8.9.4" + cached_network_image: + dependency: "direct main" + description: + name: cached_network_image + sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.4.1" + cached_network_image_platform_interface: + dependency: transitive + description: + name: cached_network_image_platform_interface + sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.1.1" + cached_network_image_web: + dependency: transitive + description: + name: cached_network_image_web + sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.3.1" characters: dependency: transitive description: @@ -346,10 +370,10 @@ packages: dependency: "direct main" description: name: external_path - sha256: e6d70bd47ee25d164287ecab65426684825439c6a39ee1895c6193d65576ee13 + sha256: "68a18a2aa51ec012d7013ea2a80305dc5372f3577a2bbcc7dcc5550b25a5a73b" url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.0" + version: "2.2.0" fake_async: dependency: transitive description: @@ -411,6 +435,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_cache_manager: + dependency: transitive + description: + name: flutter_cache_manager + sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.4.1" flutter_easyloading: dependency: "direct main" description: @@ -802,6 +834,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.1.6" + octo_image: + dependency: transitive + description: + name: octo_image + sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.0" package_config: dependency: transitive description: @@ -1018,6 +1058,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.2.3" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.28.0" shelf: dependency: transitive description: @@ -1071,14 +1119,30 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.10.0" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.flutter-io.cn" + source: hosted + version: "7.0.0" sqflite: dependency: "direct main" description: name: sqflite - sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6 + sha256: "2d7299468485dca85efeeadf5d38986909c5eb0cd71fd3db2c2f000e6c9454bb" url: "https://pub.flutter-io.cn" source: hosted - version: "2.3.2" + version: "2.4.1" + sqflite_android: + dependency: transitive + description: + name: sqflite_android + sha256: "78f489aab276260cdd26676d2169446c7ecd3484bbd5fead4ca14f3ed4dd9ee3" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.0" sqflite_common: dependency: transitive description: @@ -1095,6 +1159,22 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.3.4+4" + sqflite_darwin: + dependency: transitive + description: + name: sqflite_darwin + sha256: "22adfd9a2c7d634041e96d6241e6e1c8138ca6817018afc5d443fef91dcefa9c" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.1+1" + sqflite_platform_interface: + dependency: transitive + description: + name: sqflite_platform_interface + sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.0" sqlite3: dependency: transitive description: @@ -1239,6 +1319,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.2.2" + uuid: + dependency: transitive + description: + name: uuid + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.5.1" vector_graphics: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 99e48aa..f33ac34 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,7 +27,7 @@ dependencies: # 图片处理 image: ^4.3.0 # 图片缓存 - # cached_network_image: 3.3.1 + cached_network_image: ^3.4.1 # 表格 data_table_2: ^2.5.18 # 分页 @@ -40,18 +40,18 @@ dependencies: # 权限判断 permission_handler: ^11.4.0 # 串口 - flutter_libserialport: 0.5.0 + flutter_libserialport: ^0.5.0 # 状态管理、路由 get: ^4.7.2 # 双屏 - flutter_subscreen_plugin: 1.3.2+5 + flutter_subscreen_plugin: ^1.3.2+5 # 数据库 - sqflite: 2.3.2 + sqflite: 2.4.1 floor: 1.4.2 # json序列化 json_annotation: ^4.9.0 # 外部路径获取 - external_path: ^2.0.1 + external_path: ^2.2.0 # 获取唯一id android_id: ^0.4.0 # 监听网络状态