feat(boxing): handle multi-code paichan switches

This commit is contained in:
Misaka_Company
2026-05-14 14:04:25 +08:00
parent 28871eb21f
commit a165bfeabe
4 changed files with 148 additions and 2 deletions

View File

@@ -4,6 +4,7 @@ import 'package:pad_scanner/services/app_config_service.dart';
import 'package:pad_scanner/services/scanner_service.dart';
import 'package:pad_scanner/services/code_parser.dart';
import 'package:pad_scanner/services/api_service.dart';
import 'package:pad_scanner/services/boxing_context.dart';
import 'package:pad_scanner/services/feedback_service.dart';
import 'package:pad_scanner/pages/boxing_detail_page.dart';
import 'package:pad_scanner/widgets/status_bar.dart';
@@ -101,6 +102,8 @@ class _BoxingPageState extends State<BoxingPage> {
int? _editingPackedItemId;
String _editingPackedQuantity = '';
int? _deletingPackedItemId;
String? _lastScannedPaichanNo;
String? _paichanSwitchNotice;
// 提交中
bool _isSubmitting = false;
@@ -184,6 +187,8 @@ class _BoxingPageState extends State<BoxingPage> {
_editingPackedItemId = null;
_editingPackedQuantity = '';
_deletingPackedItemId = null;
_lastScannedPaichanNo = null;
_paichanSwitchNotice = null;
_isSubmitting = false;
_lastBoxNo = null;
_editingBox = null;
@@ -260,6 +265,9 @@ class _BoxingPageState extends State<BoxingPage> {
_isDuplicateBoxNo = false;
_editingBox = null;
_statusOverrideText = null;
if (_mode == BoxingMode.singleCode) {
_paichanSwitchNotice = null;
}
// 根据模式自动填充
_applyAutoFill();
@@ -293,9 +301,27 @@ class _BoxingPageState extends State<BoxingPage> {
}
});
case BoxingMode.multiCode:
if (_boxNoController.text.trim().isEmpty) {
_boxNoController.text = (_maxBoxNo + 1).toString();
final decision = decideMultiCodePaichanContext(
lastPaichanNo: _lastScannedPaichanNo,
currentPaichanNo: _paichanNo,
currentBoxNoText: _boxNoController.text,
maxBoxNo: _maxBoxNo,
);
if (decision.isSwitched) {
_manyToOnePackedItems.clear();
_editingPackedItemId = null;
_editingPackedQuantity = '';
_deletingPackedItemId = null;
_paichanSwitchNotice = '排产号已切换:${_paichanNo ?? "--"}';
_feedbackService.trigger(FeedbackEvent.paichanSwitch);
} else {
_paichanSwitchNotice = null;
}
final boxNoToApply = decision.boxNoToApply;
if (boxNoToApply != null) {
_boxNoController.text = boxNoToApply.toString();
}
_lastScannedPaichanNo = _paichanNo;
_quantityController.text = (_erpQuantity ?? 0).toString();
_quantityController.selection = TextSelection(
baseOffset: 0,
@@ -508,6 +534,7 @@ class _BoxingPageState extends State<BoxingPage> {
}
case BoxingMode.multiCode:
_lastScannedPaichanNo = _paichanNo;
setState(() {
if (boxItemId != null) {
_manyToOnePackedItems.add(
@@ -643,6 +670,7 @@ class _BoxingPageState extends State<BoxingPage> {
void _finishManyToOneBox() {
final currentBoxNo = int.tryParse(_boxNoController.text.trim());
setState(() {
_manyToOnePackedItems.clear();
_editingPackedItemId = null;
_editingPackedQuantity = '';
_deletingPackedItemId = null;
@@ -913,6 +941,11 @@ class _BoxingPageState extends State<BoxingPage> {
_statusText = '超出可装数量上限';
return;
}
if (_paichanSwitchNotice != null) {
_statusDot = StatusDotColor.blue;
_statusText = '排产号已切换,箱号已重置';
return;
}
switch (_phase) {
case _Phase.waiting:
_statusDot = StatusDotColor.blue;
@@ -978,6 +1011,16 @@ class _BoxingPageState extends State<BoxingPage> {
body: Column(
children: [
// 重复箱号警告条(保留,因为这是输入区关联的即时反馈)
if (_paichanSwitchNotice != null)
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
color: Colors.blue.shade50,
child: Text(
_paichanSwitchNotice!,
style: TextStyle(color: Colors.blue.shade900, fontSize: 13),
),
),
if (_isDuplicateBoxNo && _phase == _Phase.scanned)
Container(
width: double.infinity,