Browse Source

Update 换笼界面去除源笼号,优化页面识别rfid的提示

Yue 3 days ago
parent
commit
eabc4862ee

+ 0 - 1
UI/CF.APP/chicken_farm/lib/apis/breeding/_submit.dart

@@ -66,7 +66,6 @@ class BreedSubmitApi {
     List<Map<String, dynamic>> list = ids.map<Map<String, dynamic>>((id) {
       return {
         'rfid': id,
-        'source_cage': data['sourceCage'],
         'target_cage': data['targetCage'],
         'date': data['date'],
         'is_export': 0,

+ 0 - 1
UI/CF.APP/chicken_farm/lib/core/db/table_config.dart

@@ -51,7 +51,6 @@ class TableConfig {
           CREATE TABLE IF NOT EXISTS ${TableConfig.cageChange} (
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             rfid TEXT,
-            source_cage TEXT,
             target_cage TEXT,
             is_export INTEGER,
             date TEXT,

+ 14 - 2
UI/CF.APP/chicken_farm/lib/pages/breeding/batch_create_page.dart

@@ -291,7 +291,13 @@ class _BatchCreatePageState extends State<BatchCreatePage> {
               _rfids.insert(0, rfid.uid);
             }
           });
-          ToastUtil.success("新增 ${newRfids.length} 枚电子编号");
+          ScaffoldMessenger.of(context).showSnackBar(
+            SnackBar(
+              content: Text("新增 ${newRfids.length} 枚电子编号"),
+              backgroundColor: Colors.green,
+            ),
+          );
+          // ToastUtil.success("新增 ${newRfids.length} 枚电子编号");
           // if (newRfids.length == scannedRfids.length) {
           //   // 全都是新添加的
           //   ToastUtil.success("成功添加 ${newRfids.length} 枚新的电子编号");
@@ -302,7 +308,13 @@ class _BatchCreatePageState extends State<BatchCreatePage> {
           // }
         } else {
           // 所有RFID都已存在
-          ToastUtil.info("电子编号已存在");
+          // ToastUtil.info("电子编号已存在");
+          ScaffoldMessenger.of(context).showSnackBar(
+            const SnackBar(
+              content: Text('电子编号已存在'),
+              backgroundColor: Colors.orange,
+            ),
+          );
         }
       },
       multiple: true,

+ 14 - 2
UI/CF.APP/chicken_farm/lib/pages/breeding/batch_culling_page.dart

@@ -133,10 +133,22 @@ class _BatchCullingPageState extends State<BatchCullingPage> {
               _rfids.insert(0, rfid.uid);
             }
           });
-          ToastUtil.success("新增 ${newRfids.length} 枚电子编号");
+          // ToastUtil.success("新增 ${newRfids.length} 枚电子编号");
+          ScaffoldMessenger.of(context).showSnackBar(
+            SnackBar(
+              content: Text("新增 ${newRfids.length} 枚电子编号"),
+              backgroundColor: Colors.green,
+            ),
+          );
         } else {
           // 所有RFID都已存在
-          ToastUtil.info("电子编号已存在");
+          // ToastUtil.info("电子编号已存在");
+          ScaffoldMessenger.of(context).showSnackBar(
+            const SnackBar(
+              content: Text('电子编号已存在'),
+              backgroundColor: Colors.orange,
+            ),
+          );
         }
       },
       multiple: true,

+ 266 - 113
UI/CF.APP/chicken_farm/lib/pages/breeding/cage_change_page.dart

