import 'dart:async'; import 'package:chicken_farm/components/vb_dict_label.dart'; import 'package:chicken_farm/core/utils/logger.dart'; import 'package:flutter/material.dart'; import 'package:chicken_farm/apis/breeding/_query.dart'; import 'package:chicken_farm/components/vb_electronic_id_field.dart'; import 'package:chicken_farm/core/utils/toast.dart'; import 'package:chicken_farm/modes/breeding/chicken.dart'; import 'package:intl/intl.dart'; class IndividualQueryPage extends StatefulWidget { const IndividualQueryPage({super.key}); @override State createState() => _IndividualQueryPageState(); } class _IndividualQueryPageState extends State { final BreedQueryApi _breedQueryApi = BreedQueryApi(); ChickenModel? _chicken; String? _electronicId; bool _isLoading = false; final TextEditingController _idController = TextEditingController(); Timer? _debounceTimer; // 添加Timer变量用于管理延时操作 // 添加手动模式状态 bool _isManualMode = false; @override void initState() { super.initState(); } @override void dispose() { // 取消任何待处理的计时器 if (_debounceTimer != null) { _debounceTimer!.cancel(); } _idController.dispose(); super.dispose(); } void _queryChickenOnce(String id) { if (_debounceTimer != null) { _debounceTimer!.cancel(); } _debounceTimer = Timer(Duration(milliseconds: 800), () { _queryChicken(id); }); } Future _queryChicken(String id) async { if (id.isEmpty) { ToastUtil.warning('请输入电子编号'); return; } setState(() { _isLoading = true; }); try { final chicken = await _breedQueryApi.queryChicken(id.trim()); if (chicken != null) { if (mounted) { // 遵循Flutter异步操作与UI更新安全规范 setState(() { _chicken = chicken; }); } } else { if (mounted) { // 遵循Flutter异步操作与UI更新安全规范 ToastUtil.error('未找到该编号对应的个体信息'); setState(() { _chicken = null; }); } } } catch (e) { if (mounted) { // 遵循Flutter异步操作与UI更新安全规范 ToastUtil.error('查询失败: $e'); logger.e(e); setState(() { _chicken = null; }); } } finally { if (mounted) { // 遵循Flutter异步操作与UI更新安全规范 setState(() { _isLoading = false; }); } } } // 手动查询方法 void _manualQueryChicken() { if (_idController.text.isEmpty) { ToastUtil.warning('请输入电子编号'); return; } _queryChicken(_idController.text); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('个体查询')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ // 按钮行 - 手动/自动切换按钮 Row( mainAxisAlignment: MainAxisAlignment.end, // 靠右对齐 children: [ // 手动/自动切换按钮 SizedBox( // 设置固定宽度 width: 120, child: ElevatedButton( onPressed: () { setState(() { _isManualMode = !_isManualMode; _idController.clear(); _chicken = null; _electronicId = null; }); }, style: ElevatedButton.styleFrom( backgroundColor: _isManualMode ? Colors.blue : Colors.orange, foregroundColor: Colors.white, ), child: Text(_isManualMode ? '识别查询' : '手动查询'), ), ), ], ), const SizedBox(height: 8), // 添加一点间距 // 电子标签输入区域 - 根据模式动态显示 if (!_isManualMode) ...[ _buildPlatformSpecificField(), ] else ...[ // 手动输入模式 Row( children: [ Expanded( child: TextField( controller: _idController, decoration: const InputDecoration( labelText: '电子编号', border: OutlineInputBorder(), hintText: '请输入电子编号', ), ), ), const SizedBox(width: 8), ElevatedButton( onPressed: _manualQueryChicken, style: ElevatedButton.styleFrom( backgroundColor: Colors.green, foregroundColor: Colors.white, ), child: const Text('查询'), ), ], ), ], const SizedBox(height: 16), // 个体信息展示区域 if (_chicken != null) ...[ Expanded( child: SingleChildScrollView( child: Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 基本信息 const Text( '基本信息', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 10), _buildInfoRow('电子编号:', _chicken!.electronicId), _buildInfoRow('批次号:', _chicken!.batchNum), _buildInfoRow('家系编号:', _chicken!.familyNum), _buildInfoRow('笼号:', _chicken!.cageNum ?? '无'), _buildInfoRow2( '性别:', VberDictLabel( dictType: "chicken_gender", value: _chicken!.gender.toString(), ), ), _buildInfoRow( '孵化日期:', DateFormat( 'yyyy-MM-dd', ).format(_chicken!.hatchDate), ), if (_chicken!.currentAge != null) _buildInfoRow('当前日龄:', '${_chicken!.currentAge} 天'), _buildInfoRow2( '养殖状态:', VberDictLabel( dictType: "chicken_status", value: _chicken!.status.toString(), ), ), if (_chicken!.cullReason != null) _buildInfoRow2( '淘汰原因:', VberDictLabel( dictType: "chicken_cull_reason", value: _chicken!.cullReason.toString(), ), ), if (_chicken!.disposalMethod != null) _buildInfoRow2( '处理方式:', VberDictLabel( dictType: "chicken_disposal_method", value: _chicken!.disposalMethod.toString(), ), ), if (_chicken!.cullTime != null) _buildInfoRow( '淘汰时间:', DateFormat( 'yyyy-MM-dd HH:mm:ss', ).format(_chicken!.cullTime!), ), const SizedBox(height: 20), // SOP信息 // const Text( // 'SOP信息', // style: TextStyle( // fontSize: 18, // fontWeight: FontWeight.bold, // ), // ), // const SizedBox(height: 10), // _buildInfoRow('饲料SOP:', _chicken!.feedSopName ?? '无'), // _buildInfoRow('用药SOP:', _chicken!.drugSopName ?? '无'), // _buildInfoRow( // '疫苗SOP:', // _chicken!.vaccineSopName ?? '无', // ), ], ), ), ), ), ), ] else if (!_isLoading) Expanded( child: Center( child: Text( '请${_isManualMode ? "输入" : "识别"}电子编号查询', style: Theme.of( context, ).textTheme.titleMedium?.copyWith(color: Colors.grey[600]), ), ), ), ], ), ), ); } // 根据平台构建特定字段组件 Widget _buildPlatformSpecificField() { return VberElectronicIdsField( electronicId: _electronicId, scanMilliseconds: 1000, onIdScanned: (id) { setState(() { _electronicId = id; }); _queryChickenOnce(id); }, label: '电子编号', placeholder: '未识别', ); } Widget _buildInfoRow(String label, String value) { return Padding( padding: const EdgeInsets.only(bottom: 8.0), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 80, child: Text( label, style: const TextStyle(fontWeight: FontWeight.w500), ), ), Expanded( child: Text(value, style: const TextStyle(color: Colors.black87)), ), ], ), ); } Widget _buildInfoRow2(String label, Widget value) { return Padding( padding: const EdgeInsets.only(bottom: 8.0), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 80, child: Text( label, style: const TextStyle(fontWeight: FontWeight.w500), ), ), value, ], ), ); } }