refactor: extract boxing page into modular components
Split the monolithic boxing_page.dart into separate files: - boxing_models.dart: data models (_ManyToOnePackedItem, _Phase) - widgets/boxing_shared_widgets.dart: shared UI components - widgets/single_code_body.dart: single-code boxing UI - widgets/multi_code_body.dart: multi-code boxing UI - widgets/multi_packed_row.dart: multi-code packed row widget - widgets/single_assigned_row.dart: single-code assigned row widget Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
231
lib/pages/boxing/widgets/single_assigned_row.dart
Normal file
231
lib/pages/boxing/widgets/single_assigned_row.dart
Normal file
@@ -0,0 +1,231 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:pad_scanner/pages/boxing/widgets/boxing_shared_widgets.dart';
|
||||
import 'package:pad_scanner/services/api_service.dart';
|
||||
|
||||
class SingleAssignedRow extends StatelessWidget {
|
||||
final CurrentZongpaiBoxData item;
|
||||
final String? workOrderNo;
|
||||
final bool editing;
|
||||
final bool deleting;
|
||||
final bool isSubmitting;
|
||||
final String editingQuantity;
|
||||
final ValueChanged<String> onEditingQuantityChanged;
|
||||
final VoidCallback onSave;
|
||||
final VoidCallback onCancelEdit;
|
||||
final VoidCallback onStartEdit;
|
||||
final VoidCallback onStartDelete;
|
||||
final VoidCallback onDelete;
|
||||
final VoidCallback onCancelDelete;
|
||||
|
||||
const SingleAssignedRow({
|
||||
super.key,
|
||||
required this.item,
|
||||
required this.workOrderNo,
|
||||
required this.editing,
|
||||
required this.deleting,
|
||||
required this.isSubmitting,
|
||||
required this.editingQuantity,
|
||||
required this.onEditingQuantityChanged,
|
||||
required this.onSave,
|
||||
required this.onCancelEdit,
|
||||
required this.onStartEdit,
|
||||
required this.onStartDelete,
|
||||
required this.onDelete,
|
||||
required this.onCancelDelete,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final barColor = editing
|
||||
? Colors.amber
|
||||
: (deleting ? Colors.red : Colors.green);
|
||||
|
||||
final Color bgColor;
|
||||
if (editing) {
|
||||
bgColor = Colors.yellow.shade50;
|
||||
} else if (deleting) {
|
||||
bgColor = Colors.red.shade50;
|
||||
} else {
|
||||
bgColor = Colors.transparent;
|
||||
}
|
||||
|
||||
final rowStyle = TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.black87,
|
||||
);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
constraints: const BoxConstraints(minHeight: 36),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: bgColor,
|
||||
border: Border(
|
||||
left: BorderSide(color: barColor, width: 3),
|
||||
bottom: BorderSide(color: Colors.grey.shade200),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 22,
|
||||
child: Text(
|
||||
'${item.boxNo} 号箱',
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: rowStyle.copyWith(fontWeight: FontWeight.w700),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 30,
|
||||
child: Text(
|
||||
workOrderNo ?? '--',
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: rowStyle,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 23,
|
||||
child: editing
|
||||
? SizedBox(
|
||||
width: 52,
|
||||
height: 28,
|
||||
child: TextField(
|
||||
keyboardType: TextInputType.none,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
textAlign: TextAlign.center,
|
||||
controller:
|
||||
TextEditingController(text: editingQuantity)
|
||||
..selection = TextSelection.collapsed(
|
||||
offset: editingQuantity.length,
|
||||
),
|
||||
onChanged: onEditingQuantityChanged,
|
||||
onSubmitted: (_) => onSave(),
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 4,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: const BorderSide(
|
||||
color: Colors.amber,
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'${item.quantity} 件',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: deleting ? Colors.red : Colors.black54,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 54,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (editing) ...[
|
||||
CompactIconButton(
|
||||
icon: Icons.check,
|
||||
color: Colors.green,
|
||||
onTap: isSubmitting ? null : onSave,
|
||||
),
|
||||
CompactIconButton(
|
||||
icon: Icons.close,
|
||||
color: Colors.grey,
|
||||
onTap: isSubmitting ? null : onCancelEdit,
|
||||
),
|
||||
] else ...[
|
||||
CompactIconButton(
|
||||
icon: Icons.edit,
|
||||
color: Colors.grey.shade700,
|
||||
onTap: isSubmitting ? null : onStartEdit,
|
||||
),
|
||||
CompactIconButton(
|
||||
icon: Icons.delete_outline,
|
||||
color: Colors.red,
|
||||
onTap: isSubmitting ? null : onStartDelete,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (deleting)
|
||||
Container(
|
||||
height: 28,
|
||||
padding: const EdgeInsets.only(left: 15, right: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red.shade50,
|
||||
border: Border(bottom: BorderSide(color: Colors.red.shade200)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'确认删除 ${item.boxNo} 号箱记录?',
|
||||
style: const TextStyle(fontSize: 12, color: Colors.red),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: isSubmitting ? null : onDelete,
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 2,
|
||||
),
|
||||
minimumSize: Size.zero,
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
),
|
||||
child: const Text(
|
||||
'删除',
|
||||
style: TextStyle(fontSize: 12, fontWeight: FontWeight.w700),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
TextButton(
|
||||
onPressed: isSubmitting ? null : onCancelDelete,
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 2,
|
||||
),
|
||||
minimumSize: Size.zero,
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
),
|
||||
child: const Text(
|
||||
'取消',
|
||||
style: TextStyle(fontSize: 12, fontWeight: FontWeight.w700),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user