import 'dart:async'; import 'package:amap_flutter_location/amap_location_option.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:lszlgl/base/base_lifecycle_state.dart'; import '../../drfit/database.dart'; import '../../drfit/model_factory.dart'; import '../../main.dart'; import '../../plugin/bluetooth_plugin.dart'; import '../../service/print_service.dart'; import '../../utils/location_utils.dart'; import '../home/home_page.dart'; import 'dart:ui' as ui; class PrintPageArgs { /// 二维码数据 Uint8List bytes; List textList; PrintPageArgs({required this.bytes, required this.textList}); @override String toString() { return {'bytes': bytes}.toString(); } } /// 电子签名 class PrintPage extends StatefulWidget { final PrintPageArgs args; const PrintPage({ super.key, required this.args, }); @override State createState() => _PrintPageState(); } class _PrintPageState extends BaseLifecycleState { late List serviceList; late List deviceList; late List deviceMacList; String scanDeviceState = ''; StreamSubscription? locationListener; StreamSubscription? onReceiveDataStreamListener; StreamSubscription? onDeviceStateStreamListener; String phoneAddress = ''; @override void initState() { super.initState(); serviceList = [ ServiceModel(name: '搜索', icon: imgBleSearch, onTap: () => startScan()), ServiceModel(name: '打印', icon: imgBlePrint, onTap: () => startPrint()), ]; deviceList = []; deviceMacList = []; PrintService.hasBluetoothConnectDevice().then((result) { if(result == false) { PrintService.connectedDeviceList = []; PrintService.connectedDeviceMacList = []; } }); getLocation(); } /// 去打印 Future startPrint() async { int targetWidth = 560; if(PrintService.connectedDeviceList.last.deviceName.contains("BTP-UP321")) { targetWidth = 500; } final codec = await ui.instantiateImageCodec( widget.args.bytes, targetHeight: 590, // 640 targetWidth: targetWidth, // 560 ); final smallImage = (await codec.getNextFrame()).image; ByteData? smallBytes = await smallImage.toByteData(format: ui.ImageByteFormat.png); Uint8List? smallUint8List = smallBytes?.buffer.asUint8List(); MyNavigator.showLoading(msg: '打印中...'); if(PrintService.connectedDeviceList.last.deviceName.contains("BTP")) { await PrintService.startBluetoothPrintBitMapAndText(smallUint8List!, widget.args.textList); } else { await PrintService.startBluetoothPrintBitMap(smallUint8List!); await PrintService.startBluetoothPrintText(widget.args.textList); } MyNavigator.dismiss(); MyNavigator.showToast('打印成功'); } /// 去搜索 Future startScan() async { setState(() { deviceList = []; deviceMacList = []; }); await PrintService.startBluetoothDiscovery(); } Future savaToSqlite(BlueDeviceInfo deviceInfo) async { DeviceInfoTableCompanion tableCompanion = await ModelFactory.convertToTSlideComp(deviceInfo.deviceMac, deviceInfo.deviceName, phoneAddress); return await database.deviceInfoTableDao.addOneDeviceComp(tableCompanion); } /// 去连接 Future startConnect(BlueDeviceInfo deviceInfo) async { if(deviceInfo.connectStateStr.contains('未配对')) { MyNavigator.showLoading(msg: '配对中...'); await PrintService.startBluetoothPair(deviceInfo); } else if(deviceInfo.connectStateStr.contains('已配对')) { MyNavigator.showLoading(msg: '连接中...'); int connectResult = await PrintService.startBluetoothConnect(deviceInfo); if(connectResult == 0) { // 连接成功 MyNavigator.dismiss(); MyNavigator.showToast('连接成功'); deviceInfo.connectSuccess(); //addOneSlideComp if(deviceMacList.contains(deviceInfo.deviceMac)) { setState(() { deviceMacList.removeWhere((element) => element == deviceInfo.deviceMac); deviceList.removeWhere((element) => element.deviceMac == deviceInfo.deviceMac); }); } setState(() { PrintService.connectedDeviceMacList.add(deviceInfo.deviceMac); PrintService.connectedDeviceList.add(deviceInfo); }); await savaToSqlite(deviceInfo); // 保存记录到数据库 database.savaBleDataToServer(); // 同步记录到服务器 } else { MyNavigator.dismiss(); MyNavigator.showToast('连接失败'); } } else if(deviceInfo.connectStateStr.contains('断开')) { int connectResult = await PrintService.endBluetoothConnect(deviceInfo); if(connectResult == 0) { // 断开成功 deviceInfo.disConnectSuccess(); if(PrintService.connectedDeviceMacList.contains(deviceInfo.deviceMac)) { setState(() { PrintService.connectedDeviceMacList.removeWhere((element) => element == deviceInfo.deviceMac); PrintService.connectedDeviceList.removeWhere((element) => element.deviceMac == deviceInfo.deviceMac); }); } setState(() { deviceMacList.add(deviceInfo.deviceMac); deviceList.add(deviceInfo); }); } } } void getLocation() async { bool granted = await LocationUtils.checkLocationAvailable(); if (!granted) { return; } LocationUtils.setLocationOption(AMapLocationOption(onceLocation: true)); LocationUtils.startLocation(); } void initLocation() { locationListener = LocationUtils.onLocationChanged().listen((value) async { phoneAddress = value['address'] as String; }); } @override void onInit() { onReceiveDataStreamListener = BluetoothPlugin.instance.onReceiveDataStream.listen((deviceInfo) { if(deviceInfo != null) { if(deviceMacList.contains(deviceInfo.deviceMac)) { setState(() { deviceMacList.removeWhere((element) => element == deviceInfo.deviceMac); deviceList.removeWhere((element) => element.deviceMac == deviceInfo.deviceMac); }); } setState(() { // 只显示支持的打印机 if(deviceInfo.deviceName.contains('BTP') || deviceInfo.deviceName.contains('B3S') || deviceInfo.deviceName.contains('A8')) { deviceMacList.add(deviceInfo.deviceMac); deviceList.add(deviceInfo); } }); } }); onDeviceStateStreamListener = BluetoothPlugin.instance.onDeviceStateStream.listen((deviceState) { if(deviceState == DeviceState.pairEnd) { MyNavigator.dismiss(); } setState(() { scanDeviceState = deviceState ?? ""; }); }); initLocation(); } @override void onDestroy() { LocationUtils.stopLocation(); LocationUtils.destroy(); locationListener?.cancel(); onDeviceStateStreamListener?.cancel(); onReceiveDataStreamListener?.cancel(); } @override Widget build(BuildContext context) { return myScaffold( child: Column( children: [ myAppBar(title: '打印二维码'), const SizedBox(height: 18), buildServiceItem(serviceList[0]), const Text('已连接打印机'), ...List.generate( PrintService.connectedDeviceList.length, (index) => buildDeviceItem(PrintService.connectedDeviceList[index]), ).toList(), const Text('可用打印机'), ...List.generate( deviceList.length, (index) => buildDeviceItem(deviceList[index]), ).toList(), Offstage( offstage: PrintService.connectedDeviceList.isEmpty, child: buildServiceItem(serviceList[1]), ) ], ), ); } Widget buildServiceItem(ServiceModel service) { return GestureDetector( onTap: service.onTap, child: Container( margin: const EdgeInsets.only(left: 12, right: 12, bottom: 22), padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 40), clipBehavior: Clip.hardEdge, decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(12)), boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), offset: const Offset(0, 5), blurRadius: 4)], image: const DecorationImage(image: AssetImage(imgHomeListBg), fit: BoxFit.fill), ), child: Row( children: [ Image.asset(service.icon, height: 64), const SizedBox(width: 12), Expanded( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( "${service.name}${(service.name.contains('搜索')&&scanDeviceState == DeviceState.scanStart) ? "中..." : ""}", textAlign: TextAlign.center, style: const TextStyle(color: Color(0xFF333333), fontSize: 20, fontWeight: FontWeight.w500), ), ], ), ), ], ), ), ); } Widget buildDeviceItem(BlueDeviceInfo deviceInfo) { return GestureDetector( onTap: () { // 连接 startConnect(deviceInfo); }, child: Container( margin: const EdgeInsets.only(left: 12, right: 12, bottom: 22), padding: const EdgeInsets.symmetric(vertical: 10), clipBehavior: Clip.hardEdge, decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(12)), boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), offset: const Offset(0, 5), blurRadius: 4)], image: const DecorationImage(image: AssetImage(imgHomeListBg), fit: BoxFit.fill), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text( deviceInfo.deviceName, textAlign: TextAlign.center, style: const TextStyle(color: Color(0xFF333333), fontSize: 15, fontWeight: FontWeight.w500), ), Text( deviceInfo.connectStateStr, textAlign: TextAlign.center, style: const TextStyle(color: Color(0xFF333333), fontSize: 15, fontWeight: FontWeight.w500), ), ], ), ), ); } }