improve single-code boxing UX: preserve state, fix work order display, add double-vibrate alert

- Keep UI state after boxing completion for operator review instead of auto-reset
- Show real work order number instead of hardcoded "本次扫码" in assigned list
- Add double-vibration feedback when re-scanning already completed zongpai
- Change completed status banner and dot from green to red for clearer warning

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Misaka_Company
2026-05-19 17:05:26 +08:00
parent 7a95f49acc
commit a6ee6a718b
2 changed files with 29 additions and 10 deletions

View File

@@ -344,7 +344,19 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
return false; return false;
} }
_feedbackService.trigger(FeedbackEvent.scanValid); // 判断该总牌号是否已全部装箱完毕
final packedQuantity = result.currentZongpaiBoxes.fold<int>(
0,
(sum, item) => sum + item.quantity,
);
final totalQuantity = result.quantity ?? 0;
final alreadyCompleted = totalQuantity > 0 && packedQuantity >= totalQuantity;
_feedbackService.trigger(
alreadyCompleted
? FeedbackEvent.alreadyCompleted
: FeedbackEvent.scanValid,
);
setState(() { setState(() {
_zongpaiNo = zongpai; _zongpaiNo = zongpai;
@@ -686,9 +698,6 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
StatusDotColor.green, StatusDotColor.green,
const Duration(milliseconds: 1500), const Duration(milliseconds: 1500),
); );
Future.delayed(const Duration(milliseconds: 1500), () {
if (mounted) setState(() => _resetState());
});
} else { } else {
setState(() { setState(() {
_phase = _Phase.scanned; _phase = _Phase.scanned;
@@ -1285,7 +1294,7 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
case _Phase.scanned: case _Phase.scanned:
_statusDot = StatusDotColor.blue; _statusDot = StatusDotColor.blue;
if (_remainingQuantity <= 0) { if (_remainingQuantity <= 0) {
_statusDot = StatusDotColor.green; _statusDot = StatusDotColor.red;
_statusText = '该总排号已全部装箱完毕'; _statusText = '该总排号已全部装箱完毕';
return; return;
} }
@@ -1423,11 +1432,11 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
_remainingQuantity <= 0) { _remainingQuantity <= 0) {
banners.add( banners.add(
_noticeBanner( _noticeBanner(
icon: Icon(Icons.check, size: 14, color: Colors.green.shade800), icon: Icon(Icons.warning, size: 14, color: Colors.red.shade800),
text: '${_zongpaiNo!} 已全部装箱完毕,无需操作', text: '${_zongpaiNo!} 已全部装箱完毕,无需操作',
background: Colors.green.shade50, background: Colors.red.shade50,
foreground: Colors.green.shade800, foreground: Colors.red.shade800,
border: Colors.green.shade100, border: Colors.red.shade100,
), ),
); );
} }
@@ -1762,7 +1771,7 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
Text( Text(
'本次扫码', _workOrderNo ?? '--',
style: TextStyle( style: TextStyle(
fontSize: 10, fontSize: 10,
color: Colors.grey.shade500, color: Colors.grey.shade500,

View File

@@ -10,6 +10,7 @@ enum FeedbackEvent {
duplicateError, // Duplicate (shelf) → alert loop + continuous vibrate duplicateError, // Duplicate (shelf) → alert loop + continuous vibrate
networkError, // Network error → failure sound + short vibrate networkError, // Network error → failure sound + short vibrate
duplicateBoxNo, // Duplicate box no → failure sound + short vibrate duplicateBoxNo, // Duplicate box no → failure sound + short vibrate
alreadyCompleted, // Zongpai already boxed → beep + double vibrate
modeSwitch, // Mode toggle → beep only modeSwitch, // Mode toggle → beep only
paichanSwitch, // Paichan changed → beep + short vibrate paichanSwitch, // Paichan changed → beep + short vibrate
} }
@@ -55,6 +56,10 @@ class FeedbackService {
_soundService.playFailure(); _soundService.playFailure();
_vibrateShort(); _vibrateShort();
case FeedbackEvent.alreadyCompleted:
_soundService.playBeep();
_vibrateDouble();
case FeedbackEvent.modeSwitch: case FeedbackEvent.modeSwitch:
_soundService.playBeep(); _soundService.playBeep();
@@ -82,6 +87,11 @@ class FeedbackService {
Vibration.vibrate(pattern: [0, 300, 100, 300, 100, 300]); Vibration.vibrate(pattern: [0, 300, 100, 300, 100, 300]);
} }
/// Two short bursts to signal an already-completed item.
void _vibrateDouble() {
Vibration.vibrate(pattern: [0, 200, 100, 200]);
}
Future<void> dispose() async { Future<void> dispose() async {
await _soundService.dispose(); await _soundService.dispose();
} }