feat:辅助条码

This commit is contained in:
dzc committed 2025-03-20 14:32:07 +08:00
1 parent 6b3ee0e8d1
commit 93f9ec7cfd
10 files changed
+130 -52

No files matched your search

@@ -31,8 +31,37 @@ abstract class SupermarketCodeDao {
@insert
Future<void> batchSave(List<SupermarketCodeEntity> changeList);
// @Query('''
// SELECT * FROM supermarket_code LIMIT 1
// ''')
// Future<SupermarketCodeEntity?> 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<SupermarketSpuEntity?> getByBarCode(String barCode);
}
@@ -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<int?> getCount();
Future<int?> getCount(String barCode, String classifyServiceUniqueCode);
@Query('''
SELECT
+15 -3
View File
@@ -673,10 +673,14 @@ class _$SupermarketSkuDao extends SupermarketSkuDao {
}
@override
Future<int?> getCount() async {
Future<int?> 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<String, Object?> 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<String, Object?> 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<SupermarketSpuEntity?> 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<String, Object?> 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<void> batchSave(List<SupermarketCodeEntity> changeList) async {
await _supermarketCodeEntityInsertionAdapter.insertList(
@@ -21,17 +21,29 @@ class BarcodeScanManage {
Timer? _timer;
// 二维码扫码结果
final _qrcodeScanController = StreamController<String>.broadcast();
Stream<String> get qrcodeScanStream => _qrcodeScanController.stream;
StreamController<String>? _qrcodeScanController;
Stream<String> get qrcodeScanStream {
_qrcodeScanController ??= StreamController<String>.broadcast();
return _qrcodeScanController!.stream;
}
// 扫码枪扫码结果
final _gunScanController = StreamController<String>.broadcast();
Stream<String> get gunScanStream => _gunScanController.stream;
StreamController<String>? _gunScanController;
Stream<String> get gunScanStream {
_gunScanController ??= StreamController<String>.broadcast();
return _gunScanController!.stream;
}
// 开始监听USB读头输入
void startListening() {
if (_isListening) return;
_isListening = true;
if (_qrcodeScanController?.isClosed ?? true) {
_qrcodeScanController = StreamController<String>.broadcast();
}
if (_gunScanController?.isClosed ?? true) {
_gunScanController = StreamController<String>.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();
}
}
+16 -6
View File
@@ -12,6 +12,12 @@ class PrintManage extends BaseFacilityManage {
int paperSizeWidthMM = PaperSizeWidth.mm80;
int maxPerLine = PaperSizeMaxPerLine.mm80;
static const List<String> _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<int> 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);
+19 -16
View File
@@ -74,26 +74,29 @@ abstract class SyncPrintTool {
}
final app = Get.find<AppControl>();
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;
}
}
@@ -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<void> getProduct({String classifyCode = "-1"}) async {
Future<void> 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|");
}
@@ -194,6 +194,7 @@ class CanteenProductController extends GetxController with OrderMixin {
await createApiOrder();
_clearShopCard();
putOffSendSubScreen();
EasyLoading.dismiss();
};
// |支付方式|点击|取消|
payTypeSelect.onCancel = () {};
@@ -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",
+8 -3
View File
@@ -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;