import 'package:chicken_farm/apis/index.dart'; import 'package:chicken_farm/core/utils/datetime_util.dart'; import 'package:chicken_farm/core/utils/logger.dart'; import 'package:flutter/material.dart'; import 'package:chicken_farm/components/vb_app_bar.dart'; import 'package:chicken_farm/core/utils/toast.dart'; import 'package:chicken_farm/core/services/pda/scan_channel.dart'; import 'package:chicken_farm/components/vb_rfid_field.dart'; import 'package:go_router/go_router.dart'; class CageChangePage extends StatefulWidget { const CageChangePage({super.key}); @override State createState() => _CageChangePageState(); } class _CageChangePageState extends State { final List _rfids = []; // 添加TextEditingControllers用于控制输入框 // final TextEditingController _sourceCageController = TextEditingController(); // final TextEditingController _targetCageController = TextEditingController(); final TextEditingController _cageController = TextEditingController(); // 添加FocusNode用于控制焦点 // final FocusNode _sourceCageFocusNode = FocusNode(); // final FocusNode _targetCageFocusNode = FocusNode(); // 扫描状态 // bool _isScanningSource = false; // bool _isScanningTarget = false; // int _scanTag = 1; bool _isScanningCode = false; @override void initState() { super.initState(); // _sourceCageController.clear(); // _targetCageController.clear(); // 监听焦点变化以更新_scanTag值 // _sourceCageFocusNode.addListener(() { // if (_sourceCageFocusNode.hasFocus) { // _scanTag = 1; // } // }); // _targetCageFocusNode.addListener(() { // if (_targetCageFocusNode.hasFocus) { // _scanTag = 2; // } // }); _isScanningCode = false; _cageController.clear(); // 延迟到下一帧执行,确保页面构建完成后再打开扫描头 WidgetsBinding.instance.addPostFrameCallback((_) { ScanChannel.openScanHead().then((success) { if (success) { logger.d("扫描头已打开"); } else { ToastUtil.errorAlert("扫描头打开失败"); if (mounted) { context.pop(); } } }); // 初始化监听 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; // }); // } // // 目标笼号 // 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(() { _isScanningCode = false; }); }, onKeyPress: (bool isDouble, String keyCode) { if (isDouble && keyCode == "KEY_619") { // _sourceCageController.clear(); // _targetCageController.clear(); _cageController.clear(); // _scanTag = 1; ScanChannel.startScan(); } else { logger.d("按键:$isDouble $keyCode"); } }, ); }); // _scanTag = 1; } @override void dispose() { // 释放TextEditingControllers // _sourceCageController.dispose(); // _targetCageController.dispose(); _cageController.dispose(); // 释放FocusNode // _sourceCageFocusNode.dispose(); // _targetCageFocusNode.dispose(); // 手动关闭扫描头,立即释放资源 ScanChannel.closeScanHead(); // 释放通道 ScanChannel.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: const VberAppBar(title: '换笼管理', showLeftButton: true), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // // 源笼号区域 // _buildCageSection(1), // const SizedBox(height: 15), // // 目标笼号区域 // _buildCageSection(2), // const SizedBox(height: 15), // 目标笼号区域 _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: _cageController.text.isNotEmpty && _rfids.isNotEmpty ? _handleSubmit : null, style: ElevatedButton.styleFrom( backgroundColor: (_cageController.text.isNotEmpty && _rfids.isNotEmpty) ? Colors.blue : Colors.grey, foregroundColor: Colors.white, ), child: const Text('提交'), ), ), const SizedBox(height: 20), // 已识别的电子编号列表 if (_rfids.isNotEmpty) ...[ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( '已识别的电子编号', style: TextStyle(fontWeight: FontWeight.bold), ), IconButton( icon: const Icon(Icons.clear, size: 18), onPressed: _clearRfids, tooltip: '清空编号', ), ], ), 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) { return ListTile( visualDensity: VisualDensity.compact, contentPadding: const EdgeInsets.symmetric( horizontal: 2, vertical: 0, ), title: Text(_rfids[index]), trailing: IconButton( icon: const Icon( Icons.delete, size: 18, color: Colors.red, ), onPressed: () => _removeRfid(index), ), ); }, ), ), ], const SizedBox(height: 20), ], ), ), ), ); } // 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 (_cageController.text.isNotEmpty) { _cageController.selection = TextSelection.fromPosition( TextPosition(offset: _cageController.text.length), ); } return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('目标笼号', 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( controller: _cageController, enabled: _cageController.text.isEmpty, decoration: InputDecoration( border: InputBorder.none, hintText: _cageController.text.isNotEmpty ? null : '未扫描', hintStyle: TextStyle( color: _cageController.text.isNotEmpty ? Colors.black : Colors.grey, fontSize: 16, ), ), style: TextStyle( color: _cageController.text.isNotEmpty ? Colors.black : Colors.grey, fontSize: 16, ), onChanged: (text) { setState(() { // 文本更改由controller自动处理 }); }, ), ), if (_cageController.text.isNotEmpty) ...[ IconButton( icon: const Icon(Icons.refresh, size: 20), onPressed: () { _handleChangeCageCode(); }, ), ] else ...[ IconButton( icon: _isScanningCode ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.qr_code_scanner, size: 20), onPressed: () { _handleScanCageCode(); }, ), ], ], ), ), ], ); } Widget _buildRfidSection() { return VberRfidField( rfids: _rfids, onRfidScanned: (rfid) { // 检查是否已存在相同的RFID标签 bool isDuplicate = _rfids.any((existingRfid) => existingRfid == rfid); if (isDuplicate) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('电子编号已存在'), backgroundColor: Colors.orange, ), ); } else { // 如果不重复,添加到列表中 setState(() { _rfids.insert(0, rfid); }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('成功添加新的电子编号'), backgroundColor: Colors.green, ), ); } }, multiple: true, multipleScan: false, label: '电子编号', multiplePlaceholder: '未识别', multipleFormat: '已识别 %d 枚电子编号', ); } // 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) { ToastUtil.error("扫码失败"); } } void _handleScanCageCode() async { if (_isScanningCode) return; setState(() { _isScanningCode = true; }); bool success = await ScanChannel.startScan(); if (!success) { ToastUtil.error("扫码失败"); } } void _handleChangeCageCode() { _dealyScanCode(); } // 移除指定索引的电子编号 void _removeRfid(int index) { setState(() { _rfids.removeAt(index); }); } // 清空所有已识别的电子编号 void _clearRfids() { setState(() { _rfids.clear(); }); ToastUtil.info('已清空所有电子编号'); } // 提交数据 void _handleSubmit() { // final data = { // 'sourceCage': _sourceCageController.text, // 'targetCage': _targetCageController.text, // 'rfids': _rfids, // 'date': DateTimeUtil.format(DateTime.now()), // }; final data = { 'targetCage': _cageController.text, 'rfids': _rfids, 'date': DateTimeUtil.format(DateTime.now()), }; apis.breeding.submitApi.cageChange(data).then((res) { if (res.success) { if (res.message.isNotEmpty) { ToastUtil.success(res.message); } if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('换笼提交成功'), backgroundColor: Colors.green, ), ); // 提交后重置表单 setState(() { // _sourceCageController.clear(); // _targetCageController.clear(); _cageController.clear(); _rfids.clear(); }); } } else { ToastUtil.error('换笼提交失败'); if (mounted && res.message.isNotEmpty) { logger.e(res.message); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(res.message), backgroundColor: Colors.red), ); } } }); } }