From 93f9ec7cfda862d4b16f723c8700a48c025e0785 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Thu, 20 Mar 2025 14:32:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E8=BE=85=E5=8A=A9=E6=9D=A1=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../database/dao/supermarket_code_dao.dart | 37 +++++++++++++++++-- .../database/dao/supermarket_sku_dao.dart | 6 ++- lib/common/services/database/database.g.dart | 18 +++++++-- .../utils/manage/barcode_scan_manage.dart | 32 +++++++++++----- lib/common/utils/manage/print_manage.dart | 22 ++++++++--- lib/common/utils/sync/sync_print_tool.dart | 35 ++++++++++-------- .../widgets/order/mixin/order_mixin.dart | 18 +++++---- lib/pages/canteen_product/controller.dart | 1 + .../setting/widgets/setting_product.dart | 2 +- lib/pages/supermarket_order/controller.dart | 11 ++++-- 10 files changed, 130 insertions(+), 52 deletions(-) diff --git a/lib/common/services/database/dao/supermarket_code_dao.dart b/lib/common/services/database/dao/supermarket_code_dao.dart index 3aa8437..803c1ef 100644 --- a/lib/common/services/database/dao/supermarket_code_dao.dart +++ b/lib/common/services/database/dao/supermarket_code_dao.dart @@ -31,8 +31,37 @@ abstract class SupermarketCodeDao { @insert Future batchSave(List changeList); - // @Query(''' - // SELECT * FROM supermarket_code LIMIT 1 - // ''') - // Future getByBarCode(String barCode); + @Query(''' + SELECT + supermarket_sku.id, + supermarket_sku.serviceUniqueCode, + supermarket_sku.spuId, + supermarket_spu.productCode, + supermarket_spu.classifyServiceUniqueCode, + supermarket_spu.productName, + supermarket_spu.picUrl, + supermarket_spu.productNature, + supermarket_spu.salesCount, + supermarket_spu.stock, + supermarket_spu.sort, + supermarket_spu.createTime, + supermarket_spu.updateTime, + supermarket_spu.delFlag, + supermarket_sku.barCode, + supermarket_sku.promotionPrice, + supermarket_sku.purchasePrice, + supermarket_sku.retailPrice, + supermarket_sku.spec, + supermarket_sku.packageNum, + supermarket_sku.unit, + supermarket_sku.packageNum + FROM supermarket_code + INNER JOIN supermarket_spu ON supermarket_code.spuId = supermarket_spu.serviceUniqueCode AND supermarket_spu.delFlag = 0 + INNER JOIN supermarket_sku ON supermarket_spu.serviceUniqueCode = supermarket_sku.spuId + WHERE + 1 = 1 + AND (:barCode = '-1' OR supermarket_code.barCode = :barCode) + LIMIT 1 + ''') + Future getByBarCode(String barCode); } diff --git a/lib/common/services/database/dao/supermarket_sku_dao.dart b/lib/common/services/database/dao/supermarket_sku_dao.dart index be7eba8..82f1c36 100644 --- a/lib/common/services/database/dao/supermarket_sku_dao.dart +++ b/lib/common/services/database/dao/supermarket_sku_dao.dart @@ -34,8 +34,12 @@ abstract class SupermarketSkuDao { @Query(""" SELECT DISTINCT COUNT(0) FROM supermarket_sku INNER JOIN supermarket_spu ON supermarket_sku.spuId = supermarket_spu.serviceUniqueCode AND supermarket_spu.delFlag = 0 + WHERE + 1 = 1 + AND (:barCode = '-1' OR supermarket_sku.barCode LIKE '%' || :barCode || '%') + AND (:classifyServiceUniqueCode = '-1' OR supermarket_spu.classifyServiceUniqueCode = :classifyServiceUniqueCode) """) - Future getCount(); + Future getCount(String barCode, String classifyServiceUniqueCode); @Query(''' SELECT diff --git a/lib/common/services/database/database.g.dart b/lib/common/services/database/database.g.dart index 3d57963..e642f3e 100644 --- a/lib/common/services/database/database.g.dart +++ b/lib/common/services/database/database.g.dart @@ -673,10 +673,14 @@ class _$SupermarketSkuDao extends SupermarketSkuDao { } @override - Future getCount() async { + Future getCount( + String barCode, + String classifyServiceUniqueCode, + ) async { return _queryAdapter.query( - 'SELECT DISTINCT COUNT(0) FROM supermarket_sku INNER JOIN supermarket_spu ON supermarket_sku.spuId = supermarket_spu.serviceUniqueCode AND supermarket_spu.delFlag = 0', - mapper: (Map row) => row.values.first as int); + 'SELECT DISTINCT COUNT(0) FROM supermarket_sku INNER JOIN supermarket_spu ON supermarket_sku.spuId = supermarket_spu.serviceUniqueCode AND supermarket_spu.delFlag = 0 WHERE 1 = 1 AND (?1 = \'-1\' OR supermarket_sku.barCode LIKE \'%\' || ?1 || \'%\') AND (?2 = \'-1\' OR supermarket_spu.classifyServiceUniqueCode = ?2)', + mapper: (Map row) => row.values.first as int, + arguments: [barCode, classifyServiceUniqueCode]); } @override @@ -861,6 +865,14 @@ class _$SupermarketCodeDao extends SupermarketCodeDao { await _queryAdapter.queryNoReturn('DELETE FROM supermarket_code'); } + @override + Future getByBarCode(String barCode) async { + return _queryAdapter.query( + 'SELECT supermarket_sku.id, supermarket_sku.serviceUniqueCode, supermarket_sku.spuId, supermarket_spu.productCode, supermarket_spu.classifyServiceUniqueCode, supermarket_spu.productName, supermarket_spu.picUrl, supermarket_spu.productNature, supermarket_spu.salesCount, supermarket_spu.stock, supermarket_spu.sort, supermarket_spu.createTime, supermarket_spu.updateTime, supermarket_spu.delFlag, supermarket_sku.barCode, supermarket_sku.promotionPrice, supermarket_sku.purchasePrice, supermarket_sku.retailPrice, supermarket_sku.spec, supermarket_sku.packageNum, supermarket_sku.unit, supermarket_sku.packageNum FROM supermarket_code INNER JOIN supermarket_spu ON supermarket_code.spuId = supermarket_spu.serviceUniqueCode AND supermarket_spu.delFlag = 0 INNER JOIN supermarket_sku ON supermarket_spu.serviceUniqueCode = supermarket_sku.spuId WHERE 1 = 1 AND (?1 = \'-1\' OR supermarket_code.barCode = ?1) LIMIT 1', + mapper: (Map row) => SupermarketSpuEntity(id: row['id'] as int?, serviceUniqueCode: row['serviceUniqueCode'] as String, classifyServiceUniqueCode: row['classifyServiceUniqueCode'] as String, productCode: row['productCode'] as String, productName: row['productName'] as String, productNature: _supermarketNatureConverter.decode(row['productNature'] as String), barCode: row['barCode'] as String?, packageNum: row['packageNum'] as int, unit: row['unit'] as String, spec: row['spec'] as String, picUrl: row['picUrl'] as String?, stock: row['stock'] as double?, salesCount: row['salesCount'] as double?, purchasePrice: row['purchasePrice'] as int, retailPrice: row['retailPrice'] as int, promotionPrice: row['promotionPrice'] as int, sort: row['sort'] as int, createTime: _dateTimeConverter.decode(row['createTime'] as String), updateTime: _dateTimeConverter.decode(row['updateTime'] as String), delFlag: _boolConverter.decode(row['delFlag'] as int)), + arguments: [barCode]); + } + @override Future batchSave(List changeList) async { await _supermarketCodeEntityInsertionAdapter.insertList( diff --git a/lib/common/utils/manage/barcode_scan_manage.dart b/lib/common/utils/manage/barcode_scan_manage.dart index f0f5277..172645e 100644 --- a/lib/common/utils/manage/barcode_scan_manage.dart +++ b/lib/common/utils/manage/barcode_scan_manage.dart @@ -21,17 +21,29 @@ class BarcodeScanManage { Timer? _timer; // 二维码扫码结果 - final _qrcodeScanController = StreamController.broadcast(); - Stream get qrcodeScanStream => _qrcodeScanController.stream; + StreamController? _qrcodeScanController; + Stream get qrcodeScanStream { + _qrcodeScanController ??= StreamController.broadcast(); + return _qrcodeScanController!.stream; + } // 扫码枪扫码结果 - final _gunScanController = StreamController.broadcast(); - Stream get gunScanStream => _gunScanController.stream; + StreamController? _gunScanController; + Stream get gunScanStream { + _gunScanController ??= StreamController.broadcast(); + return _gunScanController!.stream; + } // 开始监听USB读头输入 void startListening() { if (_isListening) return; _isListening = true; + if (_qrcodeScanController?.isClosed ?? true) { + _qrcodeScanController = StreamController.broadcast(); + } + if (_gunScanController?.isClosed ?? true) { + _gunScanController = StreamController.broadcast(); + } // 确保没有焦点的控件 FocusManager.instance.primaryFocus?.unfocus(); HardwareKeyboard.instance.addHandler(_handleKeyEvent); @@ -59,9 +71,9 @@ class BarcodeScanManage { final result = _buffer.toString(); logger.i("|$_tag|扫码结果: $result"); if (result.length >= 100) { - _qrcodeScanController.add(result); + _qrcodeScanController?.add(result); } else { - _gunScanController.add(result); + _gunScanController?.add(result); } _buffer.clear(); } @@ -190,15 +202,15 @@ class BarcodeScanManage { // 释放资源 void dispose() { stopListening(); - _qrcodeScanController.close(); - _gunScanController.close(); + _qrcodeScanController?.close(); + _gunScanController?.close(); } void disposeQrCodeScan() { - _qrcodeScanController.close(); + _qrcodeScanController?.close(); } void disposeGunScan() { - _gunScanController.close(); + _gunScanController?.close(); } } diff --git a/lib/common/utils/manage/print_manage.dart b/lib/common/utils/manage/print_manage.dart index 2289a40..02ca50e 100644 --- a/lib/common/utils/manage/print_manage.dart +++ b/lib/common/utils/manage/print_manage.dart @@ -12,6 +12,12 @@ class PrintManage extends BaseFacilityManage { int paperSizeWidthMM = PaperSizeWidth.mm80; int maxPerLine = PaperSizeMaxPerLine.mm80; + static const List _printVendorIds = [ + "19267", + "4070", + "10473", + ]; + @override String setName() => UsbFacilityNames.print.title; @@ -20,10 +26,14 @@ class PrintManage extends BaseFacilityManage { final check = await super.open(); if (!check) return false; final usbPrinter = await USBPrinterManager.discover(); - final sysSetting = await AppSettingTool.getSysSetting(); - final sysType = sysSetting.sysType; - final vendorId = sysType == SysType.CANTEEN ? 19267 : 4070; - final target = usbPrinter.firstWhereOrNull((v) => v.vendorId == vendorId); + USBPrinter? target = usbPrinter.firstWhereOrNull((v) { + return _printVendorIds.contains(v.vendorId ?? "-1"); + }); + if (ObjectUtil.isEmpty(target)) { + if (usbPrinter.length == 1) { + target = usbPrinter[0]; + } + } if (ObjectUtil.isEmpty(target)) return false; profile = await CapabilityProfile.load(); manager = USBPrinterManager(target!); @@ -50,9 +60,9 @@ class PrintManage extends BaseFacilityManage { profile!, ); List bytes = []; - bytes += generator.feed(2); + bytes += generator.feed(1); bytes += generator.image(image!); - bytes += generator.feed(2); + bytes += generator.feed(1); bytes += generator.cut(); try { await manager!.writeBytes(bytes); diff --git a/lib/common/utils/sync/sync_print_tool.dart b/lib/common/utils/sync/sync_print_tool.dart index f88ac17..e076829 100644 --- a/lib/common/utils/sync/sync_print_tool.dart +++ b/lib/common/utils/sync/sync_print_tool.dart @@ -74,26 +74,29 @@ abstract class SyncPrintTool { } final app = Get.find(); final printHistoryDao = app.dataBase.getPrintHistoryDao; - try { - final list = await printHistoryDao.getAll(PrintStatus.SUCCESS.name); - if (ObjectUtil.isEmptyList(list)) { - _isSync = false; - return; - } - for (final v in list) { - final printPa = { - "orderId": v.serviceOrderId, - "historyId": v.servicePrintId, - }; - await HardApi.printInvoice(printPa); + final list = await printHistoryDao.getAll(PrintStatus.SUCCESS.name); + if (ObjectUtil.isEmptyList(list)) { + _isSync = false; + return; + } + for (final v in list) { + final printPa = { + "orderId": v.serviceOrderId, + "historyId": v.servicePrintId, + }; + try { + final flag = await HardApi.printInvoice(printPa); + if (!flag) Exception("|$_tag|同步失败api错误params|${v.toJson()}|"); v.status = PrintStatus.SYNC; v.syncTime = DateTime.now(); await printHistoryDao.edit(v); + } catch (e) { + logger.e("|$_tag|检查同步,打印错误,error:|$e|"); + v.status = PrintStatus.ERROR; + await printHistoryDao.edit(v); + } finally { + _isSync = false; } - } catch (e) { - logger.e("|$_tag|检查打印,打印错误,error:|$e|"); - } finally { - _isSync = false; } } diff --git a/lib/common/widgets/order/mixin/order_mixin.dart b/lib/common/widgets/order/mixin/order_mixin.dart index c2c56ae..092ce00 100644 --- a/lib/common/widgets/order/mixin/order_mixin.dart +++ b/lib/common/widgets/order/mixin/order_mixin.dart @@ -70,7 +70,7 @@ mixin OrderMixin { RxInt currentPage = RxInt(1); RxInt totalPage = RxInt(0); - RxInt pageSize = RxInt(10); + RxInt pageSize = RxInt(15); Future? putOffSendSubScreenDelayed; @@ -92,8 +92,7 @@ mixin OrderMixin { ); currentTabIndex = i; if (i <= classifyList.length - 1) { - final current = classifyList[i]; - await getProduct(classifyCode: current.serviceUniqueCode); + await getProduct(); } EasyLoading.dismiss(); } @@ -122,13 +121,18 @@ mixin OrderMixin { } // 获取商品 - Future getProduct({String classifyCode = "-1"}) async { + Future getProduct() async { + String classifyCode = classifyList[currentTabIndex].serviceUniqueCode; if (_sysType == SysType.SUPERMARKET) { final supermarketSkuDao = appC.dataBase.getSupermarketSkuDao; - final total = await supermarketSkuDao.getCount(); + String currentBarCode = ObjectUtil.isEmpty(barCode) ? "-1" : barCode; + final total = await supermarketSkuDao.getCount( + currentBarCode, + classifyCode, + ); totalPage.value = total ?? 0; final list = await supermarketSkuDao.getAllPage( - ObjectUtil.isEmpty(barCode) ? "-1" : barCode, + currentBarCode, classifyCode, pageSize.value, (currentPage.value - 1) * pageSize.value, @@ -331,10 +335,8 @@ mixin OrderMixin { final price = AppriceTool.fenToYuan(sqlOrderDetail.payPrice); await TtsManage.speak("购买成功总金额$price元"); } - EasyLoading.dismiss(); Toast.success(msg: "购买成功"); } catch (e, stack) { - EasyLoading.dismiss(); Toast.error(msg: "结算订单失败"); logger.e("|$_tag|创建api订单,下单失败error:|$e|stack:|$stack|"); } diff --git a/lib/pages/canteen_product/controller.dart b/lib/pages/canteen_product/controller.dart index 49b8291..01b646e 100644 --- a/lib/pages/canteen_product/controller.dart +++ b/lib/pages/canteen_product/controller.dart @@ -194,6 +194,7 @@ class CanteenProductController extends GetxController with OrderMixin { await createApiOrder(); _clearShopCard(); putOffSendSubScreen(); + EasyLoading.dismiss(); }; // |支付方式|点击|取消| payTypeSelect.onCancel = () {}; diff --git a/lib/pages/setting/widgets/setting_product.dart b/lib/pages/setting/widgets/setting_product.dart index 492a168..b28e9b8 100644 --- a/lib/pages/setting/widgets/setting_product.dart +++ b/lib/pages/setting/widgets/setting_product.dart @@ -100,7 +100,7 @@ class ProductManageController extends GetxController { if (sysType == SysType.SUPERMARKET) { // 超市 final supermarketSpuDao = appC.dataBase.getSupermarketSkuDao; - final findCount = await supermarketSpuDao.getCount(); + final findCount = await supermarketSpuDao.getCount("-1", "-1"); totalPage.value = findCount ?? 0; final list = await supermarketSpuDao.getAllPage( "-1", diff --git a/lib/pages/supermarket_order/controller.dart b/lib/pages/supermarket_order/controller.dart index 74757ee..26859c0 100644 --- a/lib/pages/supermarket_order/controller.dart +++ b/lib/pages/supermarket_order/controller.dart @@ -101,7 +101,7 @@ class SupermarketOrderController extends GetxController with OrderMixin { barCode = codeText; } // 收起键盘 - FocusScope.of(Get.context!).unfocus(); + FocusManager.instance.primaryFocus?.unfocus(); await getProduct(); EasyLoading.dismiss(); } @@ -116,7 +116,7 @@ class SupermarketOrderController extends GetxController with OrderMixin { selfCodeC.clear(); barCode = ""; // 收起键盘 - FocusScope.of(Get.context!).unfocus(); + FocusManager.instance.primaryFocus?.unfocus(); await getProduct(); EasyLoading.dismiss(); } @@ -247,6 +247,7 @@ class SupermarketOrderController extends GetxController with OrderMixin { await createApiOrder(); _clearShopCard(); putOffSendSubScreen(); + EasyLoading.dismiss(); }; // |支付方式|点击|取消| payTypeSelect.onCancel = () {}; @@ -302,7 +303,11 @@ class SupermarketOrderController extends GetxController with OrderMixin { if (event.length >= 30) return; // 根据条码查询商品 final skuDao = appC.dataBase.getSupermarketSkuDao; - final scanProduct = await skuDao.getByBarCode(event); + SupermarketSpuEntity? scanProduct = await skuDao.getByBarCode(event); + if (scanProduct == null) { + final codeDao = appC.dataBase.getSupermarketCodeDao; + scanProduct = await codeDao.getByBarCode(event); + } if (scanProduct == null) { TtsManage.speak("扫码商品未知"); return;