controller.dart 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. import 'dart:ui';
  2. import 'package:fis_jsonrpc/rpc.dart';
  3. import 'package:flutter/foundation.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter_printer_plus/flutter_printer_plus.dart'
  6. if (dart.library.html) "package:vitalapp/pages/medical_checkup_station/usb_print/web/flutter_printer_plus.dart";
  7. import 'package:get/get.dart';
  8. import 'package:vitalapp/managers/interfaces/appointment.dart';
  9. import 'package:vitalapp/managers/interfaces/registration.dart';
  10. import 'package:vitalapp/pages/medical_checkup_station/registration/controller/form.dart';
  11. import 'package:vitalapp/pages/medical_checkup_station/registration/controller/list.dart';
  12. import 'package:vitalapp/pages/medical_checkup_station/registration/state/list.dart';
  13. import 'package:vitalapp/pages/medical_checkup_station/usb_print/module/printer_info.dart';
  14. import 'package:barcode_image/barcode_image.dart';
  15. import 'package:flutter_svg/flutter_svg.dart';
  16. /// 登记控制器
  17. class RegistrationController extends GetxController {
  18. late final RegistrationFormController formController;
  19. late final RegistrationListController listController;
  20. final appointmentManager = Get.find<IAppointmentManager>();
  21. final registrationManager = Get.find<IRegistrationManager>();
  22. final state = ListState();
  23. RegistrationController() {
  24. listController = RegistrationListController(this);
  25. formController = RegistrationFormController(this);
  26. }
  27. /// 登记
  28. ResidentModel resident = ResidentModel(
  29. idNumber: '',
  30. );
  31. /// 手动填写的病人名字
  32. PatientDTO? patientInfo = PatientDTO();
  33. /// 预约列表
  34. List<ResidentModel> residentList = [];
  35. /// 预约列表的总数
  36. int appointmentModelListLength = 0;
  37. /// 表格loading
  38. bool tableLoading = true;
  39. /// 当前表格页数
  40. int currPageIndex = 1;
  41. PrinterInfo? printInfo;
  42. List<Uint8List> barCodeList = [];
  43. //查询本地USB打印机列表
  44. Future<List<PrinterInfo>> queryLocalUSBPrinter() {
  45. return FlutterPrinterFinder.queryUsbPrinter().then(
  46. (value) => value.map((e) => PrinterInfo.fromUsbDevice(e)).toList(),
  47. );
  48. }
  49. _initData() async {
  50. var now = DateTime.now();
  51. listController.state.startTime = new DateTime(now.year, now.month, now.day);
  52. listController.state.endTime = listController.state.startTime!
  53. .add(Duration(hours: 23, minutes: 59, seconds: 59));
  54. await listController.getRegisterInfoPage();
  55. if (!kIsWeb) {
  56. List<PrinterInfo>? printerInfoList = await queryLocalUSBPrinter();
  57. if (printerInfoList.length == 0) {
  58. return;
  59. }
  60. printInfo = printerInfoList.first;
  61. }
  62. }
  63. Future<void> getExamLabelsByExamNoAsync(ResidentModel rowData) async {
  64. var labels = await registrationManager.getExamLabelsByExamNoAsync(
  65. physicalExamNumber: rowData.physicalExamNumber!);
  66. barCodeList.clear();
  67. for (var element in labels.eaxmLabels!) {
  68. var barCodeData = await drawRedRect(element, rowData);
  69. if (barCodeData.isNotEmpty) {
  70. barCodeList.add(barCodeData);
  71. }
  72. }
  73. }
  74. Future<Uint8List> drawRedRect(
  75. HealthExamLabelDTO labelDto, ResidentModel resident) async {
  76. const size = Size(360, 240);
  77. final svg = Barcode.code128().toSvg(labelDto.uniquedCode!, height: 80);
  78. final PictureInfo pictureInfo =
  79. await vg.loadPicture(SvgStringLoader(svg), null);
  80. var a = await _capturePainterToImage(
  81. MyPainter(pictureInfo, labelDto, resident),
  82. BgPainter(pictureInfo),
  83. size);
  84. return a!;
  85. }
  86. /// 将CustomPainter绘制的内容转换为图片
  87. Future<Uint8List?> _capturePainterToImage(
  88. CustomPainter painter, CustomPainter bgPainter, Size size) async {
  89. final bounds = Offset.zero & size;
  90. // final bounds2 = Offset.zero & Size(size.width - 20, size.height - 20);
  91. final picture = PictureRecorder();
  92. final pictureCanvas = Canvas(picture);
  93. // 给Canvas设置绘制范围
  94. pictureCanvas.clipRect(bounds);
  95. painter.paint(pictureCanvas, size);
  96. // 在Canvas上进行绘制
  97. bgPainter.paint(pictureCanvas, size);
  98. // 结束绘制
  99. final recordedPicture = picture.endRecording();
  100. final image =
  101. await recordedPicture.toImage(size.width.toInt(), size.height.toInt());
  102. // 转换为字节数组
  103. final byteData = await image.toByteData(format: ImageByteFormat.png);
  104. final bytes = byteData?.buffer.asUint8List();
  105. return bytes;
  106. }
  107. void onTap() {}
  108. @override
  109. void onReady() {
  110. _initData();
  111. super.onReady();
  112. }
  113. // void on
  114. @override
  115. void onClose() {}
  116. }
  117. class MyPainter extends CustomPainter {
  118. PictureInfo pictureInfo;
  119. HealthExamLabelDTO labelDto;
  120. ResidentModel resident;
  121. MyPainter(this.pictureInfo, this.labelDto, this.resident);
  122. @override
  123. void paint(Canvas canvas, Size size) {
  124. Paint backgroundPaint = Paint()..color = Colors.white;
  125. canvas.drawRect(
  126. Rect.fromLTWH(0, 0, size.width, size.height), backgroundPaint);
  127. canvas.drawLine(
  128. Offset(0, 85), Offset(360, 85), Paint()..color = Colors.black);
  129. // Simulate drawing the content
  130. TextSpan titleSpan = TextSpan(
  131. text: '${labelDto.title ?? ''}',
  132. style: TextStyle(fontSize: 30, height: 1, color: Colors.black),
  133. );
  134. TextPainter titleTp = TextPainter(
  135. text: titleSpan,
  136. textAlign: TextAlign.left,
  137. textDirection: TextDirection.ltr,
  138. );
  139. titleTp.layout();
  140. titleTp.paint(canvas, Offset(28, 8));
  141. TextSpan subTitleSpanName = TextSpan(
  142. text: '${resident.name} ',
  143. style: TextStyle(fontSize: 20, height: 1, color: Colors.black),
  144. );
  145. TextPainter subTitleTp1 = TextPainter(
  146. text: subTitleSpanName,
  147. textAlign: TextAlign.left,
  148. textDirection: TextDirection.ltr,
  149. );
  150. subTitleTp1.layout();
  151. subTitleTp1.paint(canvas, Offset(28, 48));
  152. TextSpan subTitleSpanAge = TextSpan(
  153. text: '${resident.age} 岁',
  154. style: TextStyle(fontSize: 20, height: 1, color: Colors.black),
  155. );
  156. TextPainter subTitleTpAge = TextPainter(
  157. text: subTitleSpanAge,
  158. textAlign: TextAlign.left,
  159. textDirection: TextDirection.ltr,
  160. );
  161. subTitleTpAge.layout();
  162. subTitleTpAge.paint(canvas, Offset(168, 48));
  163. }
  164. @override
  165. bool shouldRepaint(covariant CustomPainter oldDelegate) {
  166. return false;
  167. }
  168. }
  169. class BgPainter extends CustomPainter {
  170. PictureInfo pictureInfo;
  171. BgPainter(this.pictureInfo);
  172. @override
  173. void paint(Canvas canvas, Size size) {
  174. canvas.translate(30, 100);
  175. canvas.scale(1.5, 1.5);
  176. canvas.drawPicture(pictureInfo.picture);
  177. canvas.restore(); // 恢复之前保存的绘制状态
  178. }
  179. @override
  180. bool shouldRepaint(covariant CustomPainter oldDelegate) {
  181. return false;
  182. }
  183. }