Compare commits
1 Commits
3fd47f4d7b
...
b17e0e7e62
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b17e0e7e62 |
@@ -123,12 +123,11 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
int? _deletingAssignedItemId;
|
||||
String? _lastScannedPaichanNo;
|
||||
String? _paichanSwitchNotice;
|
||||
bool _crossPaichaPending = false;
|
||||
|
||||
// 提交中
|
||||
bool _isSubmitting = false;
|
||||
|
||||
// 单码装箱:上次提交的箱号(用于继续添加预填)
|
||||
int? _lastBoxNo;
|
||||
CurrentZongpaiBoxData? _editingBox;
|
||||
|
||||
// 重复箱号
|
||||
@@ -273,8 +272,8 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
_deletingAssignedItemId = null;
|
||||
_lastScannedPaichanNo = null;
|
||||
_paichanSwitchNotice = null;
|
||||
_crossPaichaPending = false;
|
||||
_isSubmitting = false;
|
||||
_lastBoxNo = null;
|
||||
_editingBox = null;
|
||||
_isDuplicateBoxNo = false;
|
||||
_statusOverrideText = null;
|
||||
@@ -288,6 +287,11 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_crossPaichaPending) {
|
||||
_feedbackService.trigger(FeedbackEvent.alreadyCompleted);
|
||||
return;
|
||||
}
|
||||
|
||||
final parsed = CodeParser.parse(result.barcode);
|
||||
|
||||
if (parsed.type != CodeType.zongpaiNo) {
|
||||
@@ -438,11 +442,7 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
_statusOverrideDot = StatusDotColor.red;
|
||||
return;
|
||||
}
|
||||
if (_lastBoxNo != null) {
|
||||
_boxNoController.text = (_lastBoxNo! + 1).toString();
|
||||
} else {
|
||||
_boxNoController.text = (_maxBoxNo + 1).toString();
|
||||
}
|
||||
_boxNoController.text = (_maxBoxNo + 1).toString();
|
||||
_quantityController.text = remaining.toString();
|
||||
_quantityController.selection = TextSelection(
|
||||
baseOffset: 0,
|
||||
@@ -461,12 +461,10 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
maxBoxNo: _maxBoxNo,
|
||||
);
|
||||
if (decision.isSwitched) {
|
||||
_manyToOnePackedItems.clear();
|
||||
_editingPackedItemId = null;
|
||||
_editingPackedQuantity = '';
|
||||
_deletingPackedItemId = null;
|
||||
_paichanSwitchNotice = '排产号已切换:${_paichanNo ?? "--"}';
|
||||
_feedbackService.trigger(FeedbackEvent.paichanSwitch);
|
||||
_crossPaichaPending = true;
|
||||
_feedbackService.trigger(FeedbackEvent.alreadyCompleted);
|
||||
_showCrossPaichaDialog();
|
||||
return;
|
||||
} else {
|
||||
_paichanSwitchNotice = null;
|
||||
}
|
||||
@@ -500,6 +498,178 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
_isDuplicateBoxNo = _boxNoIsDuplicate();
|
||||
}
|
||||
|
||||
// === 跨排产号确认对话框 ===
|
||||
|
||||
void _showCrossPaichaDialog() {
|
||||
final currentPaicha = _lastScannedPaichanNo ?? '--';
|
||||
final newPaicha = _paichanNo ?? '--';
|
||||
final dialogFocus = FocusNode();
|
||||
var dismissed = false;
|
||||
var selectedIndex = 0; // 0 = "否" (default), 1 = "是"
|
||||
|
||||
void dismissAsNo() {
|
||||
if (dismissed) return;
|
||||
dismissed = true;
|
||||
Navigator.of(context).pop();
|
||||
_cancelPaichanSwitch();
|
||||
}
|
||||
|
||||
void confirmSwitch() {
|
||||
if (dismissed) return;
|
||||
dismissed = true;
|
||||
Navigator.of(context).pop();
|
||||
_confirmPaichanSwitch();
|
||||
}
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (ctx) => StatefulBuilder(
|
||||
builder: (ctx, setDialogState) {
|
||||
return KeyboardListener(
|
||||
focusNode: dialogFocus,
|
||||
onKeyEvent: (event) {
|
||||
if (event is! KeyDownEvent) return;
|
||||
if (event.logicalKey == LogicalKeyboardKey.arrowUp) {
|
||||
setDialogState(() => selectedIndex = 0);
|
||||
} else if (event.logicalKey == LogicalKeyboardKey.arrowDown) {
|
||||
setDialogState(() => selectedIndex = 1);
|
||||
} else if (event.logicalKey == LogicalKeyboardKey.enter) {
|
||||
selectedIndex == 0 ? dismissAsNo() : confirmSwitch();
|
||||
} else if (event.logicalKey == LogicalKeyboardKey.escape) {
|
||||
dismissAsNo();
|
||||
}
|
||||
},
|
||||
child: PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, _) {
|
||||
if (!didPop) dismissAsNo();
|
||||
},
|
||||
child: AlertDialog(
|
||||
backgroundColor: Colors.orange.shade50,
|
||||
title: Row(
|
||||
children: [
|
||||
Icon(Icons.warning_amber, color: Colors.orange.shade800),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'跨排产号扫描',
|
||||
style: TextStyle(color: Colors.orange.shade900),
|
||||
),
|
||||
],
|
||||
),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Text(
|
||||
'当前排产号:$currentPaicha\n'
|
||||
'新排产号:$newPaicha\n\n'
|
||||
'是否切换到新的排产号?\n\n'
|
||||
'选择「是」将放弃当前已扫描的所有数据。',
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_dialogOptionBtn(
|
||||
label: '否',
|
||||
selected: selectedIndex == 0,
|
||||
onTap: dismissAsNo,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
_dialogOptionBtn(
|
||||
label: '是,切换排产号',
|
||||
selected: selectedIndex == 1,
|
||||
onTap: confirmSwitch,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
dialogFocus.requestFocus();
|
||||
});
|
||||
}
|
||||
|
||||
void _confirmPaichanSwitch() {
|
||||
setState(() {
|
||||
_crossPaichaPending = false;
|
||||
_manyToOnePackedItems.clear();
|
||||
_editingPackedItemId = null;
|
||||
_editingPackedQuantity = '';
|
||||
_deletingPackedItemId = null;
|
||||
_paichanSwitchNotice = '排产号已切换:${_paichanNo ?? "--"}';
|
||||
_boxNoController.text = (_maxBoxNo + 1).toString();
|
||||
_lastScannedPaichanNo = _paichanNo;
|
||||
});
|
||||
_feedbackService.trigger(FeedbackEvent.paichanSwitch);
|
||||
|
||||
// Continue with remaining quantity flow
|
||||
final remaining = _remainingQuantity;
|
||||
if (remaining <= 0) {
|
||||
_quantityController.clear();
|
||||
if (_manyToOnePackedItems.isEmpty && _currentZongpaiBoxes.isNotEmpty) {
|
||||
_completedJumpBoxNo = _currentZongpaiBoxes.first.boxNo;
|
||||
}
|
||||
setState(() {
|
||||
_statusOverrideText = '该总排号已全部装箱完毕';
|
||||
_statusOverrideDot = StatusDotColor.red;
|
||||
});
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
_quantityController.text = remaining.toString();
|
||||
_quantityController.selection = TextSelection(
|
||||
baseOffset: 0,
|
||||
extentOffset: _quantityController.text.length,
|
||||
);
|
||||
_isDuplicateBoxNo = _boxNoIsDuplicate();
|
||||
});
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted && _mode == BoxingMode.multiCode) {
|
||||
_quantityFocusNode.requestFocus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _cancelPaichanSwitch() {
|
||||
setState(() {
|
||||
_crossPaichaPending = false;
|
||||
_zongpaiNo = null;
|
||||
_paichanNo = _lastScannedPaichanNo;
|
||||
_phase = _Phase.waiting;
|
||||
});
|
||||
}
|
||||
|
||||
Widget _dialogOptionBtn({
|
||||
required String label,
|
||||
required bool selected,
|
||||
required VoidCallback onTap,
|
||||
}) {
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
height: 40,
|
||||
child: ElevatedButton(
|
||||
onPressed: onTap,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor:
|
||||
selected ? Colors.blue.shade700 : Colors.grey.shade200,
|
||||
foregroundColor: selected ? Colors.white : Colors.black87,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
),
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontWeight: selected ? FontWeight.w800 : FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// === 重复箱号检测 ===
|
||||
|
||||
bool _boxNoIsDuplicate() {
|
||||
@@ -674,7 +844,6 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
_feedbackService.trigger(FeedbackEvent.submitSuccess);
|
||||
|
||||
setState(() {
|
||||
_lastBoxNo = boxNo;
|
||||
if (_mode == BoxingMode.singleCode && boxItemId != null) {
|
||||
_currentZongpaiBoxes = List.from(_currentZongpaiBoxes)
|
||||
..add(
|
||||
@@ -765,7 +934,6 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
}).toList();
|
||||
_replaceExistingBoxItem(editing, boxNo, quantity);
|
||||
_editingBox = null;
|
||||
_lastBoxNo = _maxBoxNo;
|
||||
_boxNoController.text = (_maxBoxNo + 1).toString();
|
||||
final remaining = _remainingQuantity;
|
||||
if (remaining > 0) {
|
||||
@@ -884,7 +1052,6 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
}
|
||||
|
||||
void _refreshSingleCodeNewInput({bool focusQuantity = true}) {
|
||||
_lastBoxNo = _maxBoxNo;
|
||||
_boxNoController.text = (_maxBoxNo + 1).toString();
|
||||
final remaining = _remainingQuantity;
|
||||
if (remaining > 0) {
|
||||
|
||||
Reference in New Issue
Block a user