individual_culling_page.dart 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import 'package:flutter/material.dart';
  2. import 'package:chicken_farm/components/vb_app_bar.dart';
  3. import 'package:chicken_farm/components/vb_dict_select.dart';
  4. import 'package:chicken_farm/core/utils/toast.dart';
  5. class IndividualCullingPage extends StatefulWidget {
  6. const IndividualCullingPage({super.key});
  7. @override
  8. State<IndividualCullingPage> createState() => _IndividualCullingPageState();
  9. }
  10. class _IndividualCullingPageState extends State<IndividualCullingPage> {
  11. String? _rfid;
  12. String? _cullReason;
  13. String? _disposalMethod;
  14. bool _isScanningRfid = false;
  15. @override
  16. Widget build(BuildContext context) {
  17. return Scaffold(
  18. appBar: const VberAppBar(title: '个体淘汰', showLeftButton: true),
  19. body: Padding(
  20. padding: const EdgeInsets.all(16.0),
  21. child: Column(
  22. crossAxisAlignment: CrossAxisAlignment.start,
  23. children: [
  24. // 电子编号区域
  25. _buildRfidSection(),
  26. const SizedBox(height: 20),
  27. // 淘汰原因
  28. _buildCullReasonSection(),
  29. const SizedBox(height: 20),
  30. // 处置方式
  31. _buildDisposalMethodSection(),
  32. const SizedBox(height: 30),
  33. // 提交按钮
  34. SizedBox(
  35. width: double.infinity,
  36. child: ElevatedButton(
  37. onPressed:
  38. _rfid != null &&
  39. _cullReason != null &&
  40. _disposalMethod != null
  41. ? _handleSubmit
  42. : null,
  43. style: ElevatedButton.styleFrom(
  44. backgroundColor:
  45. _rfid != null &&
  46. _cullReason != null &&
  47. _disposalMethod != null
  48. ? Colors.blue
  49. : Colors.grey,
  50. foregroundColor: Colors.white,
  51. ),
  52. child: const Text('提交'),
  53. ),
  54. ),
  55. ],
  56. ),
  57. ),
  58. );
  59. }
  60. Widget _buildRfidSection() {
  61. return Column(
  62. crossAxisAlignment: CrossAxisAlignment.start,
  63. children: [
  64. const Text('电子编号', style: TextStyle(fontWeight: FontWeight.bold)),
  65. const SizedBox(height: 10),
  66. Container(
  67. padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
  68. decoration: BoxDecoration(
  69. border: Border.all(color: Colors.grey),
  70. borderRadius: BorderRadius.circular(8),
  71. ),
  72. child: Row(
  73. children: [
  74. Expanded(
  75. child: Text(
  76. _rfid ?? '未扫描',
  77. style: TextStyle(
  78. color: _rfid != null ? Colors.black : Colors.grey,
  79. fontSize: 16,
  80. ),
  81. ),
  82. ),
  83. IconButton(
  84. icon: _isScanningRfid
  85. ? const SizedBox(
  86. width: 20,
  87. height: 20,
  88. child: CircularProgressIndicator(strokeWidth: 2),
  89. )
  90. : const Icon(Icons.qr_code_scanner, size: 20),
  91. onPressed: _simulateScanRfid,
  92. ),
  93. ],
  94. ),
  95. ),
  96. ],
  97. );
  98. }
  99. Widget _buildCullReasonSection() {
  100. return Column(
  101. crossAxisAlignment: CrossAxisAlignment.start,
  102. children: [
  103. const Text('淘汰原因', style: TextStyle(fontWeight: FontWeight.bold)),
  104. const SizedBox(height: 10),
  105. Container(
  106. padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
  107. decoration: BoxDecoration(
  108. border: Border.all(color: Colors.grey),
  109. borderRadius: BorderRadius.circular(8),
  110. ),
  111. child: VberDictSelect(
  112. dictType: 'chicken_cull_reason',
  113. value: _cullReason,
  114. onChanged: (value) {
  115. setState(() {
  116. _cullReason = value;
  117. });
  118. },
  119. hint: '请选择淘汰原因',
  120. hideUnderline: true,
  121. ),
  122. ),
  123. ],
  124. );
  125. }
  126. Widget _buildDisposalMethodSection() {
  127. return Column(
  128. crossAxisAlignment: CrossAxisAlignment.start,
  129. children: [
  130. const Text('处置方式', style: TextStyle(fontWeight: FontWeight.bold)),
  131. const SizedBox(height: 10),
  132. Container(
  133. padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
  134. decoration: BoxDecoration(
  135. border: Border.all(color: Colors.grey),
  136. borderRadius: BorderRadius.circular(8),
  137. ),
  138. child: VberDictSelect(
  139. dictType: 'chicken_disposal_method',
  140. value: _disposalMethod,
  141. onChanged: (value) {
  142. setState(() {
  143. _disposalMethod = value;
  144. });
  145. },
  146. hint: '请选择处置方式',
  147. hideUnderline: true,
  148. ),
  149. ),
  150. ],
  151. );
  152. }
  153. // 模拟扫描电子编号
  154. void _simulateScanRfid() {
  155. if (_isScanningRfid) return;
  156. setState(() {
  157. _isScanningRfid = true;
  158. });
  159. // 模拟扫描过程
  160. Future.delayed(const Duration(seconds: 1), () {
  161. if (mounted) {
  162. setState(() {
  163. _rfid = 'RFID-${DateTime.now().millisecondsSinceEpoch}';
  164. _isScanningRfid = false;
  165. });
  166. ToastUtil.success('电子编号扫描成功');
  167. }
  168. });
  169. }
  170. // 提交数据
  171. void _handleSubmit() {
  172. // 在实际应用中,这里会发送数据到服务器
  173. ScaffoldMessenger.of(context).showSnackBar(
  174. const SnackBar(content: Text('个体淘汰提交成功'), backgroundColor: Colors.green),
  175. );
  176. // 提交后重置表单
  177. setState(() {
  178. _rfid = null;
  179. _cullReason = null;
  180. _disposalMethod = null;
  181. });
  182. }
  183. }