@@ -19,36 +19,40 @@ class _CageChangePageState extends State<CageChangePage> {
   final List<String> _rfids = [];
 
   // 添加TextEditingControllers用于控制输入框
-  final TextEditingController _sourceCageController = TextEditingController();
-  final TextEditingController _targetCageController = TextEditingController();
+  // final TextEditingController _sourceCageController = TextEditingController();
+  // final TextEditingController _targetCageController = TextEditingController();
+  final TextEditingController _cageController = TextEditingController();
 
   // 添加FocusNode用于控制焦点
-  final FocusNode _sourceCageFocusNode = FocusNode();
-  final FocusNode _targetCageFocusNode = FocusNode();
+  // final FocusNode _sourceCageFocusNode = FocusNode();
+  // final FocusNode _targetCageFocusNode = FocusNode();
 
   // 扫描状态
-  bool _isScanningSource = false;
-  bool _isScanningTarget = false;
-  int _scanTag = 1;
+  // bool _isScanningSource = false;
+  // bool _isScanningTarget = false;
+  // int _scanTag = 1;
+  bool _isScanningCode = false;
 
   @override
   void initState() {
     super.initState();
 
-    _sourceCageController.clear();
-    _targetCageController.clear();
+    // _sourceCageController.clear();
+    // _targetCageController.clear();
     // 监听焦点变化以更新_scanTag值
-    _sourceCageFocusNode.addListener(() {
-      if (_sourceCageFocusNode.hasFocus) {
-        _scanTag = 1;
-      }
-    });
+    // _sourceCageFocusNode.addListener(() {
+    //   if (_sourceCageFocusNode.hasFocus) {
+    //     _scanTag = 1;
+    //   }
+    // });
 
-    _targetCageFocusNode.addListener(() {
-      if (_targetCageFocusNode.hasFocus) {
-        _scanTag = 2;
-      }
-    });
+    // _targetCageFocusNode.addListener(() {
+    //   if (_targetCageFocusNode.hasFocus) {
+    //     _scanTag = 2;
+    //   }
+    // });
+    _isScanningCode = false;
+    _cageController.clear();
 
     // 延迟到下一帧执行,确保页面构建完成后再打开扫描头
     WidgetsBinding.instance.addPostFrameCallback((_) {
@@ -66,40 +70,52 @@ class _CageChangePageState extends State<CageChangePage> {
       // 初始化监听
       ScanChannel.initScanListener(
         onScanResult: (result) {
-          if (_scanTag == 1) {
-            // 源笼号
-            setState(() {
-              _sourceCageController.text = result;
-              _isScanningSource = false;
-            });
-            if (_targetCageController.text.isEmpty) {
-              // 源笼号扫描成功后自动延时扫描目标笼号
-              ScanChannel.stopSingleScan();
-              logger.d("自动扫描目标笼号");
-              _targetCageFocusNode.requestFocus();
-              _dealyScanCode(2);
-            }
-          } else if (_scanTag == 2) {
-            // 目标笼号
-            setState(() {
-              _targetCageController.text = result;
-              _isScanningTarget = false;
-            });
-          }
+          // if (_scanTag == 1) {
+          //   // 源笼号
+          //   setState(() {
+          //     _sourceCageController.text = result;
+          //     _isScanningSource = false;
+          //   });
+          //   if (_targetCageController.text.isEmpty) {
+          //     // 源笼号扫描成功后自动延时扫描目标笼号
+          //     ScanChannel.stopSingleScan();
+          //     logger.d("自动扫描目标笼号");
+          //     _targetCageFocusNode.requestFocus();
+          //     _dealyScanCode(2);
+          //   }
+          // } else if (_scanTag == 2) {
+          //   // 目标笼号
+          //   setState(() {
+          //     _targetCageController.text = result;
+          //     _isScanningTarget = false;
+          //   });
+          // }
+          // // 目标笼号
+          // setState(() {
+          //   logger.d("扫描目标笼号:$result");
+          //   _targetCageController.text = result;
+          //   _isScanningTarget = false;
+          // });
+          setState(() {
+            logger.d("扫描目标笼号:$result");
+            _cageController.text = result;
+            _isScanningCode = false;
+          });
           // 扫码成功后停止解码(保留扫描头)
           ScanChannel.stopSingleScan();
         },
         onScanError: (error) {
           logger.d("扫码错误:$error");
           setState(() {
-            _isScanningSource = false;
+            _isScanningCode = false;
           });
         },
         onKeyPress: (bool isDouble, String keyCode) {
           if (isDouble && keyCode == "KEY_619") {
-            _sourceCageController.clear();
-            _targetCageController.clear();
-            _scanTag = 1;
+            // _sourceCageController.clear();
+            // _targetCageController.clear();
+            _cageController.clear();
+            // _scanTag = 1;
             ScanChannel.startScan();
           } else {
             logger.d("按键:$isDouble $keyCode");
@@ -108,18 +124,19 @@ class _CageChangePageState extends State<CageChangePage> {
       );
     });
 
-    _scanTag = 1;
+    // _scanTag = 1;
   }
 
   @override
   void dispose() {
     // 释放TextEditingControllers
-    _sourceCageController.dispose();
-    _targetCageController.dispose();
+    // _sourceCageController.dispose();
+    // _targetCageController.dispose();
+    _cageController.dispose();
 
     // 释放FocusNode
-    _sourceCageFocusNode.dispose();
-    _targetCageFocusNode.dispose();
+    // _sourceCageFocusNode.dispose();
+    // _targetCageFocusNode.dispose();
 
     // 手动关闭扫描头,立即释放资源
     ScanChannel.closeScanHead();
@@ -138,32 +155,53 @@ class _CageChangePageState extends State<CageChangePage> {
           child: Column(
             crossAxisAlignment: CrossAxisAlignment.start,
             children: [
-              // 源笼号区域
-              _buildCageSection(1),
+              // // 源笼号区域
+              // _buildCageSection(1),
 
-              const SizedBox(height: 15),
+              // const SizedBox(height: 15),
 
+              // // 目标笼号区域
+              // _buildCageSection(2),
+              // const SizedBox(height: 15),
               // 目标笼号区域
-              _buildCageSection(2),
+              _buildCageSection(),
               const SizedBox(height: 15),
               // 电子编号区域
               _buildRfidSection(),
               const SizedBox(height: 15),
+
               // 提交按钮
+              // SizedBox(
+              //   width: double.infinity,
+              //   child: ElevatedButton(
+              //     onPressed:
+              //         _sourceCageController.text.isNotEmpty &&
+              //             _targetCageController.text.isNotEmpty &&
+              //             _rfids.isNotEmpty
+              //         ? _handleSubmit
+              //         : null,
+              //     style: ElevatedButton.styleFrom(
+              //       backgroundColor:
+              //           (_sourceCageController.text.isNotEmpty &&
+              //               _targetCageController.text.isNotEmpty &&
+              //               _rfids.isNotEmpty)
+              //           ? Colors.blue
+              //           : Colors.grey,
+              //       foregroundColor: Colors.white,
+              //     ),
+              //     child: const Text('提交'),
+              //   ),
+              // ),
               SizedBox(
                 width: double.infinity,
                 child: ElevatedButton(
                   onPressed:
-                      _sourceCageController.text.isNotEmpty &&
-                          _targetCageController.text.isNotEmpty &&
-                          _rfids.isNotEmpty
+                      _cageController.text.isNotEmpty && _rfids.isNotEmpty
                       ? _handleSubmit
                       : null,
                   style: ElevatedButton.styleFrom(
                     backgroundColor:
-                        (_sourceCageController.text.isNotEmpty &&
-                            _targetCageController.text.isNotEmpty &&
-                            _rfids.isNotEmpty)
+                        (_cageController.text.isNotEmpty && _rfids.isNotEmpty)
                         ? Colors.blue
                         : Colors.grey,
                     foregroundColor: Colors.white,
@@ -171,6 +209,7 @@ class _CageChangePageState extends State<CageChangePage> {
                   child: const Text('提交'),
                 ),
               ),
+
               const SizedBox(height: 20),
               // 已识别的电子编号列表
               if (_rfids.isNotEmpty) ...[
@@ -229,31 +268,106 @@ class _CageChangePageState extends State<CageChangePage> {
     );
   }
 
-  Widget _buildCageSection(int tag) {
-    String title = '源笼号';
-    TextEditingController controller = _sourceCageController;
-    FocusNode focusNode = _sourceCageFocusNode;
-    bool isScanning = _isScanningSource;
-
-    if (tag != 1) {
-      tag = 2;
-      title = '目标笼号';
-      controller = _targetCageController;
-      focusNode = _targetCageFocusNode;
-      isScanning = _isScanningTarget;
-    }
+  // Widget _buildCageSection(int tag) {
+  //   String title = '源笼号';
+  //   TextEditingController controller = _sourceCageController;
+  //   FocusNode focusNode = _sourceCageFocusNode;
+  //   bool isScanning = _isScanningSource;
+  //   if (tag != 1) {
+  //     tag = 2;
+  //     title = '目标笼号';
+  //     controller = _targetCageController;
+  //     focusNode = _targetCageFocusNode;
+  //     isScanning = _isScanningTarget;
+  //   }
+  //   // 确保光标在文本末尾
+  //   if (controller.text.isNotEmpty) {
+  //     controller.selection = TextSelection.fromPosition(
+  //       TextPosition(offset: controller.text.length),
+  //     );
+  //   }
+  //   return Column(
+  //     crossAxisAlignment: CrossAxisAlignment.start,
+  //     children: [
+  //       Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
+  //       const SizedBox(height: 10),
+  //       Container(
+  //         padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
+  //         decoration: BoxDecoration(
+  //           border: Border.all(color: Colors.grey),
+  //           borderRadius: BorderRadius.circular(8),
+  //         ),
+  //         child: Row(
+  //           children: [
+  //             Expanded(
+  //               // 将Text替换为TextField
+  //               child: TextField(
+  //                 focusNode: focusNode,
+  //                 controller: controller,
+  //                 enabled: controller.text.isEmpty,
+  //                 decoration: InputDecoration(
+  //                   border: InputBorder.none,
+  //                   hintText: controller.text.isNotEmpty ? null : '未扫描',
+  //                   hintStyle: TextStyle(
+  //                     color: controller.text.isNotEmpty
+  //                         ? Colors.black
+  //                         : Colors.grey,
+  //                     fontSize: 16,
+  //                   ),
+  //                 ),
+  //                 style: TextStyle(
+  //                   color: controller.text.isNotEmpty
+  //                       ? Colors.black
+  //                       : Colors.grey,
+  //                   fontSize: 16,
+  //                 ),
+  //                 onChanged: (text) {
+  //                   setState(() {
+  //                     // 文本更改由controller自动处理
+  //                   });
+  //                 },
+  //               ),
+  //             ),
+  //             if (controller.text.isNotEmpty) ...[
+  //               IconButton(
+  //                 icon: const Icon(Icons.refresh, size: 20),
+  //                 onPressed: () {
+  //                   _handleChangeCageCode(tag);
+  //                 },
+  //               ),
+  //             ] else ...[
+  //               IconButton(
+  //                 icon: isScanning
+  //                     ? const SizedBox(
+  //                         width: 20,
+  //                         height: 20,
+  //                         child: CircularProgressIndicator(strokeWidth: 2),
+  //                       )
+  //                     : const Icon(Icons.qr_code_scanner, size: 20),
+  //                 onPressed: () {
+  //                   _handleScanCageCode(tag);
+  //                 },
+  //               ),
+  //             ],
+  //           ],
+  //         ),
+  //       ),
+  //     ],
+  //   );
+  // }
 
+  Widget _buildCageSection() {
     // 确保光标在文本末尾
-    if (controller.text.isNotEmpty) {
-      controller.selection = TextSelection.fromPosition(
-        TextPosition(offset: controller.text.length),
+    if (_cageController.text.isNotEmpty) {
+      _cageController.selection = TextSelection.fromPosition(
+        TextPosition(offset: _cageController.text.length),
       );
     }
 
     return Column(
       crossAxisAlignment: CrossAxisAlignment.start,
       children: [
-        Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
+        Text('目标笼号', style: const TextStyle(fontWeight: FontWeight.bold)),
         const SizedBox(height: 10),
         Container(
           padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
@@ -266,21 +380,20 @@ class _CageChangePageState extends State<CageChangePage> {
               Expanded(
                 // 将Text替换为TextField
                 child: TextField(
-                  focusNode: focusNode,
-                  controller: controller,
-                  enabled: controller.text.isEmpty,
+                  controller: _cageController,
+                  enabled: _cageController.text.isEmpty,
                   decoration: InputDecoration(
                     border: InputBorder.none,
-                    hintText: controller.text.isNotEmpty ? null : '未扫描',
+                    hintText: _cageController.text.isNotEmpty ? null : '未扫描',
                     hintStyle: TextStyle(
-                      color: controller.text.isNotEmpty
+                      color: _cageController.text.isNotEmpty
                           ? Colors.black
                           : Colors.grey,
                       fontSize: 16,
                     ),
                   ),
                   style: TextStyle(
-                    color: controller.text.isNotEmpty
+                    color: _cageController.text.isNotEmpty
                         ? Colors.black
                         : Colors.grey,
                     fontSize: 16,
@@ -292,16 +405,16 @@ class _CageChangePageState extends State<CageChangePage> {
                   },
                 ),
               ),
-              if (controller.text.isNotEmpty) ...[
+              if (_cageController.text.isNotEmpty) ...[
                 IconButton(
                   icon: const Icon(Icons.refresh, size: 20),
                   onPressed: () {
-                    _handleChangeCageCode(tag);
+                    _handleChangeCageCode();
                   },
                 ),
               ] else ...[
                 IconButton(
-                  icon: isScanning
+                  icon: _isScanningCode
                       ? const SizedBox(
                           width: 20,
                           height: 20,
@@ -309,7 +422,7 @@ class _CageChangePageState extends State<CageChangePage> {
                         )
                       : const Icon(Icons.qr_code_scanner, size: 20),
                   onPressed: () {
-                    _handleScanCageCode(tag);
+                    _handleScanCageCode();
                   },
                 ),
               ],
@@ -327,13 +440,23 @@ class _CageChangePageState extends State<CageChangePage> {
         // 检查是否已存在相同的RFID标签
         bool isDuplicate = _rfids.any((existingRfid) => existingRfid == rfid);
         if (isDuplicate) {
-          ToastUtil.info("电子编号已存在");
+          ScaffoldMessenger.of(context).showSnackBar(
+            const SnackBar(
+              content: Text('电子编号已存在'),
+              backgroundColor: Colors.orange,
+            ),
+          );
         } else {
           // 如果不重复,添加到列表中
           setState(() {
             _rfids.insert(0, rfid);
           });
-          ToastUtil.success("成功添加新的电子编号");
+          ScaffoldMessenger.of(context).showSnackBar(
+            const SnackBar(
+              content: Text('成功添加新的电子编号'),
+              backgroundColor: Colors.green,
+            ),
+          );
         }
       },
       multiple: true,
@@ -344,10 +467,47 @@ class _CageChangePageState extends State<CageChangePage> {
     );
   }
 
-  void _dealyScanCode(int scanTag, {int? dealy}) async {
-    dealy ??= 800;
-    _scanTag = scanTag;
-    logger.d("开始扫码: $_scanTag");
+  // void _dealyScanCode(int scanTag, {int? dealy}) async {
+  //   dealy ??= 800;
+  //   _scanTag = scanTag;
+  //   logger.d("开始扫码: $_scanTag");
+  //   await Future.delayed(Duration(milliseconds: dealy));
+  //   bool success = await ScanChannel.startScan();
+  //   if (!success) {
+  //     ToastUtil.error("扫码失败");
+  //   }
+  // }
+
+  // void _handleScanCageCode(int tag) async {
+  //   if (_isScanningTarget || _isScanningSource) return;
+  //   setState(() {
+  //     if (tag == 1) {
+  //       _isScanningSource = true;
+  //     } else if (tag == 2) {
+  //       _isScanningTarget = true;
+  //     }
+  //   });
+  //   _scanTag = tag;
+  //   logger.d("开始扫码: $_scanTag");
+  //   bool success = await ScanChannel.startScan();
+  //   if (!success) {
+  //     ToastUtil.error("扫码失败");
+  //   }
+  // }
+
+  // void _handleChangeCageCode(int tag) {
+  //   setState(() {
+  //     if (tag == 1) {
+  //       _sourceCageController.clear();
+  //     } else {
+  //       _targetCageController.clear();
+  //     }
+  //   });
+  //   _dealyScanCode(tag);
+  // }
+
+  void _dealyScanCode({int? dealy}) async {
+    dealy ??= 600;
     await Future.delayed(Duration(milliseconds: dealy));
     bool success = await ScanChannel.startScan();
     if (!success) {
@@ -355,32 +515,19 @@ class _CageChangePageState extends State<CageChangePage> {
     }
   }
 
-  void _handleScanCageCode(int tag) async {
-    if (_isScanningTarget || _isScanningSource) return;
+  void _handleScanCageCode() async {
+    if (_isScanningCode) return;
     setState(() {
-      if (tag == 1) {
-        _isScanningSource = true;
-      } else if (tag == 2) {
-        _isScanningTarget = true;
-      }
+      _isScanningCode = true;
     });
-    _scanTag = tag;
-    logger.d("开始扫码: $_scanTag");
     bool success = await ScanChannel.startScan();
     if (!success) {
       ToastUtil.error("扫码失败");
     }
   }
 
-  void _handleChangeCageCode(int tag) {
-    setState(() {
-      if (tag == 1) {
-        _sourceCageController.clear();
-      } else {
-        _targetCageController.clear();
-      }
-    });
-    _dealyScanCode(tag);
+  void _handleChangeCageCode() {
+    _dealyScanCode();
   }
 
   // 移除指定索引的电子编号
@@ -400,9 +547,14 @@ class _CageChangePageState extends State<CageChangePage> {
 
   // 提交数据
   void _handleSubmit() {
+    // final data = {
+    //   'sourceCage': _sourceCageController.text,
+    //   'targetCage': _targetCageController.text,
+    //   'rfids': _rfids,
+    //   'date': DateTimeUtil.format(DateTime.now()),
+    // };
     final data = {
-      'sourceCage': _sourceCageController.text,
-      'targetCage': _targetCageController.text,
+      'targetCage': _cageController.text,
       'rfids': _rfids,
       'date': DateTimeUtil.format(DateTime.now()),
     };
@@ -420,8 +572,9 @@ class _CageChangePageState extends State<CageChangePage> {
           );
           // 提交后重置表单
           setState(() {
-            _sourceCageController.clear();
-            _targetCageController.clear();
+            // _sourceCageController.clear();
+            // _targetCageController.clear();
+            _cageController.clear();
             _rfids.clear();
           });
         }

+ 19 - 4
UI/CF.APP/chicken_farm/lib/pages/breeding/individual_culling_page.dart

@@ -69,10 +69,25 @@ class _IndividualCullingPageState extends State<IndividualCullingPage> {
     return VberRfidField(
       rfid: _rfid,
       onRfidScanned: (rfid) {
-        setState(() {
-          _rfid = rfid;
-        });
-        ToastUtil.success('电子编号识别成功');
+        if (rfid == _rfid) {
+          ScaffoldMessenger.of(context).showSnackBar(
+            const SnackBar(
+              content: Text('电子编号未改变'),
+              backgroundColor: Colors.orange,
+            ),
+          );
+        } else {
+          setState(() {
+            _rfid = rfid;
+          });
+          // ToastUtil.success('电子编号识别成功');
+          ScaffoldMessenger.of(context).showSnackBar(
+            const SnackBar(
+              content: Text('成功识别新的电子编号'),
+              backgroundColor: Colors.green,
+            ),
+          );
+        }
       },
       label: '电子编号',
       placeholder: '未识别',

+ 20 - 4
UI/CF.APP/chicken_farm/lib/pages/breeding/individual_weighing_page.dart

@@ -82,10 +82,26 @@ class _IndividualWeighingPageState extends State<IndividualWeighingPage> {
     return VberRfidField(
       rfid: _rfid,
       onRfidScanned: (rfid) {
-        setState(() {
-          _rfid = rfid;
-        });
-        ToastUtil.success('电子编号识别成功');
+        if (rfid == _rfid) {
+          ScaffoldMessenger.of(context).showSnackBar(
+            const SnackBar(
+              content: Text('电子编号未改变'),
+              backgroundColor: Colors.orange,
+            ),
+          );
+        } else {
+          setState(() {
+            _rfid = rfid;
+          });
+          // ToastUtil.success('电子编号识别成功');
+          ScaffoldMessenger.of(context).showSnackBar(
+            const SnackBar(
+              content: Text('成功识别新的电子编号'),
+              backgroundColor: Colors.green,
+            ),
+          );
+        }
+
         _handleReadWeight();
       },
       label: '电子编号',