Browse Source

Update 优化换笼页面扫码功能

Yue 1 week ago
parent
commit
0b8172fb99
1 changed files with 162 additions and 104 deletions
  1. 162 104
      UI/CF.APP/chicken_farm/lib/pages/breeding/cage_change_page.dart

+ 162 - 104
UI/CF.APP/chicken_farm/lib/pages/breeding/cage_change_page.dart

@@ -18,6 +18,10 @@ class _CageChangePageState extends State<CageChangePage> {
   String? _targetCageId;
   final List<String> _rfids = [];
 
+  // 添加FocusNode用于控制焦点
+  final FocusNode _sourceCageFocusNode = FocusNode();
+  final FocusNode _targetCageFocusNode = FocusNode();
+
   // 扫描状态
   bool _isScanningSource = false;
   bool _isScanningTarget = false;
@@ -28,6 +32,19 @@ class _CageChangePageState extends State<CageChangePage> {
   void initState() {
     super.initState();
 
+    // 监听焦点变化以更新_scanTag值
+    _sourceCageFocusNode.addListener(() {
+      if (_sourceCageFocusNode.hasFocus) {
+        _scanTag = 1;
+      }
+    });
+
+    _targetCageFocusNode.addListener(() {
+      if (_targetCageFocusNode.hasFocus) {
+        _scanTag = 2;
+      }
+    });
+
     ScanChannel.openScanHead().then((success) {
       if (success) {
         logger.d("扫描头已打开");
@@ -45,6 +62,12 @@ class _CageChangePageState extends State<CageChangePage> {
             _sourceCageId = result;
             _isScanningSource = false;
           });
+          // 源笼号扫描成功后自动延时扫描目标笼号
+          WidgetsBinding.instance.addPostFrameCallback((_) {
+            _sourceCageFocusNode.requestFocus();
+            logger.d("开始自动扫描目标笼号");
+            _dealyScanCode(2);
+          });
         } else if (_scanTag == 2) {
           // 目标笼号
           setState(() {
@@ -62,10 +85,19 @@ class _CageChangePageState extends State<CageChangePage> {
         });
       },
     );
+
+    // 进入页面默认使原笼号获取到焦点
+    WidgetsBinding.instance.addPostFrameCallback((_) {
+      _sourceCageFocusNode.requestFocus();
+    });
   }
 
   @override
   void dispose() {
+    // 释放FocusNode
+    _sourceCageFocusNode.dispose();
+    _targetCageFocusNode.dispose();
+
     // 释放RFID
     _rfidManager.disposeRfid();
     // 手动关闭扫描头,立即释放资源
@@ -79,84 +111,62 @@ class _CageChangePageState extends State<CageChangePage> {
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: const VberAppBar(title: '换笼管理', showLeftButton: true),
-      body: Padding(
-        padding: const EdgeInsets.all(16.0),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.start,
-          children: [
-            // 源笼号区域
-            _buildCageSection(
-              title: '源笼号',
-              value: _sourceCageId,
-              isScanning: _isScanningSource,
-              onScanPressed: _scanSourceCage,
-              onChangePressed: _handleChangeSourceCage,
-            ),
+      body: SingleChildScrollView(
+        child: Padding(
+          padding: const EdgeInsets.all(16.0),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              // 源笼号区域
+              _buildCageSection(1),
 
-            const SizedBox(height: 15),
+              const SizedBox(height: 15),
 
-            // 目标笼号区域
-            _buildCageSection(
-              title: '目标笼号',
-              value: _targetCageId,
-              isScanning: _isScanningTarget,
-              onScanPressed: _scanTargetCage,
-              onChangePressed: _handleChangeTargetCage,
-            ),
-            const SizedBox(height: 15),
-            // 电子编号区域
-            VberRfidField(
-              rfids: _rfids,
-              onRfidScanned: (rfid) {
-                setState(() {
-                  _rfids.insert(0, rfid);
-                });
-                ToastUtil.success("标签已添加");
-              },
-              multiple: true,
-              label: '鸡数量',
-              multiplePlaceholder: '未扫描',
-              multipleFormat: '已扫描 %d 只鸡',
-            ),
-            const SizedBox(height: 15),
-            // 提交按钮
-            SizedBox(
-              width: double.infinity,
-              child: ElevatedButton(
-                onPressed:
-                    _sourceCageId != null &&
-                        _targetCageId != null &&
-                        _rfids.isNotEmpty
-                    ? _handleSubmit
-                    : null,
-                style: ElevatedButton.styleFrom(
-                  backgroundColor:
-                      (_sourceCageId != null &&
+              // 目标笼号区域
+              _buildCageSection(2),
+              const SizedBox(height: 15),
+              // 电子编号区域
+              _buildRfidSection(),
+              const SizedBox(height: 15),
+              // 提交按钮
+              SizedBox(
+                width: double.infinity,
+                child: ElevatedButton(
+                  onPressed:
+                      _sourceCageId != null &&
                           _targetCageId != null &&
-                          _rfids.isNotEmpty)
-                      ? Colors.blue
-                      : Colors.grey,
-                  foregroundColor: Colors.white,
+                          _rfids.isNotEmpty
+                      ? _handleSubmit
+                      : null,
+                  style: ElevatedButton.styleFrom(
+                    backgroundColor:
+                        (_sourceCageId != null &&
+                            _targetCageId != null &&
+                            _rfids.isNotEmpty)
+                        ? Colors.blue
+                        : Colors.grey,
+                    foregroundColor: Colors.white,
+                  ),
+                  child: const Text('提交'),
                 ),
-                child: const Text('提交'),
-              ),
-            ),
-            const SizedBox(height: 20),
-            // 已扫描的电子编号列表
-            if (_rfids.isNotEmpty) ...[
-              const Text(
-                '已扫描的电子编号',
-                style: TextStyle(fontWeight: FontWeight.bold),
               ),
-              const SizedBox(height: 10),
-              Expanded(
-                child: Container(
+              const SizedBox(height: 20),
+              // 已扫描的电子编号列表
+              if (_rfids.isNotEmpty) ...[
+                const Text(
+                  '已扫描的电子编号',
+                  style: TextStyle(fontWeight: FontWeight.bold),
+                ),
+                const SizedBox(height: 10),
+                Container(
                   padding: const EdgeInsets.all(10),
                   decoration: BoxDecoration(
                     border: Border.all(color: Colors.grey),
                     borderRadius: BorderRadius.circular(8),
                   ),
                   child: ListView.builder(
+                    shrinkWrap: true,
+                    physics: const NeverScrollableScrollPhysics(),
                     padding: EdgeInsets.zero,
                     itemCount: _rfids.length,
                     itemBuilder: (context, index) {
@@ -179,22 +189,27 @@ class _CageChangePageState extends State<CageChangePage> {
                     },
                   ),
                 ),
-              ),
+              ],
+              const SizedBox(height: 20),
             ],
-            const SizedBox(height: 20),
-          ],
+          ),
         ),
       ),
     );
   }
 
-  Widget _buildCageSection({
-    required String title,
-    String? value,
-    required bool isScanning,
-    required VoidCallback onScanPressed,
-    required VoidCallback onChangePressed,
-  }) {
+  Widget _buildCageSection(int tag) {
+    String title = '源笼号';
+    String? value = _sourceCageId;
+    bool isScanning = _isScanningSource;
+    FocusNode focusNode = _sourceCageFocusNode;
+    if (tag != 1) {
+      tag = 2;
+      title = '目标笼号';
+      value = _targetCageId;
+      isScanning = _isScanningTarget;
+      focusNode = _targetCageFocusNode;
+    }
     return Column(
       crossAxisAlignment: CrossAxisAlignment.start,
       children: [
@@ -209,18 +224,42 @@ class _CageChangePageState extends State<CageChangePage> {
           child: Row(
             children: [
               Expanded(
-                child: Text(
-                  value ?? '未扫描',
+                // 将Text替换为TextField
+                child: TextField(
+                  focusNode: focusNode,
+                  controller: TextEditingController(text: value),
+                  decoration: InputDecoration(
+                    border: InputBorder.none,
+                    hintText: value ?? '未扫描',
+                    hintStyle: TextStyle(
+                      color: value != null ? Colors.black : Colors.grey,
+                      fontSize: 16,
+                    ),
+                  ),
                   style: TextStyle(
                     color: value != null ? Colors.black : Colors.grey,
                     fontSize: 16,
                   ),
+                  onChanged: (text) {
+                    // 根据标题判断是哪个输入框
+                    if (title == '源笼号') {
+                      setState(() {
+                        _sourceCageId = text.isEmpty ? null : text;
+                      });
+                    } else if (title == '目标笼号') {
+                      setState(() {
+                        _targetCageId = text.isEmpty ? null : text;
+                      });
+                    }
+                  },
                 ),
               ),
               if (value != null) ...[
                 IconButton(
                   icon: const Icon(Icons.refresh, size: 20),
-                  onPressed: onChangePressed,
+                  onPressed: () {
+                    _handleChangeCageCode(tag);
+                  },
                 ),
               ] else ...[
                 IconButton(
@@ -231,7 +270,9 @@ class _CageChangePageState extends State<CageChangePage> {
                           child: CircularProgressIndicator(strokeWidth: 2),
                         )
                       : const Icon(Icons.qr_code_scanner, size: 20),
-                  onPressed: onScanPressed,
+                  onPressed: () {
+                    _handleScanCageCode(tag);
+                  },
                 ),
               ],
             ],
@@ -241,48 +282,65 @@ class _CageChangePageState extends State<CageChangePage> {
     );
   }
 
-  // 扫描源笼号
-  void _scanSourceCage() async {
-    if (_isScanningSource) return;
+  Widget _buildRfidSection() {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        const Text('电子编号', style: TextStyle(fontWeight: FontWeight.bold)),
+        const SizedBox(height: 10),
+        Container(
+          padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
+          decoration: BoxDecoration(),
+        ),
+      ],
+    );
+    // return VberRfidField(
+    //   rfids: _rfids,
+    //   onRfidScanned: (rfid) {
+    //     setState(() {
+    //       _rfids.insert(0, rfid);
+    //     });
+    //     ToastUtil.success("标签已添加");
+    //   },
+    //   multiple: true,
+    //   label: '鸡数量',
+    //   multiplePlaceholder: '未扫描',
+    //   multipleFormat: '已扫描 %d 只鸡',
+    // );
+  }
 
-    setState(() {
-      _isScanningSource = true;
-    });
+  void _dealyScanCode(int scanTag, {int? dealy}) async {
+    dealy ??= 800;
+    _scanTag = scanTag;
 
-    _scanTag = 1;
+    await Future.delayed(Duration(milliseconds: dealy));
     bool success = await ScanChannel.startScan();
     if (!success) {
       ToastUtil.error("扫码失败");
     }
   }
 
-  // 扫描目标笼号
-  void _scanTargetCage() async {
-    if (_isScanningTarget) return;
-
+  void _handleScanCageCode(int tag) async {
+    if (_isScanningTarget || _isScanningSource) return;
     setState(() {
-      _isScanningTarget = true;
+      if (tag == 1) {
+        _isScanningSource = true;
+      } else if (tag == 2) {
+        _isScanningTarget = true;
+      }
     });
-
-    _scanTag = 2;
+    _scanTag = tag;
     bool success = await ScanChannel.startScan();
     if (!success) {
       ToastUtil.error("扫码失败");
     }
   }
 
-  // 重新扫描源笼号
-  void _handleChangeSourceCage() {
+  void _handleChangeCageCode(int tag) {
     setState(() {
       _sourceCageId = null;
     });
-  }
-
-  // 重新扫描目标笼号
-  void _handleChangeTargetCage() {
-    setState(() {
-      _targetCageId = null;
-    });
+    _dealyScanCode(tag);
   }
 
   // 移除指定索引的电子编号