import 'package:chicken_farm/apis/index.dart'; import 'package:chicken_farm/components/vb_electronic_id_field.dart'; import 'package:chicken_farm/core/utils/datetime_util.dart'; import 'package:chicken_farm/core/utils/logger.dart'; import 'package:chicken_farm/modes/rfid/rfid_model.dart'; import 'package:flutter/material.dart'; import 'package:chicken_farm/components/vb_app_bar.dart'; import 'package:chicken_farm/components/vb_dict_select.dart'; import 'package:chicken_farm/core/utils/toast.dart'; class BatchCullingPage extends StatefulWidget { const BatchCullingPage({super.key}); @override State createState() => _BatchCullingPageState(); } class _BatchCullingPageState extends State { final List _electronicIds = []; String? _cullReason; String? _disposalMethod; @override Widget build(BuildContext context) { return Scaffold( appBar: const VberAppBar(title: '批量淘汰', showLeftButton: true), body: SingleChildScrollView( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 电子编号区域 _buildElectronicIdSection(), const SizedBox(height: 20), // 淘汰原因 _buildCullReasonSection(), const SizedBox(height: 20), // 处置方式 _buildDisposalMethodSection(), const SizedBox(height: 20), // 提交按钮 SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _electronicIds.isNotEmpty && _cullReason != null && _disposalMethod != null ? _handleSubmit : null, style: ElevatedButton.styleFrom( backgroundColor: _electronicIds.isNotEmpty && _cullReason != null && _disposalMethod != null ? Colors.blue : Colors.grey, foregroundColor: Colors.white, ), child: const Text('提交'), ), ), const SizedBox(height: 20), // 已识别的电子编号列表 if (_electronicIds.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( height: 200, // 固定高度以支持滚动 padding: const EdgeInsets.all(10), decoration: BoxDecoration( border: Border.all(color: Colors.grey), borderRadius: BorderRadius.circular(8), ), child: ListView.builder( padding: EdgeInsets.zero, itemCount: _electronicIds.length, itemBuilder: (context, index) { return ListTile( visualDensity: VisualDensity.compact, contentPadding: const EdgeInsets.symmetric( horizontal: 2, vertical: 0, ), title: Text(_electronicIds[index]), trailing: IconButton( icon: const Icon( Icons.delete, size: 18, color: Colors.red, ), onPressed: () => _removeRfid(index), ), ); }, ), ), ], const SizedBox(height: 20), ], ), ), ); } Widget _buildElectronicIdSection() { return VberElectronicIdsField( electronicIds: _electronicIds, onIdsScanned: (List idList) { // 过滤出未存在的ID final ids = idList .where((id) => !_electronicIds.contains(id.uid)) .toList(); if (ids.isNotEmpty) { setState(() { // 将新的ID添加到列表中 for (var id in ids) { _electronicIds.insert(0, id.uid); } }); // ToastUtil.success("新增 ${newRfids.length} 枚电子编号"); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text("新增 ${ids.length} 枚电子编号"), backgroundColor: Colors.green, ), ); } else { // 所有RFID都已存在 // ToastUtil.info("电子编号已存在"); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('电子编号已存在'), backgroundColor: Colors.orange, ), ); } }, multiple: true, label: '电子编号', multiplePlaceholder: '未识别', multipleFormat: '已识别 %d 枚电子编号', ); } Widget _buildCullReasonSection() { 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( border: Border.all(color: Colors.grey), borderRadius: BorderRadius.circular(8), ), child: VberDictSelect( dictType: 'chicken_cull_reason', value: _cullReason, onChanged: (value) { setState(() { _cullReason = value; }); }, hint: '请选择淘汰原因', hideUnderline: true, ), ), ], ); } Widget _buildDisposalMethodSection() { 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( border: Border.all(color: Colors.grey), borderRadius: BorderRadius.circular(8), ), child: VberDictSelect( dictType: 'chicken_disposal_method', value: _disposalMethod, onChanged: (value) { setState(() { _disposalMethod = value; }); }, hint: '请选择处置方式', hideUnderline: true, ), ), ], ); } // 移除指定索引的电子编号 void _removeRfid(int index) { setState(() { _electronicIds.removeAt(index); }); } // 清空所有已识别的电子编号 void _clearRfids() { setState(() { _electronicIds.clear(); }); ToastUtil.info('已清空所有电子编号'); } // 提交数据 void _handleSubmit() { final data = { 'electronicIds': _electronicIds, 'disposalMethod': _disposalMethod, 'cullReason': _cullReason, 'date': DateTimeUtil.format(DateTime.now()), }; apis.breeding.submitApi.weight(data).then((res) { if (res.success) { ToastUtil.success(res.message.isNotEmpty ? res.message : '批量淘汰提交成功'); if (mounted) { // 提交后重置表单 setState(() { _electronicIds.clear(); // _cullReason = null; // _disposalMethod = null; }); } } else { ToastUtil.errorAlert(res.message.isNotEmpty ? res.message : '批量淘汰提交失败'); } }); } }