From c2b50b0a1882ec8dc4869e2f9c6945b003590b43 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Mon, 10 Mar 2025 17:43:29 +0800 Subject: [PATCH] 11 --- android/app/src/main/AndroidManifest.xml | 1 - lib/app.dart | 13 +- lib/common/api/hard_api.dart | 80 ++++------ .../models/database/database_models.dart | 3 + lib/common/models/index.dart | 2 +- ...els.dart => setting_page_enum_models.dart} | 17 +++ lib/common/utils/app/app_file_tool.dart | 3 +- lib/common/utils/app/control/app_control.dart | 3 - .../utils/app/control/app_theme_control.dart | 20 ++- lib/common/utils/logger/logger_tool.dart | 55 ++++--- lib/common/utils/manage/mq_manager.dart | 6 +- lib/common/utils/sync/sync_config_tool.dart | 7 +- lib/common/utils/sync/sync_order_tool.dart | 5 +- .../widgets/order/mixin/order_mixin.dart | 9 +- .../widgets/order/select_pay_type_dialog.dart | 22 ++- lib/main.dart | 2 + lib/pages/login/controller.dart | 4 +- lib/pages/login/view.dart | 10 +- lib/pages/order_history/controller.dart | 5 +- lib/pages/panel/controller.dart | 23 ++- lib/pages/panel/view.dart | 17 ++- lib/pages/setting/controller.dart | 137 ++++++++++++++++- .../setting/widgets/setting_baseInfo.dart | 52 +++++-- lib/pages/setting/widgets/setting_sync.dart | 138 ++++++++++-------- lib/pages/take_food/controller.dart | 4 +- pubspec.lock | 48 ++++++ pubspec.yaml | 3 +- 27 files changed, 489 insertions(+), 200 deletions(-) rename lib/common/models/page/{setting_page_models.dart => setting_page_enum_models.dart} (67%) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index eabfe36..a1eaa9c 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,7 +7,6 @@ - diff --git a/lib/app.dart b/lib/app.dart index 2d477fa..9d33c86 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -12,11 +12,12 @@ class MainApp extends StatelessWidget { @override Widget build(BuildContext context) { return ScreenUtilInit( - designSize: const Size(1920, 1080), - minTextAdapt: true, - splitScreenMode: true, - builder: (_, child) { - final appTheme = Get.put(AppThemeControl()); + designSize: const Size(1920, 1080), + minTextAdapt: true, + splitScreenMode: true, + builder: (_, child) { + return Obx(() { + final appTheme = Get.find(); final fTheme = appTheme.theme.value; final sizeScalar = appTheme.sizeScalar.value; final themeData = FThemeData.inherit( @@ -46,6 +47,8 @@ class MainApp extends StatelessWidget { ), ); }); + }, + ); } } diff --git a/lib/common/api/hard_api.dart b/lib/common/api/hard_api.dart index 7a28cf7..2a39986 100644 --- a/lib/common/api/hard_api.dart +++ b/lib/common/api/hard_api.dart @@ -12,61 +12,47 @@ abstract class HardApi { } /// 获取硬件配置信息 - static Future> get(dynamic pa) async { - final res = await HttpManage().dio.get>( + static Future get(dynamic pa) async { + final res = await HttpManage().dio.get( "/hard/hard-api/ad/get", queryParameters: pa, ); - if (res.data?.data == null) { - return res.data!; - } - final map = res.data!.data as Map; - final typeData = ServiceHardware.fromJson(map); - res.data?.data = typeData; - return res.data!; + if (res.data == null) return null; + return ServiceHardware.fromJson(res.data); } /// 获取用户信息 - static Future> getUserInfoById( + static Future getUserInfoById( dynamic formData, ) async { - final res = await HttpManage().dio.get>( + final res = await HttpManage().dio.get( "/hard/hard-api/ad/get-user", queryParameters: formData, ); - if (res.data?.data == null) { - return res.data!; - } - final map = res.data!.data as Map; - final typeData = ServiceUser.fromJson(map); - res.data?.data = typeData; - return res.data!; + if (res.data == null) return null; + return ServiceUser.fromJson(res.data); } /// 获取用户信息 - static Future> getUserByCard( + static Future getUserByCard( dynamic formData, ) async { - final res = await HttpManage().dio.get>( + final res = await HttpManage().dio.get( "/hard/hard-api/ad/get-user-by-card", queryParameters: formData, ); - if (res.data?.data == null) { - return res.data!; - } - final map = res.data!.data as Map; - final typeData = ServiceUser.fromJson(map); - res.data?.data = typeData; - return res.data!; + if (res.data == null) return null; + return ServiceUser.fromJson(res.data); } /// 创建硬件订单 - static Future createHardwareOrder(dynamic formData) async { - final res = await HttpManage().dio.post( + static Future createHardwareOrder(dynamic formData) async { + final res = await HttpManage().dio.post( "/hard/hard-api/ad/create-order", data: formData, ); - return res.data as ServiceBase; + if (res.data == null) return null; + return res.data; } /// 获取订单详情 @@ -92,46 +78,44 @@ abstract class HardApi { } /// 核销订单 - static Future cancelQrCode(dynamic formData) async { - final res = await HttpManage().dio.post( + static Future cancelQrCode(dynamic formData) async { + final res = await HttpManage().dio.post( "/hard/hard-api/ad/cancel-code", data: formData, ); - return res.data!; + if (res.data == null) return false; + return true; } /// 生成发票 - static Future> generateInvoice( + static Future generateInvoice( dynamic formData, ) async { - final res = await HttpManage().dio.get>( + final res = await HttpManage().dio.get( "/hard/hard-api/ad/generate-invoice", queryParameters: formData, ); - if (res.data?.data == null) { - return res.data!; - } - final map = res.data!.data as Map; - final typeData = ServiceGenerateInvoice.fromJson(map); - res.data?.data = typeData; - return res.data!; + if (res.data == null) return null; + return ServiceGenerateInvoice.fromJson(res.data); } /// 打印成功 - static Future printInvoice(dynamic formData) async { - final res = await HttpManage().dio.get( + static Future printInvoice(dynamic formData) async { + final res = await HttpManage().dio.get( "/hard/hard-api/ad/print-invoice", queryParameters: formData, ); - return res.data as ServiceBase; + if (res.data == null) return false; + return true; } /// 离线同步 - static Future syncOfflineOrder(dynamic formData) async { - final res = await HttpManage().dio.post( + static Future?> syncOfflineOrder(dynamic formData) async { + final res = await HttpManage().dio.post( "/hard/hard-api/ad/sync-offline-order", data: formData, ); - return res.data as ServiceBase; + if (res.data == null) return null; + return res.data?.map((e) => e.toString()).toList(); } } diff --git a/lib/common/models/database/database_models.dart b/lib/common/models/database/database_models.dart index ae0505e..648603e 100644 --- a/lib/common/models/database/database_models.dart +++ b/lib/common/models/database/database_models.dart @@ -167,6 +167,9 @@ class UserSetting extends Equatable { /// 商品时间段类型 ProductHourType? hourType; + // 全局字体大小 + SettingGlobalFontSize? globalFontSize; + UserSetting({ this.username, this.password, diff --git a/lib/common/models/index.dart b/lib/common/models/index.dart index bdf02e7..d52cc10 100644 --- a/lib/common/models/index.dart +++ b/lib/common/models/index.dart @@ -11,7 +11,7 @@ export './base/base_models.dart'; export './page/order_page_enum_models.dart'; export './page/order_page_models.dart'; export './page/panel_page_models.dart'; -export './page/setting_page_models.dart'; +export './page/setting_page_enum_models.dart'; export './mq/mq_enum_models.dart'; export './mq/mq_models.dart'; diff --git a/lib/common/models/page/setting_page_models.dart b/lib/common/models/page/setting_page_enum_models.dart similarity index 67% rename from lib/common/models/page/setting_page_models.dart rename to lib/common/models/page/setting_page_enum_models.dart index abc267d..529231f 100644 --- a/lib/common/models/page/setting_page_models.dart +++ b/lib/common/models/page/setting_page_enum_models.dart @@ -30,3 +30,20 @@ class SettingMenu { required this.type, }); } + +enum SettingGlobalFontSize implements BaseEnum { + xl("1.2", "1.2", 1.2), + xl2("1.3", "1.3", 1.3), + xl3("1.4", "1.4", 1.4), + xl4("1.5", "1.5", 1.5), + ; + + @override + final String code; + @override + final String title; + + final double fontSize; + + const SettingGlobalFontSize(this.code, this.title, this.fontSize); +} diff --git a/lib/common/utils/app/app_file_tool.dart b/lib/common/utils/app/app_file_tool.dart index 40bcd9c..5febfbe 100644 --- a/lib/common/utils/app/app_file_tool.dart +++ b/lib/common/utils/app/app_file_tool.dart @@ -68,7 +68,8 @@ abstract class AppFileTool { int day = now.day; dir = "$dir/$year-$month"; dir = await _checkAndcreateDir(dir); - return "$dir/$day.log"; + dir = "$dir/$day.log"; + return dir; } /// 创建人脸地址 diff --git a/lib/common/utils/app/control/app_control.dart b/lib/common/utils/app/control/app_control.dart index c11a07b..e03fddf 100644 --- a/lib/common/utils/app/control/app_control.dart +++ b/lib/common/utils/app/control/app_control.dart @@ -43,7 +43,6 @@ class AppControl extends GetxController { } Future initAsync() async { - final stopwatch = Stopwatch()..start(); dataBase = await AppDatabase.getDataBase(); printManage = PrintManage(); scanCodeManage = ScanCodeManage(); @@ -51,7 +50,5 @@ class AppControl extends GetxController { srialSteelyardManage = SerialSteelyardManage(); AppNetworkTool.listenNetwork(); Get.offAllNamed(RouteNames.login); - stopwatch.stop(); - logger.d('|$_tag|initAsync耗时:${stopwatch.elapsedMilliseconds}毫秒'); } } diff --git a/lib/common/utils/app/control/app_theme_control.dart b/lib/common/utils/app/control/app_theme_control.dart index 2900d78..65940f0 100644 --- a/lib/common/utils/app/control/app_theme_control.dart +++ b/lib/common/utils/app/control/app_theme_control.dart @@ -1,10 +1,28 @@ import 'package:forui/forui.dart'; import 'package:get/get.dart'; +import 'package:pj_supermarket_cloud/common/index.dart'; + class AppThemeControl extends GetxController { /// 主题 Rx theme = FThemes.zinc.light.obs; /// 字体大小 - RxDouble sizeScalar = 1.4.obs; + RxDouble sizeScalar = SettingGlobalFontSize.xl3.fontSize.obs; + + @override + void onInit() async { + super.onInit(); + } + + Future initAsync() async { + final userInfo = await AppSettingTool.getUserSetting(); + if (userInfo.globalFontSize != null) { + sizeScalar.value = userInfo.globalFontSize!.fontSize; + } + } + + void setSizeScalar(SettingGlobalFontSize fontSize) { + sizeScalar.value = fontSize.fontSize; + } } diff --git a/lib/common/utils/logger/logger_tool.dart b/lib/common/utils/logger/logger_tool.dart index 7fcee46..f573563 100644 --- a/lib/common/utils/logger/logger_tool.dart +++ b/lib/common/utils/logger/logger_tool.dart @@ -27,19 +27,30 @@ class ConsoleOutput extends LogOutput { @override Future init() async { - _filePath = await AppFileTool.getLoggerBackupPath(); - if (ObjectUtil.isNotEmpty(_filePath)) { - _sink = File(_filePath!).openWrite( - mode: FileMode.writeOnlyAppend, - encoding: utf8, - ); + try { + _filePath = await AppFileTool.getLoggerBackupPath(); + if (ObjectUtil.isNotEmpty(_filePath)) { + _sink = File(_filePath!).openWrite( + mode: FileMode.writeOnlyAppend, + encoding: utf8, + ); + } + _timer = Timer.periodic(const Duration(seconds: 60 * 60 * 2), + (Timer timer) async { + final path = await AppFileTool.getLoggerBackupPath(); + if (path == null) return; + // 关闭旧的sink并创建新的 + await _sink?.flush(); + await _sink?.close(); + _filePath = path; + _sink = File(_filePath!).openWrite( + mode: FileMode.writeOnlyAppend, + encoding: utf8, + ); + }); + } catch (e, stack) { + print("初始化日志错误error:|$e|stack:|$stack|"); } - _timer = Timer.periodic(const Duration(seconds: 60 * 60 * 2), - (Timer timer) async { - final path = await AppFileTool.getLoggerBackupPath(); - if (path == null) return; - _filePath = path; - }); } @override @@ -51,15 +62,19 @@ class ConsoleOutput extends LogOutput { @override void output(OutputEvent event) { - if (AppSysTool.isDev()) { - for (final v in event.lines) { - print(v); + try { + if (AppSysTool.isDev()) { + for (final v in event.lines) { + print(v); + } + } else { + if (_filePath == null) return; + if (_sink == null) return; + if (Level.debug == event.level) return; + _sink?.writeAll(event.lines, '\n'); } - } else { - if (_filePath == null) return; - if (_sink == null) return; - if (Level.debug == event.level) return; - _sink?.writeAll(event.lines, '\n'); + } catch (e, stack) { + print("写入日志错误error:|$e|stack:|$stack|"); } } } diff --git a/lib/common/utils/manage/mq_manager.dart b/lib/common/utils/manage/mq_manager.dart index bb4eb52..dbc834e 100644 --- a/lib/common/utils/manage/mq_manager.dart +++ b/lib/common/utils/manage/mq_manager.dart @@ -106,8 +106,10 @@ class MqManager { if (ObjectUtil.isEmpty(mqttClient)) { await initMqtt(); } else if (MqManager.state != MqttConnectionState.connected) { - final res = - await mqttClient!.connect(config!.mqUsername, config.mqPassword); + final res = await mqttClient!.connect( + config!.mqUsername, + config.mqPassword, + ); if (res != null && res.state != MqManager.state) { MqManager.state = res.state; } diff --git a/lib/common/utils/sync/sync_config_tool.dart b/lib/common/utils/sync/sync_config_tool.dart index 60322c6..bdf8ef4 100644 --- a/lib/common/utils/sync/sync_config_tool.dart +++ b/lib/common/utils/sync/sync_config_tool.dart @@ -17,12 +17,11 @@ abstract class SyncConfigTool { if (ObjectUtil.isEmpty(sysSetting.serviceId)) return; final serviceId = sysSetting.serviceId; final pa = {"id": serviceId}; - final res = await HardApi.get(pa); - if (res.code != 0) { - logger.e("|$_tag|同步设备信息错误serviceId:|$serviceId|;res:$res;"); + final data = await HardApi.get(pa); + if (data == null) { + logger.e("|$_tag|同步设备信息错误serviceId:|$serviceId|;"); return; } - final data = res.data as ServiceHardware; // 基本信息 await AppSettingTool.updateSysInfoByService(data); // 人脸sdk diff --git a/lib/common/utils/sync/sync_order_tool.dart b/lib/common/utils/sync/sync_order_tool.dart index d826c3c..bebb439 100644 --- a/lib/common/utils/sync/sync_order_tool.dart +++ b/lib/common/utils/sync/sync_order_tool.dart @@ -62,9 +62,8 @@ abstract class SyncOrderTool { }; logger.i("|$_tag|同步参数:|$pa|"); try { - final res = await HardApi.syncOfflineOrder(pa); - if (res.code != 0 || res.data == null) throw Error(); - final data = res.data as List; + final data = await HardApi.syncOfflineOrder(pa); + if (data == null) throw Error(); final batchEditCount = await handEditOfflineStatus(data); logger.i("|$_tag|同步成功的数量为:|$batchEditCount|ids为:|$data|"); } catch (e) { diff --git a/lib/common/widgets/order/mixin/order_mixin.dart b/lib/common/widgets/order/mixin/order_mixin.dart index 6d3a3d0..af6e0d6 100644 --- a/lib/common/widgets/order/mixin/order_mixin.dart +++ b/lib/common/widgets/order/mixin/order_mixin.dart @@ -298,13 +298,10 @@ mixin OrderMixin { logger.i("|$_tag|创建api订单,下单参数:|${json.encode(pa)}|"); try { if (isNetwork) { - final res = await HardApi.createHardwareOrder(pa); - if (res.code != 0) { - throw Error(); - } - final data = res.data; + final data = await HardApi.createHardwareOrder(pa); + if (data == null) throw Error(); if (ObjectUtil.isEmpty(data)) throw Error(); - logger.i("|$_tag||有网络|创建api订单,下单成功res:|${res.toJson()}|"); + logger.i("|$_tag||有网络|创建api订单,下单成功res:|$data|"); sqlOrderDetail.status = OrderStatus.pay; sqlOrderDetail.serviceUniqueCode = data.toString(); } else { diff --git a/lib/common/widgets/order/select_pay_type_dialog.dart b/lib/common/widgets/order/select_pay_type_dialog.dart index 8a5e71a..f245f0b 100644 --- a/lib/common/widgets/order/select_pay_type_dialog.dart +++ b/lib/common/widgets/order/select_pay_type_dialog.dart @@ -198,11 +198,9 @@ class SelectPayTypeDialogController extends GetxController { "id": qrCode.userId, "type": appSetting.sysType.name, }; - final res = await HardApi.getUserInfoById(pa); - if (res.code != 0) { - throw Error(); - } - payUser.value = res.data; + final data = await HardApi.getUserInfoById(pa); + if (data != null) throw Error(); + payUser.value = data; if (payUser.value != null) { await SyncUserTool.storageUser(user: payUser.value!); } @@ -248,15 +246,15 @@ class SelectPayTypeDialogController extends GetxController { final isNetwork = AppNetworkTool.isAutoNetwork(); if (isNetwork) { final pa = {"card": card}; - final res = await HardApi.getUserByCard(pa); - if (res.code != 0 || res.data == null) { + final data = await HardApi.getUserByCard(pa); + if (data == null) { logger.e("|$_tag|饭卡识别,无效的饭卡cardId:|$card|"); isRecognition.value = false; app.serialCardManage.close(); Toast.error(msg: "查询不到此用户"); return; } - payUser.value = res.data; + payUser.value = data; if (payUser.value != null) { await SyncUserTool.storageUser(user: payUser.value!); } @@ -357,11 +355,9 @@ class SelectPayTypeDialogController extends GetxController { "id": event.userId, "type": appSetting.sysType.name, }; - final res = await HardApi.getUserInfoById(pa); - if (res.code != 0) { - throw Error(); - } - payUser.value = res.data; + final data = await HardApi.getUserInfoById(pa); + if (data == null) throw Error(); + payUser.value = data; logger.i("|_tag|人脸识别|有网络|,用户信息:|${payUser.toJson()}|"); if (payUser.value != null) { await SyncUserTool.storageUser(user: payUser.value!); diff --git a/lib/main.dart b/lib/main.dart index d01a630..ef0c21b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -16,9 +16,11 @@ void main() async { Future checkSubScreen() async { switch (window.defaultRouteName) { case "/": + final appTheme = Get.put(AppThemeControl()); runApp(MainApp()); final app = Get.put(AppControl()); await app.initAsync(); + await appTheme.initAsync(); break; case "subMain": await Future(() async { diff --git a/lib/pages/login/controller.dart b/lib/pages/login/controller.dart index e416b6c..f315620 100644 --- a/lib/pages/login/controller.dart +++ b/lib/pages/login/controller.dart @@ -47,6 +47,7 @@ class LoginController extends GetxController { ); } try { + await AppSettingTool.setUserSetting(UserSetting()); final data = await UserApi.login(pa); if (data == null) { if (visibleMsg) EasyLoading.dismiss(); @@ -68,10 +69,9 @@ class LoginController extends GetxController { Get.offAndToNamed(RouteNames.panel); _clearForm(); } catch (e) { - logger.d("|$_tag|登录错误error:|$e|"); + logger.e("|$_tag|登录错误error:|$e|"); EasyLoading.dismiss(); } - Get.offAllNamed(RouteNames.panel); } Future autoLogin() async { diff --git a/lib/pages/login/view.dart b/lib/pages/login/view.dart index 9e9c957..4e248d0 100644 --- a/lib/pages/login/view.dart +++ b/lib/pages/login/view.dart @@ -16,13 +16,19 @@ class LoginPage extends GetView { List widgets = [ SizedBox(height: 30.h), FTextField( - label: Text('用户名'), + label: Text( + '用户名', + style: theme.typography.base, + ), controller: controller.usernameC, hint: '请输入用户名', ), SizedBox(height: 30.h), FTextField.password( - label: Text('密码'), + label: Text( + '密码', + style: theme.typography.base, + ), controller: controller.passwordC, hint: '请输入密码', ), diff --git a/lib/pages/order_history/controller.dart b/lib/pages/order_history/controller.dart index ca1cdb5..025dede 100644 --- a/lib/pages/order_history/controller.dart +++ b/lib/pages/order_history/controller.dart @@ -195,9 +195,8 @@ class OrderHistoryController extends GetxController { try { final orderId = int.tryParse(v.serviceUniqueCode); final pa = {"orderId": orderId}; - final res = await HardApi.generateInvoice(pa); - if (res.code != 0) throw Error(); - final data = res.data as ServiceGenerateInvoice; + final data = await HardApi.generateInvoice(pa); + if (data == null) throw Error(); if (ObjectUtil.isEmpty(data.historyId) || ObjectUtil.isEmpty(data.pic)) { throw Error(); } diff --git a/lib/pages/panel/controller.dart b/lib/pages/panel/controller.dart index 214633d..69e465e 100644 --- a/lib/pages/panel/controller.dart +++ b/lib/pages/panel/controller.dart @@ -1,4 +1,6 @@ +import 'package:common_utils/common_utils.dart'; import 'package:get/get.dart'; + import 'package:pj_supermarket_cloud/common/index.dart'; class PanelController extends GetxController { @@ -35,27 +37,36 @@ class PanelController extends GetxController { _initData(); } - void doBtn(PanelType type) { + Future doBtn(PanelType type) async { switch (type) { case PanelType.supermarketOrder: + if (!await _checkIsBind()) return; Get.toNamed(RouteNames.supermarketProduct); break; case PanelType.canteenOrder: + if (!await _checkIsBind()) return; Get.toNamed(RouteNames.canteenProduct); break; case PanelType.takeFood: + if (!await _checkIsBind()) return; Get.toNamed(RouteNames.takeFood); break; case PanelType.orderHistory: + if (!await _checkIsBind()) return; Get.toNamed(RouteNames.orderHistory); break; case PanelType.setting: Get.toNamed(RouteNames.setting); break; case PanelType.cardActive: + if (!await _checkIsBind()) return; Get.toNamed(RouteNames.cardActive); break; case PanelType.logout: + final isNetwork = AppNetworkTool.isAutoNetwork(); + if (isNetwork) { + await AppSettingTool.setUserSetting(UserSetting()); + } Get.offAndToNamed(RouteNames.login); break; default: @@ -63,6 +74,16 @@ class PanelController extends GetxController { } } + Future _checkIsBind() async { + final sysSetting = await AppSettingTool.getSysSetting(); + final id = sysSetting.serviceMerchantId; + if (ObjectUtil.isEmpty(id)) { + Toast.base(msg: "请前往设置绑定设备"); + return false; + } + return true; + } + Future _updateMenus() async { final sysSetting = await AppSettingTool.getSysSetting(); final sysType = sysSetting.sysType; diff --git a/lib/pages/panel/view.dart b/lib/pages/panel/view.dart index 717c62d..c4b51be 100644 --- a/lib/pages/panel/view.dart +++ b/lib/pages/panel/view.dart @@ -35,13 +35,16 @@ class PanelPage extends GetView { .toList() .toColumn(), ), - ].toColumnSpace( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - space: 20.h, - ), - ).center(); + ] + .toColumnSpace( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + space: 20.h, + ) + .scrollable() + .center(), + ); } @override diff --git a/lib/pages/setting/controller.dart b/lib/pages/setting/controller.dart index af98dd7..2b14272 100644 --- a/lib/pages/setting/controller.dart +++ b/lib/pages/setting/controller.dart @@ -1,11 +1,25 @@ +import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:forui/forui.dart'; import 'package:get/get.dart'; import 'package:pj_supermarket_cloud/common/index.dart'; class SettingController extends GetxController { + static const String _tag = "设置 Controller"; + + final appC = Get.find(); + + Rx sysSetting = Rx(null); + + Rx userSetting = Rx(null); + + var globalFontSizeC = FRadioSelectGroupController( + value: SettingGlobalFontSize.xl3.code, + ); + _initData() { update(["setting"]); + getSetting(); } RxList menuList = [ @@ -43,7 +57,18 @@ class SettingController extends GetxController { Rx cuurentMenuType = SettingMenuType.baseInfo.obs; - void onTap() {} + @override + void onInit() async { + super.onInit(); + globalFontSizeC.addValueListener((v) { + final fontSizeType = SettingGlobalFontSize.values.fromCode( + v.first, + ); + if (fontSizeType == null) return; + final appTheme = Get.find(); + appTheme.setSizeScalar(fontSizeType); + }); + } @override void onReady() { @@ -51,6 +76,12 @@ class SettingController extends GetxController { _initData(); } + @override + void onClose() { + super.onClose(); + globalFontSizeC.dispose(); + } + void doMenu(SettingMenu v) { if (v.type == cuurentMenuType.value) { return; @@ -58,4 +89,108 @@ class SettingController extends GetxController { cuurentMenuType.value = v.type; menuList.refresh(); } + + // 同步设置 + void syncConfig() async { + final isNetwork = AppNetworkTool.isAutoNetworkMsg(); + if (!isNetwork) return; + EasyLoading.show( + status: '同步中...', + maskType: EasyLoadingMaskType.black, + ); + try { + await SyncConfigTool.autoSyncSysInfo(); + Toast.success(msg: "同步设备信息成功"); + } catch (e, stack) { + Toast.error(msg: "同步设备信息错误"); + logger.e("|$_tag|同步设备信息error:|$e|stack:|$stack|"); + EasyLoading.dismiss(); + } + } + + // 重新连接长链接 + void syncMq() async { + final isNetwork = AppNetworkTool.isAutoNetworkMsg(); + if (!isNetwork) return; + EasyLoading.show( + status: '同步中...', + maskType: EasyLoadingMaskType.black, + ); + try { + await AppMqTool.mqRefresh(); + Toast.success(msg: "同步长连接成功"); + } catch (e, stack) { + Toast.error(msg: "同步长连接错误"); + logger.e("|$_tag|同步长连接error:|$e|stack:|$stack|"); + EasyLoading.dismiss(); + } + } + + // 同步分类 + void syncClassify() async { + final isNetwork = AppNetworkTool.isAutoNetworkMsg(); + if (!isNetwork) return; + EasyLoading.show( + status: '同步中...', + maskType: EasyLoadingMaskType.black, + ); + try { + await SyncProductTool.syncClassify(); + Toast.success(msg: "同步分类成功"); + EasyLoading.dismiss(); + } catch (e, stack) { + Toast.error(msg: "同步分类错误"); + logger.e("|$_tag|同步分类error:|$e|stack:|$stack|"); + EasyLoading.dismiss(); + } + } + + // 同步商品 + void syncProduct() async { + final isNetwork = AppNetworkTool.isAutoNetworkMsg(); + if (!isNetwork) return; + EasyLoading.show( + status: '同步中...', + maskType: EasyLoadingMaskType.black, + ); + try { + await SyncProductTool.syncProduct(); + EasyLoading.dismiss(); + Toast.success(msg: "同步商品成功"); + EasyLoading.dismiss(); + } catch (e, stack) { + Toast.error(msg: "同步商品错误"); + logger.e("|$_tag|同步商品error:|$e|stack:|$stack|"); + EasyLoading.dismiss(); + } + } + + // 同步离线订单 + void syncOfflineOrder() async { + final isNetwork = AppNetworkTool.isAutoNetworkMsg(); + if (!isNetwork) return; + EasyLoading.show( + status: '同步中...', + maskType: EasyLoadingMaskType.black, + ); + try { + await SyncOrderTool.syncOfflineOrder(); + Toast.success(msg: "同步离线订单成功"); + EasyLoading.dismiss(); + } catch (e) { + Toast.error(msg: "同步离线订单错误"); + logger.e("|$_tag|同步离线订单error:|$e|"); + EasyLoading.dismiss(); + } + } + + Future getSetting() async { + sysSetting.value = await AppSettingTool.getSysSetting(); + userSetting.value = await AppSettingTool.getUserSetting(); + if (userSetting.value!.globalFontSize != null) { + globalFontSizeC = FRadioSelectGroupController( + value: SettingGlobalFontSize.xl3.code, + ); + } + } } diff --git a/lib/pages/setting/widgets/setting_baseInfo.dart b/lib/pages/setting/widgets/setting_baseInfo.dart index 80aae17..546588a 100644 --- a/lib/pages/setting/widgets/setting_baseInfo.dart +++ b/lib/pages/setting/widgets/setting_baseInfo.dart @@ -7,6 +7,8 @@ import 'package:get/get.dart'; import 'package:pj_supermarket_cloud/common/index.dart'; +import '../index.dart'; + Future _bindServiceDialog(BuildContext context, SysSetting sys) async { final theme = FTheme.of(context); TextEditingController uniqueCodeC = TextEditingController(); @@ -59,6 +61,8 @@ Future _bindServiceDialog(BuildContext context, SysSetting sys) async { final flag = await AppSettingTool.bindSys(serverId!); EasyLoading.dismiss(); if (flag) { + final settingC = Get.find(); + await settingC.getSetting(); // 连接mq await AppMqTool.mqRefresh(); Toast.success(msg: "绑定成功"); @@ -76,13 +80,12 @@ Future _bindServiceDialog(BuildContext context, SysSetting sys) async { } Widget settingBaseInfo(BuildContext context) { - return FutureBuilder( - future: AppSettingTool.getSysSetting(), - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const SizedBox.shrink(); - } - final sys = snapshot.data!; + final theme = FTheme.of(context); + return GetBuilder( + builder: (controller) { + return Obx(() { + final sys = controller.sysSetting.value; + if (sys == null) return const SizedBox.shrink(); return [ appDividerTitle(context, "基本信息"), FTile( @@ -128,13 +131,42 @@ Widget settingBaseInfo(BuildContext context) { onPress: () => KeywordTool.copy(sys.merchantDeptId), ), appDividerTitle(context, "主题样式"), - FTile( + FSelectMenuTile( + groupController: controller.globalFontSizeC, prefixIcon: appPrefixIcon(context, FAssets.icons.settings), suffixIcon: appSuffixIcon(context, FAssets.icons.audioLines), title: appPrefixTitle(context, "字体大小"), - details: appSuffixTitle(context, sys.merchantDeptId), - onPress: () => KeywordTool.copy(sys.merchantDeptId), + autoHide: true, + validator: (value) => value == null ? '请选择' : null, + menu: SettingGlobalFontSize.values.map((v) { + return FSelectTile( + title: Text( + v.title, + style: theme.typography.xl, + ), + value: v.code, + ); + }).toList(), + details: ListenableBuilder( + listenable: controller.globalFontSizeC, + builder: (context, _) { + final v = controller.globalFontSizeC.value.firstOrNull; + if (v == null) return const SizedBox(); + final fontSizeType = SettingGlobalFontSize.values.fromCode( + v, + ); + if (fontSizeType == null) return const SizedBox(); + return Text( + fontSizeType.title, + style: theme.typography.base.copyWith( + color: theme.colorScheme.primary, + ), + ); + }, + ), ), ].toColumnSpace(space: 20.h); }); + }, + ); } diff --git a/lib/pages/setting/widgets/setting_sync.dart b/lib/pages/setting/widgets/setting_sync.dart index f0dc783..bd99add 100644 --- a/lib/pages/setting/widgets/setting_sync.dart +++ b/lib/pages/setting/widgets/setting_sync.dart @@ -2,83 +2,95 @@ 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:get/get.dart'; import 'package:pj_supermarket_cloud/common/index.dart'; +import '../index.dart'; + Widget settingSync(BuildContext context) { String dateFormat(DateTime? dataTime) { if (dataTime == null) return ""; return DateUtil.formatDate(dataTime); } - return FutureBuilder( - future: AppSettingTool.getSysSetting(), - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const SizedBox.shrink(); - } - final sys = snapshot.data!; - String getSyncClassifyTime() { - if (sys.sysType == SysType.canteen) { - return dateFormat(sys.canteenClassifySyncTime); - } else if (sys.sysType == SysType.supermarket) { - return dateFormat(sys.supermarketClassifySyncTime); - } else { - return "未同步"; - } - } + return GetBuilder(builder: (controller) { + return Obx(() { + final sys = controller.sysSetting.value; + if (sys == null) return const SizedBox.shrink(); - String getSyncProductTime() { - if (sys.sysType == SysType.canteen) { - return dateFormat(sys.canteenProductSyncTime); - } else if (sys.sysType == SysType.supermarket) { - return dateFormat(sys.supermarketProductSyncTime); - } else { - return "未同步"; - } + String getSyncClassifyTime() { + if (sys.sysType == SysType.canteen) { + return dateFormat(sys.canteenClassifySyncTime); + } else if (sys.sysType == SysType.supermarket) { + return dateFormat(sys.supermarketClassifySyncTime); + } else { + return "未同步"; } + } - return [ - FTile( - prefixIcon: appPrefixIcon(context, FAssets.icons.settings), - suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw), - title: appPrefixTitle(context, "同步设备信息"), - details: appSuffixTitle( - context, - "最后同步时间:${dateFormat(sys.syncTime)}", - ), - onPress: () => KeywordTool.copy(dateFormat(sys.syncTime)), + String getSyncProductTime() { + if (sys.sysType == SysType.canteen) { + return dateFormat(sys.canteenProductSyncTime); + } else if (sys.sysType == SysType.supermarket) { + return dateFormat(sys.supermarketProductSyncTime); + } else { + return "未同步"; + } + } + + return [ + FTile( + prefixIcon: appPrefixIcon(context, FAssets.icons.settings), + suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw), + title: appPrefixTitle(context, "同步设备信息"), + details: appSuffixTitle( + context, + "最后同步时间:${dateFormat(sys.syncTime)}", ), - FTile( - prefixIcon: appPrefixIcon(context, FAssets.icons.settings), - suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw), - title: appPrefixTitle(context, "同步长链接"), - details: appSuffixTitle( - context, - "最后同步时间:${dateFormat(sys.mqSyncTime)}", - ), - onPress: () => KeywordTool.copy(dateFormat(sys.syncTime)), + onPress: () => controller.syncConfig(), + ), + FTile( + prefixIcon: appPrefixIcon(context, FAssets.icons.settings), + suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw), + title: appPrefixTitle(context, "同步长链接"), + details: appSuffixTitle( + context, + "最后同步时间:${dateFormat(sys.mqSyncTime)}", ), - FTile( - prefixIcon: appPrefixIcon(context, FAssets.icons.settings), - suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw), - title: appPrefixTitle(context, "同步分类"), - details: appSuffixTitle( - context, - "最后同步时间:${getSyncClassifyTime()}", - ), - onPress: () => KeywordTool.copy(dateFormat(sys.syncTime)), + onPress: () => controller.syncMq(), + ), + FTile( + prefixIcon: appPrefixIcon(context, FAssets.icons.settings), + suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw), + title: appPrefixTitle(context, "同步分类"), + details: appSuffixTitle( + context, + "最后同步时间:${getSyncClassifyTime()}", ), - FTile( - prefixIcon: appPrefixIcon(context, FAssets.icons.settings), - suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw), - title: appPrefixTitle(context, "同步商品"), - details: appSuffixTitle( - context, - "最后同步时间:${getSyncProductTime()}", - ), - onPress: () => KeywordTool.copy(dateFormat(sys.syncTime)), + onPress: () => controller.syncClassify(), + ), + FTile( + prefixIcon: appPrefixIcon(context, FAssets.icons.settings), + suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw), + title: appPrefixTitle(context, "同步商品"), + details: appSuffixTitle( + context, + "最后同步时间:${getSyncProductTime()}", ), - ].toColumnSpace(space: 20.h); - }); + onPress: () => controller.syncProduct(), + ), + FTile( + prefixIcon: appPrefixIcon(context, FAssets.icons.settings), + suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw), + title: appPrefixTitle(context, "同步离线订单"), + details: appSuffixTitle( + context, + "最后同步时间:${getSyncProductTime()}", + ), + onPress: () => controller.syncOfflineOrder(), + ), + ].toColumnSpace(space: 20.h); + }); + }); } diff --git a/lib/pages/take_food/controller.dart b/lib/pages/take_food/controller.dart index f2102f2..3896cc4 100644 --- a/lib/pages/take_food/controller.dart +++ b/lib/pages/take_food/controller.dart @@ -166,8 +166,8 @@ class TakeFoodController extends GetxController { status: '核销中...', maskType: EasyLoadingMaskType.black, ); - final res = await HardApi.cancelQrCode(pa); - if (res.code != 0) throw Error(); + final flag = await HardApi.cancelQrCode(pa); + if (flag == false) throw Error(); EasyLoading.dismiss(); Toast.error(msg: "核销成功"); _speeching("核销成功"); diff --git a/pubspec.lock b/pubspec.lock index fdf364c..bc0632a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -882,6 +882,54 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.0.4" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849" + url: "https://pub.flutter-io.cn" + source: hosted + version: "11.4.0" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc + url: "https://pub.flutter-io.cn" + source: hosted + version: "12.1.0" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: f84a188e79a35c687c132a0a0556c254747a08561e99ab933f12f6ca71ef3c98 + url: "https://pub.flutter-io.cn" + source: hosted + version: "9.4.6" + permission_handler_html: + dependency: transitive + description: + name: permission_handler_html + sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.1.3+5" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.3.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.2.1" petitparser: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 51ffed1..b2bd160 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,7 +31,8 @@ dependencies: # 分页 number_pagination: ^1.1.6 - + # 权限判断 + permission_handler: ^11.4.0 # 串口 flutter_libserialport: 0.5.0 # 状态管理、路由