You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
534 lines
14 KiB
534 lines
14 KiB
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:typed_data';
|
|
import 'dart:ui';
|
|
|
|
import 'package:barcode_widget/barcode_widget.dart';
|
|
import 'package:dj_printer/src/status_enum.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_image_compress/flutter_image_compress.dart';
|
|
import 'package:widget_to_image/widget_to_image.dart';
|
|
|
|
class DjPrinter {
|
|
static late final DjPrinter _instance = DjPrinter._();
|
|
|
|
DjPrinter._();
|
|
|
|
factory DjPrinter() => _instance;
|
|
static const MethodChannel _channel = MethodChannel('dj_printer');
|
|
static const EventChannel _deviceChannel =
|
|
EventChannel("com.discovery.devices");
|
|
StreamSubscription? _discoveryStream;
|
|
|
|
StreamSubscription addDiscoveryListen(
|
|
{required void Function(dynamic data) onReceive,
|
|
void Function()? onStart,
|
|
void Function()? onFinish}) {
|
|
if (_discoveryStream == null) {
|
|
return _deviceChannel.receiveBroadcastStream().listen((data) {
|
|
if (data == "start" && onStart != null) {
|
|
onStart();
|
|
} else if (data == "finish" && onFinish != null) {
|
|
onFinish();
|
|
} else {
|
|
onReceive(data);
|
|
}
|
|
});
|
|
} else {
|
|
return _discoveryStream!;
|
|
}
|
|
}
|
|
|
|
void cancelDiscovery() {
|
|
_discoveryStream?.cancel();
|
|
_discoveryStream = null;
|
|
print('结束搜索');
|
|
disposeDiscovery();
|
|
}
|
|
|
|
static const EventChannel _connectChannel = EventChannel("com.connect");
|
|
StreamSubscription? _connectStream;
|
|
|
|
StreamSubscription addConnectListen({required void Function() onConnect,
|
|
required void Function() onDisconnect}) {
|
|
if (_connectStream == null) {
|
|
return _connectChannel.receiveBroadcastStream().listen((data) {
|
|
if (data == 'connected') {
|
|
onConnect();
|
|
} else if (data == 'disconnected') {
|
|
onDisconnect();
|
|
}
|
|
});
|
|
} else {
|
|
return _connectStream!;
|
|
}
|
|
}
|
|
|
|
void cancelConnect() {
|
|
if (_connectStream != null) {
|
|
_connectStream!.cancel();
|
|
_connectStream = null;
|
|
}
|
|
}
|
|
|
|
void get startSearch {
|
|
final res = _channel.invokeMethod('startSearch');
|
|
}
|
|
|
|
bool _hasInit = false;
|
|
|
|
bool get hasInit => _hasInit;
|
|
|
|
Future<bool?> connect(String address) async {
|
|
final res = await _channel.invokeMethod('connect', {'address': address});
|
|
return res;
|
|
}
|
|
|
|
void disposeDiscovery() {
|
|
print('disposeDiscovery');
|
|
final res = _channel.invokeMethod('disposeDiscovery');
|
|
}
|
|
|
|
Future<bool?> disposeConnect() async {
|
|
final res = await _channel.invokeMethod('disposeConnect');
|
|
return res;
|
|
}
|
|
|
|
Future<bool?> init() async {
|
|
final res = await _channel.invokeMethod('init');
|
|
_hasInit = true;
|
|
return res;
|
|
}
|
|
|
|
//0 normal
|
|
//1 busy
|
|
//2 paper empty
|
|
//4 cover open
|
|
//8 battery low
|
|
Future<PRINT_STATUS?> getStatus() async {
|
|
final res = await _channel.invokeMethod('getStatus');
|
|
switch (res) {
|
|
case 0:
|
|
return PRINT_STATUS.normal;
|
|
case 1:
|
|
return PRINT_STATUS.busy;
|
|
case 2:
|
|
return PRINT_STATUS.paperEmpty;
|
|
case 4:
|
|
return PRINT_STATUS.coverOpen;
|
|
case 8:
|
|
return PRINT_STATUS.batteryLow;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
Future<bool?> printNewAScode({required String code,
|
|
required String barCode,
|
|
required String channel,
|
|
required String country,
|
|
required String num,
|
|
required String sum,
|
|
required int offset,
|
|
required bool hasPlan}) async {
|
|
final res = await _channel.invokeMethod('newPrint', {
|
|
'code': code,
|
|
'barCode':barCode,
|
|
'channel': channel,
|
|
'country': country,
|
|
'num': num,
|
|
'sum': sum,
|
|
'offset': offset,
|
|
'hasPlan': hasPlan,
|
|
});
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<bool?> printAScode({required String code,
|
|
required String channel,
|
|
required String country,
|
|
required String countStr,
|
|
required int offset,
|
|
required bool hasPlan}) async {
|
|
final res = await _channel.invokeMethod('print', {
|
|
'code': code,
|
|
'channel': channel,
|
|
'country': country,
|
|
'countStr': countStr,
|
|
'offset': offset,
|
|
'hasPlan': hasPlan,
|
|
});
|
|
return res;
|
|
}
|
|
|
|
Future<bool?> printAScodeByImg({required String code,
|
|
required String channel,
|
|
required String country,
|
|
required String num,
|
|
required String sum,
|
|
required String countStr,
|
|
required int offset,
|
|
required bool hasPlan}) async {
|
|
|
|
|
|
ByteData bDCode = await WidgetToImage.widgetToImage( Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child:_getCode(code),
|
|
),
|
|
),pixelRatio: window.devicePixelRatio,size: const Size(25,240));
|
|
|
|
Uint8List uint8ListCode = await testComporessList(bDCode);
|
|
|
|
|
|
ByteData bDChannel = await WidgetToImage.widgetToImage( Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child:_getChannel(channel)
|
|
),
|
|
),pixelRatio: window.devicePixelRatio,size: const Size(40,140));
|
|
|
|
Uint8List uint8ListChannel = await testComporessList(bDChannel);
|
|
|
|
|
|
ByteData bDNum = await WidgetToImage.widgetToImage( Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child:_getNum(num)
|
|
),
|
|
),pixelRatio: window.devicePixelRatio,size: Size(20,(20*num.length).toDouble()));
|
|
|
|
Uint8List uint8ListNum = await testComporessList(bDNum);
|
|
|
|
|
|
ByteData bDSum = await WidgetToImage.widgetToImage( Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child:_getNum(sum)
|
|
),
|
|
),pixelRatio: window.devicePixelRatio,size: Size(20,(20*sum.length).toDouble()));
|
|
|
|
Uint8List uint8ListSum= await testComporessList(bDSum);
|
|
|
|
|
|
Uint8List uint8ListCountry;
|
|
if(hasPlan){
|
|
ByteData bDCountry = await WidgetToImage.widgetToImage( Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child:_getCountry(country)
|
|
),
|
|
),pixelRatio: window.devicePixelRatio,size: Size(country.length>4?44: 22,70));
|
|
|
|
uint8ListCountry = await testComporessList(bDCountry);
|
|
}else{
|
|
ByteData bDCountry = await WidgetToImage.widgetToImage( Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child:_getNoplan()
|
|
),
|
|
),pixelRatio: window.devicePixelRatio,size: const Size(22,100));
|
|
|
|
uint8ListCountry = await testComporessList(bDCountry);
|
|
}
|
|
|
|
|
|
|
|
ByteData bDBarCode = await WidgetToImage.widgetToImage( Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child:_getBarCode(code)
|
|
),
|
|
),pixelRatio: window.devicePixelRatio,size: const Size(60,120));
|
|
|
|
Uint8List uint8ListBarCode = await testComporessList(bDBarCode);
|
|
|
|
final res = await _channel.invokeMethod('print', {
|
|
'code': code,
|
|
'channel': channel,
|
|
'country': country,
|
|
'countStr': countStr,
|
|
'offset': offset,
|
|
'hasPlan': hasPlan,
|
|
'byteCode': uint8ListCode,
|
|
'bytesChannel':uint8ListChannel,
|
|
'bytesCountry':uint8ListCountry,
|
|
'bytesBarCode':uint8ListBarCode,
|
|
'bytesSum':uint8ListSum,
|
|
'bytesNum':uint8ListNum,
|
|
});
|
|
return res;
|
|
}
|
|
|
|
Future<Uint8List> testComporessList(ByteData data) async {
|
|
|
|
final buffer = data.buffer;
|
|
|
|
var result = await FlutterImageCompress.compressWithList(
|
|
buffer.asUint8List(),
|
|
quality: 1,
|
|
|
|
);
|
|
print(buffer.asUint8List().length);
|
|
print(result.length);
|
|
return result;
|
|
}
|
|
|
|
|
|
Widget _getCountry(String country){
|
|
return RotatedBox(
|
|
quarterTurns: 1,
|
|
child: Text(
|
|
country,
|
|
maxLines: 2,
|
|
textAlign: TextAlign.center,
|
|
style: const TextStyle(
|
|
color: Colors.black,
|
|
fontSize: 17,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
|
|
Widget _getNoplan(){
|
|
return RotatedBox(
|
|
quarterTurns: 1,
|
|
child: Text(
|
|
'未 建 计 划',
|
|
textAlign: TextAlign.center,
|
|
style: const TextStyle(
|
|
color: Colors.black,
|
|
fontSize: 17,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
|
|
Widget _getNum(String num){
|
|
return RotatedBox(
|
|
quarterTurns: 1,
|
|
child: Text(
|
|
num,
|
|
textAlign: TextAlign.center,
|
|
style: const TextStyle(
|
|
color: Colors.black,
|
|
fontSize: 17,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
|
|
|
|
Widget _getChannel(String channel){
|
|
return RotatedBox(
|
|
quarterTurns: 1,
|
|
child: Text(
|
|
channel,
|
|
maxLines: 2,
|
|
style: const TextStyle(
|
|
color: Colors.black,
|
|
fontSize: 13,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget _getCode(String code){
|
|
return RotatedBox(
|
|
quarterTurns: 1,
|
|
child: Text(
|
|
code,
|
|
style: const TextStyle(
|
|
color: Colors.black,
|
|
fontSize: 20,
|
|
fontWeight: FontWeight.bold),
|
|
),
|
|
);
|
|
}
|
|
|
|
|
|
Widget _getBarCode(String code){
|
|
return RotatedBox(
|
|
quarterTurns: 1,
|
|
child: BarcodeWidget(
|
|
barcode: Barcode.code128(),
|
|
data: code,
|
|
style: TextStyle(
|
|
fontSize: 10
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _getCard(String code, String channel, String country, String countStr,
|
|
int offset, bool hasPlan) {
|
|
return RotatedBox(
|
|
quarterTurns: 3,
|
|
child: Text(
|
|
code,
|
|
style: const TextStyle(
|
|
color: Colors.black,
|
|
fontSize: 15,
|
|
),
|
|
),
|
|
);
|
|
|
|
|
|
Container(
|
|
//margin: EdgeInsets.all(5),
|
|
width: 700 / 3.7,
|
|
height: 950 / 3.7,
|
|
// decoration: BoxDecoration(
|
|
// color: Colors.white,
|
|
// border: Border.all(color: Colors.black, width: 0.5)),
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
Container(
|
|
width: 197 / 3.7,
|
|
height: 950 / 3.7,
|
|
// decoration: BoxDecoration(
|
|
// color: Colors.white,
|
|
// border: Border(
|
|
// right: BorderSide(
|
|
// color: Colors.black,
|
|
// width: 0.5,
|
|
// )),
|
|
// ),
|
|
alignment: Alignment.center,
|
|
child: RotatedBox(
|
|
quarterTurns: 3,
|
|
child: Text(
|
|
code,
|
|
style: TextStyle(
|
|
color: Colors.black,
|
|
fontSize: 20,
|
|
fontWeight: FontWeight.bold),
|
|
),
|
|
),
|
|
),
|
|
Container(
|
|
width: 215 / 3.7,
|
|
height: 950 / 3.7,
|
|
// decoration: BoxDecoration(
|
|
// border: Border(
|
|
// right: BorderSide(
|
|
// color: Colors.black,
|
|
// width: 0.5,
|
|
// )),
|
|
// ),
|
|
alignment: Alignment.center,
|
|
// child: Column(
|
|
// children: [
|
|
// Container(
|
|
// width: 215 / 3.7,
|
|
// height: 950 / 3.7 / 3,
|
|
// decoration: BoxDecoration(
|
|
// border: Border(
|
|
// bottom: BorderSide(
|
|
// color: Colors.black,
|
|
// width: 0.5,
|
|
// )),
|
|
// ),
|
|
// alignment: Alignment.center,
|
|
// child: RotatedBox(
|
|
// quarterTurns: 3,
|
|
// child: Text(
|
|
// country,
|
|
// style: TextStyle(
|
|
// color: Colors.black,
|
|
// fontSize: 17,
|
|
// fontWeight: FontWeight.bold),
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// Container(
|
|
// width: 215 / 3.7,
|
|
// height: 950 / 3.7 / 3 * 2 - 4,
|
|
// padding: EdgeInsets.symmetric(vertical: 10),
|
|
// alignment: Alignment.center,
|
|
// child: RotatedBox(
|
|
// quarterTurns: 3,
|
|
// child: Text(
|
|
// channel,
|
|
// style: TextStyle(
|
|
// color: Colors.black,
|
|
// fontSize: 15,
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// )
|
|
// ],
|
|
// )
|
|
),
|
|
Container(
|
|
width: 358 / 3.7 -30,
|
|
height: 950 / 3.7,
|
|
alignment: Alignment.center,
|
|
child: Column(
|
|
children: [
|
|
// Container(
|
|
// width: 358 / 3.7 -20,
|
|
// height: 950 / 3.7 / 3,
|
|
// decoration: BoxDecoration(
|
|
// border: Border(
|
|
// bottom: BorderSide(
|
|
// color: Colors.black,
|
|
// width: 0.5,
|
|
// )),
|
|
// ),
|
|
// alignment: Alignment.center,
|
|
// child: RotatedBox(
|
|
// quarterTurns: 3,
|
|
// child: Text(
|
|
// countStr,
|
|
// style: TextStyle(
|
|
// color: Colors.black,
|
|
// fontSize: 17,
|
|
// fontWeight: FontWeight.bold),
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// Container(
|
|
// width: 358 / 3.7 -30,
|
|
// height: 950 / 3.7 / 3 * 2 - 1.5,
|
|
// padding: EdgeInsets.only(left: 15,top: 15,bottom: 15,right: 10) ,
|
|
// child: RotatedBox(
|
|
// quarterTurns: 3,
|
|
// child: BarcodeWidget(
|
|
//
|
|
// barcode: Barcode.code128(),
|
|
// data: code,
|
|
// style: TextStyle(
|
|
// fontSize: 10
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// )
|
|
],
|
|
)),
|
|
],
|
|
),
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|