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.

509 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?> 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
// ),
// ),
// ),
// )
],
)),
],
),
);
}
}