vb_rfid_field.dart 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import 'package:chicken_farm/core/utils/logger.dart';
  2. import 'package:chicken_farm/modes/rfid/rfid_model.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:chicken_farm/core/services/pda/rfid_manager.dart';
  5. import 'package:chicken_farm/core/utils/toast.dart';
  6. /// RFID字段组件,支持单个或多个RFID显示
  7. ///
  8. /// 当[multiple]为true时,显示已识别的RFID数量
  9. /// 当[multiple]为false时,显示单个RFID的具体值
  10. class VberRfidField extends StatefulWidget {
  11. final List<String>? rfids;
  12. final String? rfid;
  13. final ValueChanged<String>? onRfidScanned; // RFID识别成功回调
  14. final ValueChanged<List<RfidModel>>? onRfidsScanned; // RFID识别成功回调
  15. final ValueChanged<String>? onKeyPress; // 按键事件
  16. final bool multiple;
  17. final bool? multipleScan;
  18. final ValueChanged<int>? onDeleteRfid; // 仅在multiple模式下使用
  19. final String label; // 显示的标签文本
  20. final String placeholder; // 未识别时显示的占位符文本
  21. final String multiplePlaceholder; // 多个模式下未识别时显示的占位符文本
  22. final String multipleFormat; // 多个模式下有值时的显示格式,包含一个%d占位符表示数量
  23. const VberRfidField({
  24. super.key,
  25. this.rfids,
  26. this.rfid,
  27. this.onRfidScanned,
  28. this.onRfidsScanned,
  29. this.onKeyPress,
  30. this.multiple = false,
  31. this.multipleScan,
  32. this.onDeleteRfid,
  33. this.label = '电子编号',
  34. this.placeholder = '未识别',
  35. this.multiplePlaceholder = '未识别',
  36. this.multipleFormat = '已识别 %d 枚电子编号',
  37. });
  38. @override
  39. State<VberRfidField> createState() => _VberRfidFieldState();
  40. }
  41. class _VberRfidFieldState extends State<VberRfidField> {
  42. late final RfidManager _rfidManager;
  43. bool _isScanning = false; // 内部管理识别状态
  44. bool _isMultiple = false; // 内部管理识别状态
  45. @override
  46. void initState() {
  47. super.initState();
  48. _rfidManager = RfidManager(
  49. onTagScanned: _handleRfidsScanned,
  50. onRFIDScanned: _handleRfidScanned,
  51. onKeyPress: _handleKeyPress,
  52. onErrorScanned: _handleScanError,
  53. );
  54. _isMultiple = widget.multipleScan ?? widget.multiple;
  55. _rfidManager.initRfid();
  56. }
  57. @override
  58. void dispose() {
  59. _rfidManager.disposeRfid();
  60. super.dispose();
  61. }
  62. void _handleRfidScanned(String rfid) {
  63. logger.d('识别成功,已识别电子编号:$rfid');
  64. setState(() {
  65. _isScanning = false;
  66. });
  67. if (widget.onRfidScanned != null) {
  68. widget.onRfidScanned!(rfid);
  69. }
  70. }
  71. void _handleRfidsScanned(List<RfidModel> rfidList) {
  72. logger.d('识别成功,已识别电子编号:$rfidList');
  73. setState(() {
  74. _isScanning = false;
  75. });
  76. if (widget.onRfidsScanned != null) {
  77. widget.onRfidsScanned!(rfidList);
  78. }
  79. }
  80. void _handleScanError(String error) {
  81. ToastUtil.error(error);
  82. setState(() {
  83. _isScanning = false;
  84. });
  85. }
  86. void _handleKeyPress(String keyCode) {
  87. if (keyCode == 'KEY_619') {
  88. _scanRfid();
  89. }
  90. }
  91. void _scanRfid() {
  92. setState(() {
  93. _isScanning = true;
  94. });
  95. ToastUtil.success('开始识别电子编号');
  96. _rfidManager.startScan(isMultiple: _isMultiple);
  97. }
  98. @override
  99. Widget build(BuildContext context) {
  100. return Column(
  101. crossAxisAlignment: CrossAxisAlignment.start,
  102. children: [
  103. Text(widget.label, style: const TextStyle(fontWeight: FontWeight.bold)),
  104. const SizedBox(height: 10),
  105. Container(
  106. padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
  107. decoration: BoxDecoration(
  108. border: Border.all(color: Colors.grey),
  109. borderRadius: BorderRadius.circular(8),
  110. ),
  111. child: Row(
  112. children: [
  113. Expanded(
  114. child: Text(
  115. _getDisplayText(),
  116. style: TextStyle(
  117. color: _hasValue() ? Colors.black : Colors.grey,
  118. fontSize: 16,
  119. ),
  120. ),
  121. ),
  122. IconButton(
  123. icon: _isScanning
  124. ? const SizedBox(
  125. width: 20,
  126. height: 20,
  127. child: CircularProgressIndicator(strokeWidth: 2),
  128. )
  129. : Icon(
  130. widget.multiple ? Icons.add : Icons.qr_code_scanner,
  131. size: 20,
  132. ),
  133. onPressed: _isScanning ? null : _scanRfid,
  134. ),
  135. ],
  136. ),
  137. ),
  138. ],
  139. );
  140. }
  141. /// 获取显示的文本
  142. String _getDisplayText() {
  143. if (widget.multiple) {
  144. if (widget.rfids == null || widget.rfids!.isEmpty) {
  145. return widget.multiplePlaceholder;
  146. } else {
  147. return widget.multipleFormat.replaceAll(
  148. '%d',
  149. widget.rfids!.length.toString(),
  150. );
  151. }
  152. } else {
  153. return widget.rfid ?? widget.placeholder;
  154. }
  155. }
  156. /// 判断是否有值
  157. bool _hasValue() {
  158. if (widget.multiple) {
  159. return widget.rfids != null && widget.rfids!.isNotEmpty;
  160. } else {
  161. return widget.rfid != null;
  162. }
  163. }
  164. }